Spring-web源码解析之ContentNegotiationStrategy
来源:互联网 发布:备案网站域名查询 编辑:程序博客网 时间:2024/05/05 14:59
基于4.1.7.RELEASE
request和mediatypes解析的策略类,其唯一的一个接口是
List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException;
该接口负责将给与的request解析出对应的MediaType来,其实现有以下几种
- FixedContentNegotiationStrategy
固定类型解析 : 返回固定的MediaType,每个类都有一个defaultContentType,在构造函数时需要传入默认的MediaType类型,其接口实现方式如下@Overridepublic List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) { return Collections.singletonList(this.defaultContentType);}
- HeaderContentNegotiationStrategy
accept Header解析 : 负责解析request头中的accept,接口实现如下@Overridepublic 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。 - ParameterContentNegotiationStrategy
parameter解析 : 根据request中的参数来判断mediaType的类型,默认的参数名为format,在其构造函数中需要传递一个mediaType的Map,在解析format时,format对应的值就会在这个map里寻找匹配MediaType。其参数名可以使用setParameterName方法注入修改。
举例: http://xxx.alibaba-inc.com/xx?format=json 时,会根据format的值json,去寻找json对应的MediaType类型。@Overrideprotected String getMediaTypeKey(NativeWebRequest webRequest) { return webRequest.getParameter(this.parameterName);}
根据MediaTypeKey去寻找MediaType。 - PathExtensionContentNegotiationStrategy
路径名解析 : 根据请求路径的后缀名来判断用哪种MediaType,默认忽略未知的路径扩展名,比如说我们常见的 xx.html,xx.json ,里的.html,.json都是已知的路径扩展名,对于程序来说,只要没有匹配上就属于未知的扩展名。
在寻找路径名匹配的过程中,如果在构造函数中的Map中没有找到MediaType,会采用JAF作为备用机制来查询MediaType。@Overrideprotected 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。 - ServletPathExtensionContentNegotiationStrategy
属于4的扩展,作为4的一种备用机制使用ServletContext.getMIMEType来匹配MediaType,备用机制的实现是在handlerNoMatch方法里,如果是application/octet-stream类型(比如上传文件),则不采用该备用机制。
总结:4种策略 固定类型,accept Header解析,parameter解析,路径扩展名解析。
0 0
- Spring-web源码解析之ContentNegotiationStrategy
- SpringMVC源码解析-ContentNegotiationStrategy
- Spring-web源码解析之ContextLoaderListener
- Spring-web源码解析之ContextLoader
- Spring-web源码解析之Initializer
- Spring-web源码解析之Initializer2-SpringServletContainerInitializer
- Spring-web源码解析之HttpRequestHandler
- Spring-web源码解析之MediaTypeFileExtensionResolver
- spring-web源码解析之ContentNegotiationManager
- spring-web源码解析之MappingMediaTypeFileExtensionResolver
- spring-web源码解析之AbstractMappingContentNegotiationStrategy
- Spring-web源码解析之Filter-CharacterEncodingFilter
- Spring-web源码解析之Filter-OncePerRequestFilter:
- Spring-web源码解析之Filter-AbstractRequestLoggingFilter
- Spring-web源码解析之Filter-HiddenHttpMethodFilter
- Spring-web源码解析之Filter-OncePerRequestFilter:
- Spring-web源码解析之Filter-OncePerRequestFilter
- Spring源码解析之初始化
- 算法训练 安慰奶牛
- hdu-1558-Segment set(计算几何&并查集)
- DataShuo大数据时代转挑战为商机
- Visual C++在虚继承中使用协变报错
- Android中的页面切换动画
- Spring-web源码解析之ContentNegotiationStrategy
- Windows7下 IIS(FastCGI)+ MySQL+ PHP + PHPmyadmin + Zend Optimizer 环境配置
- eclipse 创建 javaWeb 项目 如何 配置 tomcat
- 《剑指offer》——二叉树的深度
- 为打开新Activity动作添加动画效果
- c++
- 克制
- 《转》Vmware vSphere常见问题汇总
- 1428 - Ping pong