效能构建

效能构建

原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/

简介: Spring,构建 Java™ 平台和 Enterprise Edition (Java EE)
应用程序的头面框架,现在在其模型-视图-控制器(Model-View-Controller
,MVC)层帮忙具象状态传输 (REST)。RESTful web
服务依照客户端请求生成几个具体(representations)很重要。在本篇作品中,学习运用 HttpMessageConverter 生成六个具体。代码示例体现什么采用RestTemplate 和 HttpMessageConverter 与服务开展通信。此外,还将学习怎么着运用
Spring API 和注释构建 RESTful web 服务,生成常见具象,比如 ATOM
Feed、XML 和 JavaScript Object Notation (JSON)。

简介

随附作品,“使用 Spring 3 构建 RESTful web
服务”(参见 参考资料),介绍了动用
Spring 构建 RESTful web
服务的主意。还表达了什么样利用 ContentNegotiatingViewResolver 生成多少个具体,这是
RESTful web
服务的一个重要意义。本文还演讲了拔取HttpMessageConverter 生成四个具体的另一种艺术,并且本文中的示例显示了如何行使 RestTemplate 和HttpMessageConverter 与服务开展通信。

Spring MVC 中的 REST 支持

本有的提供了支撑 RESTful web 服务的重大 Spring 效能(或注释)的概述。

@Controller
使用 @Controller 注释对将成为 MVC 中控制器的类进行诠释并处理 HTTP
请求。

@RequestMapping
使用 @RequestMapping 注释对函数举办声明,该函数处理某些 HTTP 方法、URI
或 HTTP 头。此注释是 Spring REST
补助的基本点。可以更改 method参数以处理任何 HTTP 方法。

例如:“

@RequestMapping(method=RequestMethod.GET, value="/emps", 
headers="Accept=application/xml, application/json")
                    

@PathVariable
使用 @PathVariable 注释可将 URI 中的路径变量作为参数插入。

例如:

@RequestMapping(method=RequestMethod.GET, value="/emp/{id}")
public ModelAndView getEmployee(@PathVariable String id) { … }
                    

其余有效的诠释
个人档案,使用 @RequestParam 将 URL 参数插入方法中。

使用 @RequestHeader 将某一 HTTP 头插入方法中。

使用 @RequestBody 将 HTTP 请求正文插入方法中。

使用 @ResponseBody 将内容或对象作为 HTTP 响应正文再次回到。

使用 HttpEntity<T> 将它自动插入方法中,假设将它当做参数提供。

使用 ResponseEntity<T> 重返具有自定义状态或头的 HTTP 响应。

例如:

public @ResponseBody Employee getEmployeeBy(@RequestParam("name") 
String name, @RequestHeader("Accept") String accept, @RequestBody String body) {…} 
public ResponseEntity<String> method(HttpEntity<String> entity) {…}
                    

参见 Spring
文档(参见 参考资料)
得到可插入方法中的扶助注释或对象的总体列表。

多具象援助

拔取不同 MIME 类型表示一致资源是 RESTful web
服务的一个第一方面。通常,能够行使所有不同 “accept” HTTP 头的同一 URI
提取具有不同代表的资源。还足以采用不同的 URI 或富有不同请求参数的 URI。

“使用 Spring 3 构建 RESTful web
服务”(参见 参考资料)介绍了 ContentNegotiatingViewResolver,可以拔取不同的视图解析器处理同一
URI(具有不同的 accept
头)。因而,ContentNegotiatingViewResolver 可用于转移六个有血有肉。

还有另一种方法可生成多具象 —
将 HttpMessageConverter 和 c@ResponseBody 注释结合起来使用。使用这种方法无需选取视图技术。

 

回页首

HttpMessageConverter

HTTP
请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本举办通信。但是,使用
Spring,controller 类中的方法重返纯 ‘String’ 类型和域模型(或其他 Java
内建目的)。怎么样将对象类别化/反系列化为原始文本?这由HttpMessageConverter 处理。Spring
具有捆绑实现,可满足周边需求。表 1 呈现了部分示范。

表 1. HttpMessageConverter 示例

