您的位置:首页 > 编程语言 > Java开发

[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方法是:

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的例子

........

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: