SpringBoot2.x系列教程27--整合SpringMVC之内容协商ContentNegotiation机制
作者:一一哥
一.内容协商ContentNegotiation机制
1.需求概述
我们进行web开发时,现在一般都是设计成RESTful风格的url。如果此时我们希望在请求同一个RESTful的URL时,得到不同的PDF视图、JSON视图、Html视图,也就是说我们需要对同一个url返回多种不同的结果,这该如何实现?
要想实现上面的需求,这就可以用到我今天给大家讲解的内容协商ContentNegotiation机制了!
2.内容协商ContentNegotiation概念
一个URL资源服务端可以以多种形式进行响应:即MIME(MediaType)媒体类型。但对于某一个客户端(浏览器、APP、Excel导出…)来说它只需要一种。此时在客户端和服务端之间就得有一种机制来沟通这个事情,这就是我们要说的内容协商机制。
内容协商机制是指客户端和服务器端就响应的资源内容进行协商交涉,然后提供给客户端最为合适的资源。内容协商是以响应资源的语言、字符集、编码方式等作为判断的基准。
![1370b06e78e7fafaf9cc0475999a49ac.png](https://i-blog.csdnimg.cn/blog_migrate/551eaafcdded9c9cca20662c80b048d9.jpeg)
这也是RESTful服务中很重要的一个特性是:对同一资源可以有多种形式的表述。
3.内容协商常见概念简介
3.1 ContentNegotiationManager
ContentNegotiationManager是Spring Web提供的一个重要工具类,用于判断一个请求的媒体类型MediaType列表。具体的做法是委托给它所维护的一组ContentNegotiationStrategy实例。实际上它自身也实现了接口ContentNegotiationStrategy,使用者可以直接将它作为一个ContentNegotiationStrategy使用。
另外,ContentNegotiationManager也实现了接口MediaTypeFileExtensionResolver,从而可以根据MediaType查找到相应的文件扩展名。这一点也是通过将任务委托给他所维护的一组MediaTypeFileExtensionResolver实例完成的。
3.2 请求头、响应头内容
请求头
- Accept:告诉服务端,客户端这边需要的MIME类型(一般是多个,比如text/plain,application/json等,/表示可以是任何MIME类型的资源);
- Accept-Language:告诉服务端,客户端这边需要的语言;
- Accept-Charset:告诉服务端,客户端这边需要的字符集;
- Accept-Encoding:告诉服务端,客户端需要的压缩方式(gzip,deflate,br)。
响应头
- Content-Type:告诉客户端,服务器端响应的媒体类型(如application/json、text/html等);
- Content-Language:告诉客户端,服务器端响应的语言;
- Content-Charset:告诉客户端,服务器端响应的字符集;
- Content-Encoding:告诉客户端,服务器端响应的压缩方式(gzip)。
3.3 Accept与Content-Type的区别
一般来说,Accept属于请求头,Content-Type属于响应头,但这并不完全准确。在前后端分离的请求中,在前端的request请求上大都有Content-Type:application/json;charset=utf-8这个请求头,因此可见Content-Type并不仅仅属于响应头。其实Content-Type指请求消息体的数据格式,因为请求和响应中都可以有消息体,所以它既可以用在请求头中,也可以用在响应头中。
3.4 HTTP协议格式
<request-line>(请求消息行)
<headers>(请求消息头)
<blank line>(请求空白行)
<request-body>(请求消息体)
4. Http内容协商的方式
http内容协商的方式大致有两种:
- ①.服务端将可用的MIME类型列表发给客户端,客户端选择某个MIME类型后再告诉服务端。这样服务端就按照客户端告诉它的MIME类型来返回给它具体的内容。(缺点:多一次网络交互,而且使用对使用者要求高,所以此方式一般不用)
- ②.客户端发请求时就指明需要的MIME类型(比如Http头部的Accept),服务端根据客户端指定的要求返回合适的内容类型,并且在响应头中做出说明(如Content-Type)。如果客户端要求的MIME类型数据服务端提供不了,那就会产生406异常。
5. Spring MVC内容协商方式
Spring MVC在实现了HTTP内容协商的同时,又进行了扩展,它支持4种协商方式:
HTTP的Accept头;
扩展名;
请求参数;
固定类型(producers).
二.Spring MVC内容协商验证
我们创建一个新的web项目,在该项目中验证Spring MVC的内容协商机制。
1. 验证HTTP的Accept头
1.1 创建测试接口方法
我们在Controller中创建一个测试接口方法。
package com.yy