使用…… 您可以……
StringHttpMessageConverter 从请求和响应读取/编写字符串。默认情况下,它支持媒体类型 text/* 并使用文本/无格式内容类型编写。
FormHttpMessageConverter 从请求和响应读取/编写表单数据。默认情况下,它读取媒体类型 application/x-www-form-urlencoded 并将数据写入 MultiValueMap<String,String>。
MarshallingHttpMessageConverter 使用 Spring 的 marshaller/un-marshaller 读取/编写 XML 数据。它转换媒体类型为 application/xml 的数据。
MappingJacksonHttpMessageConverter 使用 Jackson 的 ObjectMapper 读取/编写 JSON 数据。它转换媒体类型为 application/json 的数据。
AtomFeedHttpMessageConverter 使用 ROME 的 Feed API 读取/编写 ATOM 源。它转换媒体类型为 application/atom+xml 的数据。
RssChannelHttpMessageConverter 使用 ROME 的 feed API 读取/编写 RSS 源。它转换媒体类型为 application/rss+xml 的数据。

 

回页首

构建 RESTful web 服务

在此部分中,学习构建可生成六个有血有肉的简便 RESTful web
服务。示例应用程序中采取的一些资源在 “使用 Spring 3 构建 RESTful web
服务”(参见 参考资料)中构建。还可以 下载 示范代码。

先是,您必须配备 HttpMessageConverter。要生成五个实际,自定义多少个 HttpMessageConverter 实例,以将对象转换为不同的传媒类型。此部分包括
JSON、ATOM 和 XML 媒体类型。

JSON

从最简易的以身作则起始。JSON
是一个轻量型的数据交流格式,人们可轻松地展开读取和编制。清单 1
显示了布置 JSON converter 的代码。

清单 1. 配置 rest-servlet.xml 中的 HttpMessageConverter

               
<bean class="org.springframework.web.servlet.mvc.annotation
.AnnotationMethodHandlerAdapter">
   <property name="messageConverters">
       <list>
           <ref bean="jsonConverter" />
   <ref bean="marshallingConverter" />
   <ref bean="atomConverter" />
       </list>
   </property>
</bean>

<bean id="jsonConverter" 
            class="org.springframework.http.converter.json
.MappingJacksonHttpMessageConverter">
   <property name="supportedMediaTypes" value="application/json" />
</bean>

 

在配置中,注册了 3
个转移程序。MappingJacksonHttpMessageConverter 用于将对象转换为
JSON,反之亦然。此放置转换程序采用 杰克逊 的 ObjectMapper 将 JSON
映射到 JavaBean,因而你必须将下列 杰克逊(Jackson) JAR 文件添加到类路径。

  • org.codehaus.jackson.jar
  • org.codehaus.jackson.mapper.jar

下一步是编写一个办法,处理请求 JSON 具象的伸手。清单 2 显示了详细音信。

清单 2. 甩卖在 EmployeeController 中定义的 JSON 请求

               
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}", 
        headers="Accept=application/json")
public @ResponseBody Employee getEmp(@PathVariable String id) {
Employee e = employeeDS.get(Long.parseLong(id));
return e;
}

@RequestMapping(method=RequestMethod.GET, value="/emps", 
        headers="Accept=application/json")
public @ResponseBody EmployeeListinggetAllEmp() {
List<Employee> employees = employeeDS.getAll();
EmployeeListinglist = new EmployeeList(employees);
return list;
}
            

 

@ResponseBody 注释用于将重回对象(Employee 或 EmployeeList)变为响应的正文内容,将利用MappingJacksonHttpMessageConverter将其映射到
JSON。

使用 HttpMessageConverter 和 @ResponseBody,您可以实现六个实际,而无需蕴涵
Spring 的视图技术 —
这是使用ContentNegotiatingViewResolver 所不具有的一个优势。

前日您可以选用 CURL 或 REST Client Firefox 插件调用请求。记住添加一个
HTTP 头:Accept=application/json。清单 3 以 JSON
格式显示了所需的响应。

清单 3. getEmp() 和 getAllEmp() 的 JSON 结果

               

Response for /rest/service/emp/1
{"id":1,"name":"Huang Yi Ming","email":"huangyim@cn.ibm.com"}

Response for /rest/service/emps
{"count":2,
"employees":[
{"id":1,"name":"Huang Yi Ming","email":"huangyim@cn.ibm.com"},
{"id":2,"name":"Wu Dong Fei","email":"wudongf@cn.ibm.com"}
]}
            

 

XML

Spring 的松手转换程序 MarshallingHttpMessageConverter 用于在目的和 XML
(OXM) 之间开展映射。本示例使用 JAXB 2 作为转换程序的
marshaller/un-marshaller。清单 4 呈现了安排。

清单 4. 配置 MarshallingHttpMessageConverter

               
<bean id="marshallingConverter" 
class="org.springframework.http.converter.xml
        .MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller" />
    <property name="supportedMediaTypes" value="application/xml"/>
      </bean>

      <bean id="jaxbMarshaller" 
      class="org.springframework.oxm.jaxb.Jaxb2Marshaller">

    <property name="classesToBeBound">
      <list>
        <value>dw.spring3.rest.bean.Employee</value>
        <value>dw.spring3.rest.bean.EmployeeList</value>
      </list>
    </property>

</bean>
            

 

打听 JAXB 2 无法很好地支撑 java.util.List<T> 到 XML
的投射很关键。常用实践是为目标集添加一个包装类。参见 “使用 Spring 3 构建
RESTful web
服务”(参见 参考资料)或 下载 源代码,通晓此
JAXB 注释类的详细新闻。

在拍卖请求的控制器中的方法怎么样?回顾一下 清单
2
 中的代码。发现在此间不需要丰盛另外代码一点也不意外。您只需要在Accept 头中添加另一个支撑的传媒类型,如下所示。

headers=”Accept=application/json, application/xml”
            

 

转换程序将对象不错地照耀到请求的类别(JSON 或 XML)。清单 5 呈现了请求
application/xml 具象的脍炙人口结果。

清单 5. getEmp() 和 getAllEmp() 的 XML 结果

               
Response for /rest/service/emp/1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <employee>
   <email>huangyim@cn.ibm.com</email>
   <id>1</id>
   <name>Huang Yi Ming</name>
 </employee>
Response for /rest/service/emps
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <employees>
  <count>2</count>
    <employee>
      <email>huangyim@cn.ibm.com</email>
      <id>1</id>
      <name>Huang Yi Ming</name>
    </employee>
    <employee>
      <email>wudongf@cn.ibm.com</email>
      <id>2</id><name>Wu Dong Fei</name>
    </employee>
 </employees>
            

 

ATOM 源

ATOM 源是另一种在 RESTful web 服务中交流数据的常见格式。Atom 源文档是
Atom
源(包括关于源及与其连带的所有或一些项的元数据)的实际。其根是 atom:feed 元素。还有一个
ATOM Publish Protocol (APP) 定义互换格式和表现。(定义 ATOM 和 APP
格式不在本文的座谈范围内。参见 参考资料 了然更多音信。)

本示例使用 AtomFeedHttpMessageConverter 转换 ATOM 源,利用 ROME ATOM
API。因而,您必须在类路径中包含 JAR 文件 sun.syndication.jar。清单 6
显示了此转换程序的安排。

清单 6. 配置 AtomFeedHttpMessageConverter

               
<bean id="atomConverter" 
class="org.springframework.http.converter.feed
        .AtomFeedHttpMessageConverter">
<property name="supportedMediaTypes" value="application/atom+xml" />
</bean>
            

 

清单 7 展现了处理 ATOM 请求和源生成的代码。

清单 7. EmployeeController & AtomUtil 类中的 getEmpFeed() 

               
@RequestMapping(method=RequestMethod.GET, value="/emps", 
        headers="Accept=application/atom+xml")
public @ResponseBody Feed getEmpFeed() {
    List<Employee> employees = employeeDS.getAll();
    return AtomUtil.employeeFeed(employees, jaxb2Mashaller);
}

public static Feed employeeFeed(
    List<Employee> employees, Jaxb2Marshaller marshaller) {
Feed feed = new Feed();
feed.setFeedType("atom_1.0");
feed.setTitle("Employee Atom Feed");

List<Entry> entries = new ArrayList<Entry>();
for(Employee e : employees) {
    StreamResult result = new StreamResult(
    new ByteArrayOutputStream());
    marshaller.marshal(e, result);
    String xml = result.getOutputStream().toString();

    Entry entry = new Entry();
    entry.setId(Long.valueOf(e.getId()).toString());
    entry.setTitle(e.getName());
    Content content = new Content();
    content.setType(Content.XML);
    content.setValue(xml);

    List<Content> contents = new ArrayList<Content>();
    contents.add(content);
    entry.setContents(contents);
    entries.add(entry);
}
feed.setEntries(entries);
return feed;
}
            

 

在上述代码中,注意:

  • getEmpFeed() 方法将同一 URI
    处理为 getAllEmp(),但具有不同的 Accept 头。
  • 使用 employeeFeed() 方法,您可以将 Employee 对象解析为
    XML,然后将其添加到源项的 <content> 元素。

清单 8 突显了请求 URI /rest/service/emps 的 application/atom+xml
具象时的出口。

清单 8. 请求 application/atom+xml 时的 /rest/service/emps 输出

               
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Employee Atom Feed</title>

 <entry>
    <title>Huang Yi Ming</title>
    <id>1</id>
  <content type="xml">
    <employee>
            <email>huangyim@cn.ibm.com</email>
            <id>1</id>
            <name>Huang Yi Ming</name>
    </employee>
  </content>
</entry>

  <entry>
    <title>Wu Dong Fei</title>
    <id>2</id>
  <content type="xml">
    <employee>
            <email>wudongf@cn.ibm.com</email>
            <id>2</id>
            <name>Wu Dong Fei</name>
     </employee>
   </content>
 </entry>

</feed>
 

 

实现 POST、PUT 和 DELETE

目前结束,示例已落实了多少个处理 HTTP GET 方法的法子。清单 9
显示了 POSTPUT 和 DELETE 方法的实现。

清单 9. EmployeeController 中的 POST、PUT 和 DELETE 方法

               
@RequestMapping(method=RequestMethod.POST, value="/emp")
public @ResponseBody Employee addEmp(@RequestBody Employee e) {
employeeDS.add(e);
return e;
}

@RequestMapping(method=RequestMethod.PUT, value="/emp/{id}")
public @ResponseBody Employee updateEmp(
    @RequestBody Employee e, @PathVariable String id) {
employeeDS.update(e);
return e;
}

@RequestMapping(method=RequestMethod.DELETE, value="/emp/{id}")
public @ResponseBody void removeEmp(@PathVariable String id) {
employeeDS.remove(Long.parseLong(id));
}
            

 

@RequestBody 注释在 addEmp() 和 updateEmp() 方法中动用。它接受
HTTP
请求正文并准备动用注册的HttpMessageConverter 将其转移为对象类。在下有些中,您将采纳 RestTemplate 与这几个服务拓展通信。

 

回页首

行使 RestTemplate 与 REST 服务举办通信

“使用 Spring 3 构建 RESTful web
服务”(参见 参考资料)介绍了什么样使用
CURL 和 REST 客户端测试 REST 服务。从编程水平上讲,Jakarta 康芒斯(Commons)(Commons)HttpClient
平日用于完成此测试(但那不在本文的研讨范围中)。您还足以行使名为 RestTemplate 的
Spring REST 客户端。从概念上讲,它与 Spring
中的其他模板类一般,比如 JdbcTemplate 和 JmsTemplate

RestTemplate 还使用 HttpMessageConverter。您能够将对象类传入请求并使转换程序处理映射。

配置 RestTemplate

清单 10 显示了 RestTemplate 的布局。它还利用在此以前介绍的 3 个转移程序。

清单 10. 配置 RestTemplate

               
<bean id="restTemplate" 
class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
    <list>
    <ref bean="marshallingConverter" />
    <ref bean="atomConverter"  />
    <ref bean="jsonConverter" />
    </list>
</property>
</bean>
            

 

正文中的示例仅使用了部分可简化服务器之间通信的形式。RestTemplate协理其他措施,包括:

  • exchange:使用请求正文执行一些 HTTP 方法并收获响应。
  • getForObject:执行 HTTP GET 方法并将响应作为目标拿到。
  • postForObject:使用一定请求正文执行 HTTP POST 方法。
  • put:使用一定请求正文执行 HTTP PUT 方法。
  • delete:执行 HTTP DELETE措施以赢得一定 URI。

代码示例

下列代码示例援助演讲如何拔取 RestTemplate。参见 RestTemplate
API(参见 参考资料)拿到行使的
API 的详尽表达。

清单 11
呈现怎么将头添加到请求中,然后调用请求。使用 MarshallingHttpMessageConverter 您可以收获响应并将其转移为类型类。可以拔取不同的传媒类型测试其他实际。

清单 11. XML 具象请求

               
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<EmployeeList> response = restTemplate.exchange(
"http://localhost:8080/rest/service/emps", 
HttpMethod.GET, entity, EmployeeList.class);
EmployeeListingemployees = response.getBody();
// handle the employees
            

 

清单 12
展现了什么样将新职工发表到服务器。服务器端服务 addEmp() 可接受媒体类型为
application/xml 和 application/json 的数额。

清单 12. 发布新职工

               
Employee newEmp = new Employee(99, "guest", "guest@ibm.com");
HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp);
ResponseEntity<Employee> response = restTemplate.postForEntity(
"http://localhost:8080/rest/service/emp", entity, Employee.class);
Employee e = response.getBody();
// handle the employee
            

 

清单 13 呈现了什么样 PUT 修改的员工以改进旧员工。它还显示了可用作请求 URI
占位符({id})的功能。

清单 13. PUT 以更新员工

               
Employee newEmp = new Employee(99, "guest99", "guest99@ibm.com");
HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp);
restTemplate.put(
    "http://localhost:8080/rest/service/emp/{id}", entity, "99");

 

清单 14 显示了哪些 DELETE 现有职工。

清单 14. DELETE 现有职工

               
restTemplate.delete(
    "http://localhost:8080/rest/service/emp/{id}", "99");

 

 

回页首

结束语

在本篇著作中,您读书了 Spring 3
中引入的 HttpMessageConverter。它提供了对多具象的客户端和劳务器端援助。使用提供的 源代码,您可以研讨本文中的 HttpMessageConverter 实现和使用
“使用 Spring 3 构建 RESTful web 服务”
中的ContentNegotiatingViewResolver 实现之间的歧异。

 

 

回页首

下载

描述 名字 大小 下载方法
文章源代码 src_code.zip 11KB HTTP

关于下载情势的音讯

 

参考资料

学习

收获产品和技术

讨论

admin

网站地图xml地图