[Spring] Spring 3.0对RESTful web service的支持

  尽管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注解来声明。通常,我们在一个类的顶端使用该注解来上面这个特定的类是控制器。
  1. @Controller
  2. public class StockController {
  3.    private final Stock stock;
  4.    @AutoWired
  5.    public StockController(Stock stock) {
  6.       this.stock = stock;
  7.    }
  8.    @RequestMapping("/")
  9.    public void stockInfo() {
  10.    }
  11.    @RequestMapping("/stockdetails")
  12.    public String getStockDetails() {
  13.       return this.stock.getStockDetails();
  14.    }
  15. }
复制代码
    注解@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模板进行比较并替换其中的参数。
  1. @RequestMapping(value="/users/{username}", method=RequestMethod.GET)
  2. public String sayHello(Model model) {
  3.    ......
  4.    return "Hello, Welcome!";
  5. }
复制代码


Spring注解 : @PathVariable
    注解@PathVariable被用来将UIR模板变量和方法参数绑定到一起。在前面的例子中,可以使用@PathVariable注解就爱那个URI模板变量username和方法参数userName绑定到一起。使用了@PathVariable声明的方法参数的类型并不一定要是字符串,可以是原始类型,如int,long,double等。
  1. @RequestMapping(value="/users/{username}", method=RequestMethod.GET)
  2. public String sayHello(@PathVariable("username") String userName, Model model) {
  3.    ......
  4.    return "Hello "+userName+", Welcome!";
  5. }
复制代码
    可以将多个URI模板变量绑定到方法的参数中,如:
  1. @RequestMapping(value="/users/{username}/city/{cityname}", method=RequestMethod.GET)
  2. public String sayHello(@PathVariable("username") String userName, @PathVariable("cityname")  String cityName, Model model) {
  3.    ......
  4. }
复制代码
    URI模板变量也可以来找相对路径:
  1. @Controller
  2. @RequestMapping(value="/users/{username}")
  3. public class SayHelloController {
  4.    @RequestMapping(value="/city/{cityname}")
  5.    public String sayHello(@PathVariable("username") String userName, @PathVariable("cityname")  String cityName, Model model) {
  6.    ......
  7.    }
  8. }
复制代码
    参数化的添加如myParam=paramValue也是被支持的,这样只有参数等于给定的参数值的请求才会被映射。

Spring注解 : @RequestParam
    注解@RequestParam被用来将请求参数和方法参数绑定在一起。注解@RequestBody用来表明参数被绑定到HTTP request body中的值。在发送回应的时候,注解@ResponseBody能够白用来将值返回到HTTPrquest body中。
  1. @Controller
  2. @RequestMapping("/stockquote")
  3. public class StockController {
  4.    .....
  5.    @RequestMapping(method=RequestMethod.GET)
  6.    public double getStockPrice(@RequestParam("stockSymbol") String stockSymbol, Model model) {
  7.       ...
  8.       model.setAttribute("stockSymbol", stockSymbol);
  9.       ...
  10.    }
  11.    .....
  12.    .....
  13. }
复制代码


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类的方法名传递的含义很简单。第一部分是其对应的HTTP方法的名字;第二部分表明了返回的值。例如getForObject方法,该方法会执行GET操作并从HTTP response中返回一个对象(HTTP response被转换成对象类型)。同样的,postForLocation方法执行一个POST操作并返回一个HTTP location header,指明了新创建的对象的位置。
    RestTemplate类的方法接受一个字符串类型的URL。RestTemplate对象可以使用默认的构造函数来创建,客户使用java.net包中的API来创建HTTP request。下面是一个客户使用RestTemplate类访问RESTful web service的例子
  1. ........
  2. String uri = "http://stock.com/stockdata/{symbol}/stockquote";
  3. RestTemplate template = new RestTemplate();
  4. StockQuote sq = new StockQuote();
  5. ........
  6. URI location = template.postForLocation(uri, sq, "INFY");
  7. ........
复制代码

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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值