对象转换为所需的内容类型。JAX-RS实现 需要具备一个JAXB MessageBodyWriter,这可以使用具有注解@Provider的客户化MessageBodyWriter实现 。
使用Spring MVC设定响应体数据
在Spring MVC中,响应是通过一个视图解析过程来实现的,这样就可以从一系列视图技术中选择了。 但在与Web Services客户端交互时,更加合理的方式则是舍弃视图解析过程,转而使用方法所返回的对象 :
@RequestMapping(value="/{username}", method=GET)
public @ResponseBody Account getAccount(@PathVariable String username) {
return accountRepository.findAccountByUsername(username);
}
如果对控制器方法或其返回类型应用注解@ResponseBody,那么就会使用HttpMessageConverter处理返 回值,然后用该返回值设定响应体。用于请求体参数的HttpMessageConverter集合也用于响应体,因此无 需再做任何配置。
状态代码与响应头
JAX-RS使用一个链式API来构建响应:
@PUT @Path("{username}")
public Response updateAccount(Account account) {
// ...
return Response.noContent().build(); // 204 (No Content)
}
这可以与UriBuilder联合使用来为Location响应头创建实体链接:
@POST
public Response createAccount(Account account) {
// ...
URI accountLocation = uriInfo.getAbsolutePathBuilder().path(account.getUsername ()).build();
return Response.created(accountLocation).build();
}
上面代码中所用的uriInfo要么被注入到根资源(使用了@Context)中,要么是从父资源传递给子资源 。它可以附加到当前请求的路径之后。
Spring MVC提供了一个注解来设定响应代码:
@RequestMapping(method=PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updateAccount(@RequestBody Account account) {
// ...
}
Spring MVC与JAX-RS比较与分析(10)
时间:2011-10-22 infoq 译:张龙
可以直接使用HttpServletResponse对象设定Location头:
@RequestMapping(method=POST)
@ResponseStatus(CREATED)
public void createAccount(@RequestBody Account account, HttpServletRequest request,
HttpServletResponse response) {
// ...
String requestUrl = request.getRequestURL().toString();
URI uri = new UriTemplate("{requestUrl}/{username}").expand(requestUrl, account.getUsername());
response.setHeader("Location", uri.toASCIIString());
}
异常处理
JAX-RS允许资源方法抛出WebApplicationException类型的异常,该异常会包含一个响应。下面的示例 代码将一个JPA NoResultException转换为特定于Jersey的NotFoundException,这会导致一个404的错误 :
@GET
@Path("{username}")
public Account getAccount(@PathParam("username") String username) {
try {
return accountRepository.findAccountByUsername(username);
} catch (NoResultException e) {
throw new NotFoundException();
}
}
WebApplicationException实例会封装必要的逻辑来生成特定的响应,但每个独立的资源类方法中都需 要捕获异常。
Spring MVC支持定义控制器级别的方法来处理异常:
@Controller
@RequestMapping("/accounts")
public class AccountController {
@ResponseStatus(NOT_FOUND)
@ExceptionHandler({NoResultException.class})
public void handle() {
//
|