[Spring] Spring 3.0对RESTful web service的支持
2012-07-22 13:24
274 查看
尽管Spring MVC框架在很早以前就通过注解和其他的API特性添加了RESTful的功能,但是对RESTfu web service的支持却是比较晚才添加到Spring MVC中的。一些JAX-RS实现(如Restlet,RESTEasy和Jersey)已经支持RESTful web service,但是Spring社区直到Spring 3.0才支持RESTful web service特性。本文中我们会讨论Spring 3.0对开发RESTful web service的支持,查看其提供的类和注解。
首先让我们简单的复习一下。RESTful web service是使用REST原则创建和访问的web service。RESTful web service是使用HTTP没方法来执行操作的,能够很容易的通过URI进行访问。HTTP方法POST,GET,PUT和DELETE能够被映射到创建、读取、更新和删除(CRUD)操作。
使用JAX-RS的RESTful Web Service
JAX-RS是一个Java编程的API(JSR 311),是Java EE平台的一部分。JAX-RS被设计用来简化使用REST原则和架构的Java应用程序的开发。通过使用注解,JAX-RS开发人员能够将POJO暴露为web资源。和其他的Java web应用程序一样,JAX-RS应用程序被打包为WAR文件,并布署在支持Java Servlet API的容器上。
在Java中开发JAX-RS应用程序的方法之一就是使用Jersey。Jersey是一个开源的、质量良好的JAX-RS参考实现。Jersey实现了所有的API,并且提供了能够快速简便的开发REST类型的Java web service的注解。它还使用自己定义的API(如Jersey Client API)提供了很多附加的特性。对于RESTful web service,Jersey使用的是名为Grizzly的web 服务器。对该容器的请求会被一个Grizzly
Servlet处理,该Servlet的全名是com.sun.jersey.spi.container.servlet.ServletContainer.
使用Spring编写RESTful web service
使用Spring MVC对RESTful web service的支持,Java开发人员能够使用继承自Spring的MVC框架的注解来构建RESTful的应用程序。对于RESTful应用程序的客户端的支持是RestTemplate API提供的,该API在概念上和JdbcTemplate或JmsTemplate十分类似。REST功能是HttpConverters类提供的,该类帮助将对象转换成HTTP请求或回应中的representation,或者是相反的过程。为了完成对象和XML之间的映射,Spring提供了MarshallingHttpMessageConverter类。
Spring web MVC使用了DispatcherServlet来将请求分发给处理器。默认的处理器是使用@Controller和@RequestMapping注解标明的。这两个注解在使用Spring开发RESTful的应用程序扮演了主要的角色,实际上这两个注解和另外一个注解#PathVariable构成了Spring中RESTful功能的基础。注解@Controller被用来将一个POJO标记为控制器,注解@RequestMapping用来将请求映射到类或处理器方法。
Spring控制器和RESTful web service
控制器对应Spring web MVC中的C。它们帮助处理用户输入,并为用户将输入通过视图(view)转换为模型(model)。控制器可以通过@controller注解来声明。通常,我们在一个类的顶端使用该注解来上面这个特定的类是控制器。
@Controller
public class StockController {
private final Stock stock;
@AutoWired
public StockController(Stock stock) {
this.stock = stock;
}
@RequestMapping("/")
public void stockInfo() {
}
@RequestMapping("/stockdetails")
public String getStockDetails() {
return this.stock.getStockDetails();
}
}
复制代码
注解@RequestMapping并不要求被使用在类级别上,它也可以被使用在方法级别上。根据absolute路径,控制器会调用合适的方法。
URI模板
一个URI模板是一个将URI作为字符串保持的模板。通常,一个URI模板会含有变量,当这些变量被值替换的时候,URI模板就变成了实际的URI。我们可以在@RequestMapping注解中使用URI模板。
例如,URI http://www.helloworld.com/users/{username}就是一个URI模板,允许使用实际的用户名来替换username,例如http://www.helloworld.com/users/john
。处理器将实际的UIR和URI模板进行比较并替换其中的参数。
@RequestMapping(value="/users/{username}", method=RequestMethod.GET)
public String sayHello(Model model) {
......
return "Hello, Welcome!";
}
复制代码
Spring注解: @PathVariable
注解@PathVariable被用来将UIR模板变量和方法参数绑定到一起。在前面的例子中,可以使用@PathVariable注解就爱那个URI模板变量username和方法参数userName绑定到一起。使用了@PathVariable声明的方法参数的类型并不一定要是字符串,可以是原始类型,如int,long,double等。
@RequestMapping(value="/users/{username}", method=RequestMethod.GET)
public String sayHello(@PathVariable("username") String userName, Model model) {
......
return "Hello "+userName+", Welcome!";
}
复制代码
可以将多个URI模板变量绑定到方法的参数中,如:
@RequestMapping(value="/users/{username}/city/{cityname}", method=RequestMethod.GET)
public String sayHello(@PathVariable("username") String userName, @PathVariable("cityname") String cityName, Model model) {
......
}
复制代码
URI模板变量也可以来找相对路径:
@Controller
@RequestMapping(value="/users/{username}")
public class SayHelloController {
@RequestMapping(value="/city/{cityname}")
public String sayHello(@PathVariable("username") String userName, @PathVariable("cityname") String cityName, Model model) {
......
}
}
复制代码
参数化的添加如myParam=paramValue也是被支持的,这样只有参数等于给定的参数值的请求才会被映射。
Spring注解: @RequestParam
注解@RequestParam被用来将请求参数和方法参数绑定在一起。注解@RequestBody用来表明参数被绑定到HTTP request body中的值。在发送回应的时候,注解@ResponseBody能够白用来将值返回到HTTPrquest body中。
@Controller
@RequestMapping("/stockquote")
public class StockController {
.....
@RequestMapping(method=RequestMethod.GET)
public double getStockPrice(@RequestParam("stockSymbol") String stockSymbol, Model model) {
...
model.setAttribute("stockSymbol", stockSymbol);
...
}
.....
.....
}
复制代码
Spring中的RESTful客户端
我们前面提到过,RestTemplate是用来在客户端访问RESTful服务的类。仅管和其他的Spring中的模板类很相似,我们还是可以通过提供回调方法和配置HttpMessageConverter类来客户化该模板。客户端的操作可以完全使用RestTemplate和HttpMessageConveter类来执行。
RestTemplate类
在Java中,Jakarta Commons HttpClient类被用来调用RESTful服务。对于普通的操作,HttpClient的executeMethod被用来执行对应6种HTTP方法的高层次的操作。RestTemplate提供了一组方法来确保REST的最佳实践。RestTemplate类提供的这些方法对应的HTTP方法是:
RestTemplate类的方法名传递的含义很简单。第一部分是其对应的HTTP方法的名字;第二部分表明了返回的值。例如getForObject方法,该方法会执行GET操作并从HTTP response中返回一个对象(HTTP response被转换成对象类型)。同样的,postForLocation方法执行一个POST操作并返回一个HTTP location header,指明了新创建的对象的位置。
RestTemplate类的方法接受一个字符串类型的URL。RestTemplate对象可以使用默认的构造函数来创建,客户使用java.net包中的API来创建HTTP request。下面是一个客户使用RestTemplate类访问RESTful web service的例子
........
String uri = "http://stock.com/stockdata/{symbol}/stockquote";
RestTemplate template = new RestTemplate();
StockQuote sq = new StockQuote();
........
URI location = template.postForLocation(uri, sq, "INFY");
........
复制代码
HTTP Message转换器
发送给RestTemplate方法的对象以及从RestTemplate方法返回的对象被HttpMessageConverter接口转换成HTTP消息——HTTP request和HTTP response。该接口有以下的方法:
boolean canRead(Class<?>clazz, MediaType mediaType):用来判定给定的类和媒体类型能否被转换器读
boolean canWrite(Class<?> clazz, MediaType mediaType):用来判定给定的类和媒体类型能否被转换器写
List<MediaType> getSupportedMediaTypes():返回一个支持的MediaType对象的列表
T read(Class<T> clazz, HttpInputMessage inputMessage):从给定的inputMessage中读取对象并返回该对象
void write(T t, HttpOutputMessage outputMessage):将给定的对象写入给定的outputMessage中。
对MIME类型的转换器是默认生效的。我们也可以编写客户自己的转换器。下面的表格中列出了默认的转换器的实例:
总结
RESTful web service最适合于需要无状态的web service的情况,这种情况下基于REST的价格提供了更好的性能和缓存选择。本文中我们介绍了Spring框架对构建RESTful web service提供的良好的支持,使得可以使用注解和象RestTemplate这样API简单而优雅的构建一个RESTful web service。
首先让我们简单的复习一下。RESTful web service是使用REST原则创建和访问的web service。RESTful web service是使用HTTP没方法来执行操作的,能够很容易的通过URI进行访问。HTTP方法POST,GET,PUT和DELETE能够被映射到创建、读取、更新和删除(CRUD)操作。
使用JAX-RS的RESTful Web Service
JAX-RS是一个Java编程的API(JSR 311),是Java EE平台的一部分。JAX-RS被设计用来简化使用REST原则和架构的Java应用程序的开发。通过使用注解,JAX-RS开发人员能够将POJO暴露为web资源。和其他的Java web应用程序一样,JAX-RS应用程序被打包为WAR文件,并布署在支持Java Servlet API的容器上。
在Java中开发JAX-RS应用程序的方法之一就是使用Jersey。Jersey是一个开源的、质量良好的JAX-RS参考实现。Jersey实现了所有的API,并且提供了能够快速简便的开发REST类型的Java web service的注解。它还使用自己定义的API(如Jersey Client API)提供了很多附加的特性。对于RESTful web service,Jersey使用的是名为Grizzly的web 服务器。对该容器的请求会被一个Grizzly
Servlet处理,该Servlet的全名是com.sun.jersey.spi.container.servlet.ServletContainer.
使用Spring编写RESTful web service
使用Spring MVC对RESTful web service的支持,Java开发人员能够使用继承自Spring的MVC框架的注解来构建RESTful的应用程序。对于RESTful应用程序的客户端的支持是RestTemplate API提供的,该API在概念上和JdbcTemplate或JmsTemplate十分类似。REST功能是HttpConverters类提供的,该类帮助将对象转换成HTTP请求或回应中的representation,或者是相反的过程。为了完成对象和XML之间的映射,Spring提供了MarshallingHttpMessageConverter类。
Spring web MVC使用了DispatcherServlet来将请求分发给处理器。默认的处理器是使用@Controller和@RequestMapping注解标明的。这两个注解在使用Spring开发RESTful的应用程序扮演了主要的角色,实际上这两个注解和另外一个注解#PathVariable构成了Spring中RESTful功能的基础。注解@Controller被用来将一个POJO标记为控制器,注解@RequestMapping用来将请求映射到类或处理器方法。
Spring控制器和RESTful web service
控制器对应Spring web MVC中的C。它们帮助处理用户输入,并为用户将输入通过视图(view)转换为模型(model)。控制器可以通过@controller注解来声明。通常,我们在一个类的顶端使用该注解来上面这个特定的类是控制器。
@Controller
public class StockController {
private final Stock stock;
@AutoWired
public StockController(Stock stock) {
this.stock = stock;
}
@RequestMapping("/")
public void stockInfo() {
}
@RequestMapping("/stockdetails")
public String getStockDetails() {
return this.stock.getStockDetails();
}
}
复制代码
注解@RequestMapping并不要求被使用在类级别上,它也可以被使用在方法级别上。根据absolute路径,控制器会调用合适的方法。
URI模板
一个URI模板是一个将URI作为字符串保持的模板。通常,一个URI模板会含有变量,当这些变量被值替换的时候,URI模板就变成了实际的URI。我们可以在@RequestMapping注解中使用URI模板。
例如,URI http://www.helloworld.com/users/{username}就是一个URI模板,允许使用实际的用户名来替换username,例如http://www.helloworld.com/users/john
。处理器将实际的UIR和URI模板进行比较并替换其中的参数。
@RequestMapping(value="/users/{username}", method=RequestMethod.GET)
public String sayHello(Model model) {
......
return "Hello, Welcome!";
}
复制代码
Spring注解: @PathVariable
注解@PathVariable被用来将UIR模板变量和方法参数绑定到一起。在前面的例子中,可以使用@PathVariable注解就爱那个URI模板变量username和方法参数userName绑定到一起。使用了@PathVariable声明的方法参数的类型并不一定要是字符串,可以是原始类型,如int,long,double等。
@RequestMapping(value="/users/{username}", method=RequestMethod.GET)
public String sayHello(@PathVariable("username") String userName, Model model) {
......
return "Hello "+userName+", Welcome!";
}
复制代码
可以将多个URI模板变量绑定到方法的参数中,如:
@RequestMapping(value="/users/{username}/city/{cityname}", method=RequestMethod.GET)
public String sayHello(@PathVariable("username") String userName, @PathVariable("cityname") String cityName, Model model) {
......
}
复制代码
URI模板变量也可以来找相对路径:
@Controller
@RequestMapping(value="/users/{username}")
public class SayHelloController {
@RequestMapping(value="/city/{cityname}")
public String sayHello(@PathVariable("username") String userName, @PathVariable("cityname") String cityName, Model model) {
......
}
}
复制代码
参数化的添加如myParam=paramValue也是被支持的,这样只有参数等于给定的参数值的请求才会被映射。
Spring注解: @RequestParam
注解@RequestParam被用来将请求参数和方法参数绑定在一起。注解@RequestBody用来表明参数被绑定到HTTP request body中的值。在发送回应的时候,注解@ResponseBody能够白用来将值返回到HTTPrquest body中。
@Controller
@RequestMapping("/stockquote")
public class StockController {
.....
@RequestMapping(method=RequestMethod.GET)
public double getStockPrice(@RequestParam("stockSymbol") String stockSymbol, Model model) {
...
model.setAttribute("stockSymbol", stockSymbol);
...
}
.....
.....
}
复制代码
Spring中的RESTful客户端
我们前面提到过,RestTemplate是用来在客户端访问RESTful服务的类。仅管和其他的Spring中的模板类很相似,我们还是可以通过提供回调方法和配置HttpMessageConverter类来客户化该模板。客户端的操作可以完全使用RestTemplate和HttpMessageConveter类来执行。
RestTemplate类
在Java中,Jakarta Commons HttpClient类被用来调用RESTful服务。对于普通的操作,HttpClient的executeMethod被用来执行对应6种HTTP方法的高层次的操作。RestTemplate提供了一组方法来确保REST的最佳实践。RestTemplate类提供的这些方法对应的HTTP方法是:
HTTP方法 | RestTemplate方法 |
GET | getForObject getForEntity |
POST | postForLocation(String url, Object request, String... urlVariables) postForObject(String url, Object request, Class<t> responseType, String...urlVariables) |
PUT | put(String url, Object request, String...urlVariables) |
DELETE | delete |
HEAD | headForHeaders(String url, String... urlVariables) |
OPTIONS | optionsForAllow(String url, String... urlVariables) |
RestTemplate类的方法接受一个字符串类型的URL。RestTemplate对象可以使用默认的构造函数来创建,客户使用java.net包中的API来创建HTTP request。下面是一个客户使用RestTemplate类访问RESTful web service的例子
........
String uri = "http://stock.com/stockdata/{symbol}/stockquote";
RestTemplate template = new RestTemplate();
StockQuote sq = new StockQuote();
........
URI location = template.postForLocation(uri, sq, "INFY");
........
复制代码
HTTP Message转换器
发送给RestTemplate方法的对象以及从RestTemplate方法返回的对象被HttpMessageConverter接口转换成HTTP消息——HTTP request和HTTP response。该接口有以下的方法:
boolean canRead(Class<?>clazz, MediaType mediaType):用来判定给定的类和媒体类型能否被转换器读
boolean canWrite(Class<?> clazz, MediaType mediaType):用来判定给定的类和媒体类型能否被转换器写
List<MediaType> getSupportedMediaTypes():返回一个支持的MediaType对象的列表
T read(Class<T> clazz, HttpInputMessage inputMessage):从给定的inputMessage中读取对象并返回该对象
void write(T t, HttpOutputMessage outputMessage):将给定的对象写入给定的outputMessage中。
对MIME类型的转换器是默认生效的。我们也可以编写客户自己的转换器。下面的表格中列出了默认的转换器的实例:
转换器 | 详细 |
ByteArrayHttpMessageConverter | 能够从HTTP message中读写byte数组的转换器 支持所有的MIME类型*/*,默认使用application/octet-stream进行写 |
StringHttpMessageConverter | 从HTTP message中读写String对象的转换器 支持MIME类型text/*,默认使用text/plain进行写 |
FormHttpMessageConverter | 从HTTP message中读写表单数据 默认支持MIME类型application/x-www-form-urlencoded |
SourceHttpMessageConverter | 可以从HTTP message中读写javax.xml.transform.Source的转换器。支持的Source只有DOMSource,SAXSource和StreamSource 默认支持的MIME类型是text/xml和application/xml。 |
MarshallingHttpMessageConverter | 可以使用Spring的Marshaller和UnMarshaller来读写xml的转换器 默认支持的MIME类型是text/xml和application/xml。 |
MappingJacksonHttpMessageConverter | 可以使用Jackson ObjectMapper读取JSON的转换器 默认支持的MIME类型是application/json |
BufferedImageHttpMessageConverter | 可以从HTTP message读写java.awt.image.BufferedImage的转换器 支持所有Java I/O API支持的MIME类型 |
RESTful web service最适合于需要无状态的web service的情况,这种情况下基于REST的价格提供了更好的性能和缓存选择。本文中我们介绍了Spring框架对构建RESTful web service提供的良好的支持,使得可以使用注解和象RestTemplate这样API简单而优雅的构建一个RESTful web service。
相关文章推荐
- spring3.0支持restful实例
- spring3.0支持restful实例
- spring 3.0 应用springmvc 构造RESTful URL 详细讲解
- Spring restful web service编码乱码问题
- Apache CXF实现Web Service(3)——Tomcat容器和不借助Spring的普通Servlet实现JAX-RS(RESTful) web service
- Spring3.0新特性 - REST架构的支持
- Spring 支持 Restful风格 源码分析
- Spring创始人:看衰Java EE,Spring3.0将支持REST
- spring 3.0 应用springmvc 构造RESTful URL 详细讲解
- Spring Boot:建立一个RESTful Web Service
- Spring4和Spring3对于restful的支持对比
- Spring restful web service编码乱码问题
- Spring 3支持RESTful API/APP配置示例
- Spring 4.x实现Restful web service
- Spring Boot、Mybatis框架整合开发Java RESTful Web Service
- 使用Spring创建满足RESTful规范的Web Service
- 使用IDEA创建一个简单的基于Spring Boot的RESTful Web Service
- 创建maven spring boot的RESTful Web Service工程(使用IntelliJ IDEA以及无集成开发环境)
- Spring Boot 创建RESTful Web Service
- spring 3.0 应用springmvc 构造RESTful URL 详细讲解