Spring-web源码解析之ContentNegotiationStrategy

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 基于4.1.7.RELEASErequest和mediatypes解析的策略类,其唯一的一个接口是List resolveMediaTypes(NativeWebRequest we...

基于4.1.7.RELEASE


request和mediatypes解析的策略类,其唯一的一个接口是

List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException;

该接口负责将给与的request解析出对应的MediaType来,其实现有以下几种

  1. FixedContentNegotiationStrategy
    固定类型解析 : 返回固定的MediaType,每个类都有一个defaultContentType,在构造函数时需要传入默认的MediaType类型,其接口实现方式如下
    @Override
    public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) {
       return Collections.singletonList(this.defaultContentType);
    }

  2. HeaderContentNegotiationStrategy
    accept Header解析 : 负责解析request头中的accept,接口实现如下
    @Override
    public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
       String acceptHeader = webRequest.getHeader(ACCEPT_HEADER);
       try {
          if (StringUtils.hasText(acceptHeader)) {
             List<MediaType> mediaTypes = MediaType.parseMediaTypes(acceptHeader);
             MediaType.sortBySpecificityAndQuality(mediaTypes);
             return mediaTypes;
          }
       }
       catch (InvalidMediaTypeException ex) {
          throw  ;
       }
       return Collections.emptyList();
    }

    这里首先从request中取出Accept对应的字段,然后解析将其包装成MeidaType,排完序后返回MediaType列表。下面举例来说明:
    比如我有一个请求  Accept是这样  
    Accept:image/webp,image/*,*/*;q=0.8
    在上面的步骤中,首先会取出Accept对应的字段交给MediaType.parseMediaTypes进行包装,根据正则表达式 “ ,\\s* ”进行分割,分割后字符串变成了如下形式[imgage/webp] [image/*] [*/*;q=0.8]
    然后逐个对数组元素进行判断,判断规则如下
    1 根据 “;” 符号进行拆分
    2 拆分出的第一部分再根据  “/“ 进行拆分
    3 判断步骤2中拆分出的两部分是否符合  */xxx 的模式,如果是,则抛出异常,这里只允许   */*,  xx/* , xx/xx  的模式 (type/subType)
    4 对步骤1中第二部分根据 ”=“ 号拆分,将其封装进MediaType的parameterMap中
    5 将步骤3中的type和subType封装进MediaType

    到此处理完毕之后就返回解析出的MediaTypes。

  3. ParameterContentNegotiationStrategy
    parameter解析 : 根据request中的参数来判断mediaType的类型,默认的参数名为format,在其构造函数中需要传递一个mediaType的Map,在解析format时,format对应的值就会在这个map里寻找匹配MediaType。其参数名可以使用setParameterName方法注入修改。
    举例: http://xxx.alibaba-inc.com/xx?format=json  时,会根据format的值json,去寻找json对应的MediaType类型。
    @Override
    protected String getMediaTypeKey(NativeWebRequest webRequest) {
       return webRequest.getParameter(this.parameterName);
    }

    根据MediaTypeKey去寻找MediaType。

  4. PathExtensionContentNegotiationStrategy
    路径名解析 : 根据请求路径的后缀名来判断用哪种MediaType,默认忽略未知的路径扩展名,比如说我们常见的 xx.html,xx.json ,里的.html,.json都是已知的路径扩展名,对于程序来说,只要没有匹配上就属于未知的扩展名。
    在寻找路径名匹配的过程中,如果在构造函数中的Map中没有找到MediaType,会采用JAF作为备用机制来查询MediaType。
    @Override
    protected String getMediaTypeKey(NativeWebRequest webRequest) {
       HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
       if (servletRequest == null) {
          return null;
       }
       String path = urlPathHelper.getLookupPathForRequest(servletRequest);
       String filename = WebUtils.extractFullFilenameFromUrlPath(path);
       String extension = StringUtils.getFilenameExtension(filename);
       return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;
    }

    根据MediaTypeKey去寻找MediaType。

  5. ServletPathExtensionContentNegotiationStrategy
    属于4的扩展,作为4的一种备用机制使用ServletContext.getMIMEType来匹配MediaType,备用机制的实现是在handlerNoMatch方法里,如果是application/octet-stream类型(比如上传文件),则不采用该备用机制。

    总结:4种策略  固定类型,accept Header解析,parameter解析,路径扩展名解析。
目录
相关文章
|
20小时前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
20小时前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
1天前
|
算法 Java 程序员
Map - TreeSet & TreeMap 源码解析
Map - TreeSet & TreeMap 源码解析
7 0
|
1天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
11 0
|
5月前
|
XML Java uml
spring 源码解析——第一篇(ioc xml方式)
spring 源码解析——第一篇(ioc xml方式)
56 0
|
5月前
|
安全 Java 应用服务中间件
阿里技术官架构使用总结:Spring+MyBatis源码+Tomcat架构解析等
分享Java技术文以及学习经验也有一段时间了,实际上作为程序员,我们都清楚学习的重要性,毕竟时代在发展,互联网之下,稍有一些落后可能就会被淘汰掉,因此我们需要不断去审视自己,通过学习来让自己得到相应的提升。
|
5月前
|
Java 关系型数据库 数据库连接
Spring源码解析--深入Spring事务原理
本文将带领大家领略Spring事务的风采,Spring事务是我们在日常开发中经常会遇到的,也是各种大小面试中的高频题,希望通过本文,能让大家对Spring事务有个深入的了解,无论开发还是面试,都不会让Spring事务成为拦路虎。
77 1
|
12天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
50 9
|
1天前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
4 0
|
1天前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
3 0

推荐镜像

更多