需要实现RESTful功能的Spring MVC控制器

@Controller
@RequestMapping("/spittle")
public class SpittleApiController {

    private static final String MAX_LONG_AS_STRING = "9223372036854775807";

    private SpittleRepository spittleRepository;

    @Autowired
    public SpittleApiController(SpittleRepository spittleRepository) {
        this.spittleRepository = spittleRepository;
    }

    @RequestMapping(method = RequestMethod.GET)
    public List<Spittle> spittles(@RequestParam(value = "max", defaultValue = MAX_LONG_AS_STRING) long max,
            @RequestParam(value = "count", defaultValue = "20") int count) {
        return spittleRepository.findSpittles(max, count);
    }

}

1、Spring提供了2种将Java表述形式转换为发给客户端的表述形式的方式。

内容协商

选择一个视图,能够将模型渲染为呈现给客户端的表述形式

这种方式一般不用

消息转换器

使用HTTP信息转换器

这是一种直接的方式,将控制器的数据转换为服务于客户端的表述形式。

当使用消息转换功能时, DispatcherServlet不用麻烦地将模型传递给视图中。

这里没有视图,甚至没有模型,只有控制器产生的数据,然后经过消息转换器,产生资源表述,传到客户端。

Spring中自带了各种各样的转换器,能够满足常见的对象转换为表述的需求。

例如,客户端通过请求的Accept头信息表明它能接受"application/json",并且Jackson JSON在类路径下,那么处理方法返回的对象将交给MappingJacksonHttpMessageConverter,由他转换为返回客户端的JSON表述形式。

或者,如果请求的头信息表明客户端想要"text/xml"格式,那么Jaxb2RootElementHttpMessageConverter将会为客户端产生XML表述形式。

restful 点对点 rest端点_客户端

除了其中5个外,其它都是自动注册的,不需要Spring配置;但是为了支持他们,需要把对应的库添加到类路径中。

2、消息转换器的具体用法

在响应体中返回资源状态

正常情况,如果控制器方法返回Java对象,这个对象会放到模型中,并在视图中渲染。

为了使用消息转换功能,我们需要告诉Spring跳过正常的模型/视图流程,并使用消息转换器。

最简单的方式:使用@ResponseBody

@RequestMapping(method = RequestMethod.GET, produces = "application/json")
public @ResponseBody List<Spittle> spittles(@RequestParam(value = "max", defaultValue = MAX_LONG_AS_STRING) long max,
        @RequestParam(value = "count", defaultValue = "20") int count) {
    return spittleRepository.findSpittles(max, count);
}

@ResponseBody会告诉Spring,我们要将返回的对象作为资源发送给客户端,并转换为客户端要求的表述形式。

DispatcherServlet会根据请求中Accept头部信息,找到对应的消息转换器,然后把Java对象转换为客户端需要的表述形式。

例如客户端请求的Accept头部信息表明它接收"application/json",且Jackson JSON库位于应用的类路径下,那么将选择MappingJacksonHttpMessageConverter或MappingJackson2HttpMessageConverter(取决于类路径下是哪个版本的Jackson)作为消息转换器,并将Java对象转换为JSON文档,写入到相应体中。

restful 点对点 rest端点_JSON_02

@ RequestMapping中produces属性,代表该控制器只处理预期输出为JSON的请求,也就是Accept头信息包含"application/json"的请求。

其它类型请求,即使URL匹配且为GET请求,也不会被处理。

这样的请求会被其它的方法进行处理(有适当方法的情况下),或者返回HTTP 406(Not Acceptable)响应。

请求体中接收资源状态

上面只讨论了如何将一个REST资源转换为客户端所需要的表述,这里讨论如何将客户端发送过来的资源状态表述转换为JAVA对象。

使用@RequestBody注解

@RequestMapping(method = RequestMethod.POST, consumes = "application/json")
public @ResponseBody Spittle saveSpittle(@RequestBody Spittle spittle) {
    return spittleRepository.save(spittle);
}

@RequestBody表明

a、这个控制器方法,只能处理/spittles(定义在类级别上了)的POST请求,而且请求中预期要包含一个Spittle的资源表述

b、Spring会根据请求的Content-Type头信息,查找对应的消息转换器,把客户端发送的资源的表述形式(JSON,或HTMl)转化为Java对象

为控制器默认设置消息转换

@RestController注解(Spring 4.0及以上)

使用@RestController代替@Controller标注控制器,Spring会为所有方法应用消息转换功能,我们就不用每个方法添加@ResponseBody,当然@RequestBody如果需要使用到,是不能省略的