当前位置: 首页 > news >正文

SpringBoot-Web开发之内容协商

  • 根据客户端接收能力不同,返回不同媒体类型的数据

默认协商规则

基于请求头内容协商:(默认开启)
  • 客户端向服务端发送请求,携带HTTP标准的Accept请求头,例如:application/json 、 text/xml 、 text/yaml
  • 服务端根据客户端请求头期望的数据类型进⾏动态返回
基于请求参数内容协商:(需要开启)
  • 发送请求 GET /projects/spring-boot?format=json
  • 匹配到 @GetMapping("/projects/spring-boot")
  • 根据参数协商,优先返回 json 类型数据【需要开启参数匹配设置】
  • 发送请求 GET /projects/spring-boot?format=xml,优先返回 xml 类型数据
# 开启基于请求参数的内容协商功能。 默认此功能不开启
spring.mvc.contentnegotiation.favor-parameter=true
# 指定内容协商时请求路径里使⽤的参数名。默认是 format
spring.mvc.contentnegotiation.parameter-name=type
http://localhost:8080/test/person?format=json 
http://localhost:8080/test/person?format=xml

内容协商原理

  • 判断当前响应头中是否已经有确定的媒体类型。MediaType
  • 获取客户端Accept请求头字段,判断支持接收的内容类型
    • contentNegotiationManager类,内容协商管理器,默认使用基于请求头的策略
    • HeaderContentNegotiationStrategy 确定客户端可以接收的内容类型

  • 遍历循环所有当前系统的 MessageConverter,看谁支持操作返回对象

  • 找到支持操作返回格式的converter,把converter支持的媒体类型统计出来
  • 比如json、xml等等,进行内容协商的最佳匹配媒体类型
  • 用支持将对象转为最佳匹配媒体类型的converter进行转化

自定义MessageConverter

1. MessageConverter作用

  • 使用注解@ResponseBody的Controller方法响应数据出去,通过调用 RequestResponseBodyMethodProcessor 处理
  • Processor 处理方法通过 MessageConverter 处理返回值
  • 所有 MessageConverter 合起来可以支持各种媒体类型数据的操作(读、写)
  • 内容协商找到最终的 messageConverter

2.  自定义MessageConverter

  • 配置类中添加一个 WebMvcConfigurer
@Bean
public WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer() {@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {//加入自定义的Converterconverters.add(new MyMessageConverter());}}
}
public class MyMessageConverter implements HttpMessageConverter<Person> {@Overridepublic boolean canRead(Class<?> clazz, MediaType mediaType) {return false;}@Overridepublic boolean canWrite(Class<?> clazz, MediaType mediaType) {//匹配是否是person类型return clazz.isAssignableFrom(Person.class);}/*** 服务器要统计所有MessageConverter都能写出哪些内容类型** application/x-my* @return*/@Overridepublic List<MediaType> getSupportedMediaTypes() {return MediaType.parseMediaTypes("application/x-my");}@Overridepublic Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage)throws IOException, HttpMessageNotReadableException {return null;}@Overridepublic void write(Person person, MediaType contentType, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException {//自定义协议数据的写出格式String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth();//写出去OutputStream body = outputMessage.getBody();body.write(data.getBytes());}
}
  • 自定义后效果 

  • 此时的配置只支持匹配请求头是application/x-my,不支持匹配请求参数format=my

3. 适配请求参数format=自定义

  • 配置类实现:配置类中WebMvcConfigurer重写configureContentNegotiation()
    • 第一种重写方法:覆盖默认协商策略strategies和媒体类型mediaTypes,全自定义
    • 第二种重写方法:只是追加媒体类型mediaTypes
/*** 自定义内容协商策略* @param configurer*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {Map<String, MediaType> mediaTypes = new HashMap<>();mediaTypes.put("json",MediaType.APPLICATION_JSON);mediaTypes.put("xml",MediaType.APPLICATION_XML);mediaTypes.put("my",MediaType.parseMediaType("application/x-my"));//指定支持解析哪些参数对应的哪些媒体类型//配置匹配参数format的策略ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);//自定义匹配的参数,默认为format//parameterStrategy.setParameterName("ff");//配置匹配请求头策略,否则就是匹配*/*HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();//此处自定义后将覆盖默认的strategiesconfigurer.strategies(Arrays.asList(parameterStrategy,headerStrategy));
}
/*** 自定义内容协商策略* @param configurer*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {//添加自定义的媒体类型configurer.mediaType("my",MediaType.parseMediaType("application/x-my"));
}
  • 注解实现
spring:mvc:hiddenmethod:filter:enabled: true   #restFul的过滤器contentnegotiation:favor-parameter: true   #开启支持请求参数进行内容协商media-types:my: application/x-my  #自定义内容协商的媒体类型

http://www.dtcms.com/a/519349.html

相关文章:

  • 实现一个JSON工具类自动处理JSON转String
  • 域名注册网站那个好企业服务官网
  • SpringBoot-数据访问之MyBatis与Redis
  • iOS 26 App 运行状况全面解析 多工具协同监控与调试实战指南
  • uts ios插件开发tips
  • 单页营销型网站全国城建中心官方网站
  • 了解sip和rtp是什么
  • MySQL-3-函数应用及多表查询
  • 自然语言处理分享系列-词语和短语的分布式表示及其组合性(二)
  • 网站建设珠海 新盈科技泉州建站模板
  • ISO 8601日期时间标准及其在JavaScript、SQLite与MySQL中的应用解析
  • 利用博客做网站排名南京外贸网站建设案例
  • 使用 VS Code 的 Dev Containers 插件,通过跳板机间接连接docker
  • 衡水城乡建设局网站首页北京网站建设华大
  • 湛江网站建设哪家优惠多常见的网站结构有哪些
  • php网站源码架构seo标题生成器
  • ui设计师与网站编辑有什么关系重庆森林为什么不能看
  • 站长工具成品源码广西贵港建设集团有限公司网站
  • 电子商务网站建设技术解决方案wordpress ios
  • 企业是如何做电子商务网站软件开发培训机构去学
  • 摄影网站策划书wordpress 赞 分享
  • 深圳我的网站深圳市工程交易服务网宝安
  • php制作wap网站开发我国酒店网站建设存在的问题
  • 金坛网站建设企业手机网站建设渠道
  • 做网站要不要钱东莞网站快速优化排名
  • 做微信营销网站建设dw个人简历网页制作
  • 建个免费的销售网站好asp net4.0网站开发
  • 给个能看的网站中国500强企业名称
  • 网站一般用什么免费字体云主机wordpress
  • 旅游网站流程图电子商务网站开发的视频