转自:https://www.cnblogs.com/forerver-elf/p/6610901.html
RPC是面向服务的,并关注与行为和动作;而REST是面向资源的,强调描述应用程序的事务的名词。REST将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户端。
REST
Representational(表述性):REST资源实际上可以用各种形式来进行表述,包括XML,JSON深圳HTML
State(状态):当使用REST的时候,我们更关注资源的状态而不是对资源采取的行为
Transfer(转移):REST涉及到转移资源数据,它以某种表属性形式从一个应用转移到另一个应用
在REST中,资源通过URL进行识别和定位。REST中的行为是通过HTTP方法定义的。这些HTTP方法通常会匹配如下CRUD动作:
Create:POST
Read:GET
Update:PUT或PATCH
Delete:DELETE
Spring支持一下方式来创建REST资源:
控制器可以出了力所有的HTTP方法,包含四个主要的REST方法:GET、PUT、DELETE和POST。Spring3.2及以上版本还支持PATCH方法
借助@PathVariable注解,控制其能够处理参数化URL
借助Spring的视图和视图解析器,资源能够以多种方式进行表述,包括将模型数据渲染为XML、JSON、Atom以及RSS的View实现
可以使用ContentNegotitaingViewResolver来选择最合适客户端的表述
借助@ResponseBody注解和各种HttpMethodConvertor实现,能够替换基于视图的渲染方式
@RequestBody注解以及HttpMethodConvertor实现可以将传入的HTTP数据转化为传入控制器处理方法的Java对象
借助RestTemplate,Spring应用能够方便的使用REST资源
Spring提供了两种方法将资源的Java表述形式转换为发送给客户端的表述形式
内容协商(Content negotiation):选择一个视图,它能够将模型渲染为呈现给客户端的表述形式
消息转换器(Message conversion):通过一个消息转换器将控制器所返回的对象转换为呈现给客户端的表述形式
Spring的ContentNegotiatingViewResolver是一个特殊的视图解析器,它考虑到了客户端所需要的内容类型。按照其最简单的形式,ContentNegitiatingViewResolver可以按照如下配置,它可以完成两个功能:确定请求的媒体类型和找到合适请求媒体类型的最佳视图
@Bean
public ViewResolver cnViewResolver(){
return new ContentNegotiatingViewResolver();
}
确定请求的媒体类型
ContentNegotitaingViewResolver会考虑Accept头部信息并使用它所请求的媒体类型,但是它会首先查看URL的文件扩展名。如果URL在结尾处有文件扩展名,ContentNegotiatingViewResolver将会给予该扩展名确定所需的类型,如果扩展名是.json,那么所需的内容类型必须是”application/json”。如果扩展名是.xml,那么客户端请求的是”application/xml”。如果根据文件扩展名不能得到任何媒体类型的话,那么就会考虑Accept头部信息。此时,Accept头部信息中的值就表明了客户端想要的MIME类型。如果没有Accept头部信息,并且扩展名也无法提供任何帮助的话,ContentNegotiatingViewResolver将会使用/作为默认的内容,这意味着客户端必须要接受服务器发送的任何形式的表述。一旦内容类型确定之后,ContentNegotiatingViewResolver就会将逻辑视图名解析为渲染模型的View,ContentNegotiatingViewResolver本身不会解析视图,而是委托给其他的视图解析器,让它们来解析视图。ContentNegotiatingViewResolver要求其他的视图解析器将逻辑视图名解析为视图。解析得到的每个视图都会放到一个列表中,这个列表装配完成后,ContentNegotiatingViewResolver会循环客户端请求的所有媒体类型,在候选的收中查找能够产生对应内容类型的视图。第一个匹配的视图会用来渲染模型。
影响媒体类型的选择
通过设置ContentNegotiationManager可以改变选择媒体类型的策略,ContentNegotiationManager可以做到
指定默认的内容类型,如果根据请求无法得到内容类型的话,会使用默认值
通过请求参数指定内容类型
忽视请求的Accept头部信息
将请求的扩展名映射为特定的媒体类型
将JAF(Java Activation Framework)作为根据扩展名名查找媒体类型的备用方案
有三种配置ContentNegotiationManager方法
直接声明一个ContentNegotiationManager类型的bean
通过ContentNegotiationManagerFactoryBean间接创建bean
重载WebMvcConfigurerAdapater的configureContentNegotiation()方法。
使用Java配置,获得ContentNegotiationManager的最简便方法就是扩展WebMvcConfigurerAdapter并重新configureContentNegotiation()方法。
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer){
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
ContentNegotiatingViewResolver最大的优势在于它在Spring MVC之上构建了REST资源表述层,控制器代码无需修改。相同一套控制器方法能够产生HTML,也可以产生JSON或XML。ContentNegotiatingViewResolver作为ViewResolver的实现,它只能决定资源该如何渲染到客户端,并没有涉及到客户端要发送什么样的表述给控制器,如果客户端发送JSON或XML的话,ContentNegotiatingViewResolver就无法识别。
使用HTTP信息转换器
消息转换(message conversion)提供了一种更为直接的方式,它能将控制器产生的数据转换为服务于客户端的表述形式。当使用消息转换功能时,DispatcherServlet不再需要那么麻烦地将模型数据传送到视图中。
Spring自带了各种各样的转换器,用于实现资源表述与各种Java类型之间的互相转换
AtomFeedHttpMessageConverter Rome Feed对象和Atom feed之间相互转换(如果Rome包在类路径下将会进行注册)
BufferedImageHttpMessageConverter BufferedImages与图片二进制数据之间相互转换
ByteArrayHttpMessageConverter 读取/写入字节数组。从所有媒体类型中读取,并以application/octet-stream格式写入
FormHttpMessageConverter 将application/x-www-form-urlencode内容读入到MultiValueMap