我们已经知道 对于 RequestMappingInfoHandlerMapping, 它在对带有后缀的http 请求进行匹配的时候,如果找不到精确的pattern, 那么就会 pattern+.* 后再匹配 url。  它会处理多个不同形式是 url, 但是返回的只是一个view。

ContentNegotiatingViewResolver 貌似也有这样的功能,但实际上是大不一样的。ContentNegotiatingViewResolver 有些难懂, 开始的时候, 我也是一直没有搞懂,反而搞晕了, 非常郁闷和尴尬。 它有些复杂,但也还好。

现在考虑这么一个情况,只配置一个@RequestMapping, 匹配多个 url, 这些url 可能有三个方面的不同:

1 其他都相同,只是后缀不同。 比如 /aa.jsp /aa.pdf  /aa.xml  /aa.json /aa (无后缀)

2 其他都相同,只是format参数不同。 比如 /aa?view=jsp /aa?view=pdf  /aa?view=xml  /aa?view=json  /aa(无view 参数)

3 其他都相同,只是accept-type不同。 比如 /aa HTTP Request Header中的Accept 分别是 text/jsp,  text/pdf,  text/xml,  text/json,  无Accept 请求头

如果是RequestMappingInfoHandlerMapping, 那么无法一个@RequestMapping满足这样的要求, 它需要多个@RequestMapping。

 ContentNegotiatingViewResolver 可以一个@RequestMapping,返回多个view。

我的配置如下:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorParameter" value="true"/>
<property name="favorPathExtension" value="true"/>
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml"/> //
<entry key="json" value="application/json"/> // 这里, 对于 json ,必须是application/json
<!--<entry key="json" value="text/plain"/>-->
<entry key="xls" value="application/vnd.ms-excel"/>
</map>
</property>
<property name="viewResolvers">
<list>
<ref bean="jaxb2MarshallingXmlViewResolver"></ref>
<ref bean="jsonViewResolver"></ref>
<ref bean="excelViewResolver"></ref>
</list>
</property>
</bean>

上面的 viewResolvers 属性是可以不用配置的, 默认spring 会查找所有 ViewResolver类型的对象。这样, 就同时支持了 parameter参数方式和 后缀拓展名方式。

这里我直接使用了ContentNegotiatingViewResolver, 实际spring 给我们提供了 ContentNegotiationManagerFactoryBean这是推荐的方式。 配置上类似。

默认是支持path 后缀拓展方式, 也支持accept 请求头,但不支持 format 参数的。 因此如果我们想使用 进行参数方式匹配, 那么我们需要把favorParameter 设置为true, 另外此时mediaTypes 也是必须正确配置的。 我感觉有些不合理。 应该是默认支持的, 现在却要我手动配置, 不过,我测试就是这样的结果。

源码是:

private boolean favorPathExtension = true; // 支持

private boolean favorParameter = false; // 默认不支持

private boolean ignoreAcceptHeader = false; // 默认支持accept头 

private Map<String, MediaType> mediaTypes = new HashMap<String, MediaType>();

private boolean ignoreUnknownPathExtensions = true;

private Boolean useJaf;

private String parameterName = "format";

除了xml 方式配置, 我们可以使用注解方式配置:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.yiibai.springmvc")
public class AppConfig extends WebMvcConfigurerAdapter { /*
* Configure ContentNegotiationManager
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true).defaultContentType(
MediaType.TEXT_HTML);
} /*
* Configure ContentNegotiatingViewResolver
*/
@Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager); // Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<ViewResolver>(); resolvers.add(jaxb2MarshallingXmlViewResolver());
resolvers.add(jsonViewResolver());
resolvers.add(jspViewResolver());
resolvers.add(pdfViewResolver());
resolvers.add(excelViewResolver()); resolver.setViewResolvers(resolvers);
return resolver;
} /*
* Configure View resolver to provide XML output Uses JAXB2 marshaller to
* marshall/unmarshall POJO's (with JAXB annotations) to XML
*/
@Bean
public ViewResolver jaxb2MarshallingXmlViewResolver() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(Pizza.class);
return new Jaxb2MarshallingXmlViewResolver(marshaller);
} /*
* Configure View resolver to provide JSON output using JACKSON library to
* convert object in JSON format.
*/
@Bean
public ViewResolver jsonViewResolver() {
return new JsonViewResolver();
} /*
* Configure View resolver to provide PDF output using lowagie pdf library to
* generate PDF output for an object content
*/
@Bean
public ViewResolver pdfViewResolver() {
return new PdfViewResolver();
} /*
* Configure View resolver to provide XLS output using Apache POI library to
* generate XLS output for an object content
*/
@Bean
public ViewResolver excelViewResolver() {
return new ExcelViewResolver();
} /*
* Configure View resolver to provide HTML output This is the default format
* in absence of any type suffix.
*/
@Bean
public ViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
} }

对于boot, 其自动配置了一个

        @Bean
@ConditionalOnBean({ViewResolver.class})
@ConditionalOnMissingBean(
name = {"viewResolver"},
value = {ContentNegotiatingViewResolver.class}
)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
resolver.setOrder(-2147483648);
return resolver;
} @Bean
public ContentNegotiationManager mvcContentNegotiationManager() {
ContentNegotiationManager manager = super.mvcContentNegotiationManager();
List<ContentNegotiationStrategy> strategies = manager.getStrategies();
ListIterator iterator = strategies.listIterator(); while(iterator.hasNext()) {
ContentNegotiationStrategy strategy = (ContentNegotiationStrategy)iterator.next();
if (strategy instanceof PathExtensionContentNegotiationStrategy) { // 只支持后缀 方式匹配
iterator.set(new WebMvcAutoConfiguration.OptionalPathExtensionContentNegotiationStrategy(strategy));
}
} return manager;
}

但是, 它只支持 后缀方式匹配。

参考

http://blog.csdn.net/fw0124/article/details/48315523

http://blog.csdn.net/fw0124/article/details/48315523

http://blog.csdn.net/z69183787/article/details/41696709

Spring MVC 之 ContentNegotiatingViewResolver的更多相关文章

  1. Spring学习笔记之五----Spring MVC

    Spring MVC通常的执行流程是:当一个Web请求被发送给Spring MVC Application,Dispatcher Servlet接收到这个请求,通过HandlerMapping找到Co ...

  2. Spring MVC视图解析器

    Spring MVC提供的视图解析器使用ViewResolver进行视图解析,实现浏览器中渲染模型.ViewResolver能够解析JSP.Velocity模板.FreeMarker模板和XSLT等多 ...

  3. Spring MVC 学习总结(四)——视图与综合示例

    一.表单标签库 1.1.简介 从Spring2.0起就提供了一组全面的自动数据绑定标签来处理表单元素.生成的标签兼容HTML 4.01与XHTML 1.0.表单标签库中包含了可以用在JSP页面中渲染H ...

  4. spring笔记3 spring MVC的基础知识3

    4,spring MVC的视图 Controller得到模型数据之后,通过视图解析器生成视图,渲染发送给用户,用户就看到了结果. 视图:view接口,来个源码查看:它由视图解析器实例化,是无状态的,所 ...

  5. 【Spring】搭建最简单的Spring MVC项目

    每次需要Spring MVC的web项目测试一些东西时,都苦于手头上没有最简单的Spring MVC的web项目,现写一个. > 版本说明 首先要引入一些包,Spring的IOC.MVC包就不用 ...

  6. 四、Spring——Spring MVC

    Spring MVC 1.Spring MVC概述 Spring MVC框架围绕DispatcherServlet这个核心展开,DispatcherServlet负责截获请求并将其分配给响应的处理器处 ...

  7. Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

    内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...

  8. 【Spring学习笔记-MVC-18.1】Spring MVC实现RESTful风格-同一资源,多种展现:xml-json-html

    概要 要实现Restful风格,主要有两个方面要讲解,如下: 1. 同一个资源,如果需要返回不同的形式,如:json.xml等: 不推荐的做法: /user/getUserJson /user/get ...

  9. spring mvc中的json整合

    spring mvc整合过程中是有版本兼容的问题.具体的哪个版本的springmvc和哪个个版本的json包冲突我也无从考证了.我用的springmvc版本是3.2.1jaskson的版本是 1.1. ...

随机推荐

  1. 结构体变量的 extern 使用方法,转--

    要求如下,在.h文件中这样定义: typedef struct typFNT_GB16     // 汉字字模数据结构 {     signed ];        // 汉字内码索引     ]; ...

  2. 带通滤波 matlab

    巴特沃斯:1.带阻滤波器设计带阻滤波器指标:阻带上边界频率:5Kz:阻带下边界频率:7Kz:通带上边界频率:2Kz:通带下边界频率:9Kz:通带最大衰减:1dB:阻带最小衰减:20dB:设计程序如下: ...

  3. 学习python的字符串的方法

    今天看了下学习视频,发现str也有许多方法,才发现昨天了解的关于字符串知识甚少,所以今天查看了python的源码,学习一些新的方法 以下是我把边对照着源码边翻译,边尝试实现方法 1.第一个字符有大写字 ...

  4. 5.移动终端App测试点归纳

    以下所有测试最后必须在真机上完整的执行. 1 安装.卸载测试 1.1 在真机上.第三方软件(xy苹果助手.91.安卓助手)的安装与卸载 1.2 安装在手机卡上 或 SD卡上 (不同的IOS和安卓版本) ...

  5. WKWebView 加载本地HTML随笔

    一天的时间 解决两个坑~~ 1.加载不出来本地HTML 的JS  CSS 样式,问题是引用到项目中 是用的group 这个是错的 直接上图 就知道了 像上图一样,加入相对路径即可,因为如果使用了gro ...

  6. mysql locking

    1. 意向锁 https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-insert-intention-locks 官方文 ...

  7. mybatis(一、原理,一对多,多对一查询)

    MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...

  8. JAVA高级篇(二、JVM内存模型、内存管理之第二篇)

    本文转自https://zhuanlan.zhihu.com/p/25713880. JVM的基础概念 JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机. JVM也充 ...

  9. 转 C#实现PID控制的模拟测试和曲线绘图

    C#实现PID控制的模拟测试和曲线绘图   本文分两部分,一部分是讲PID算法的实现,另一部分是讲如何用动态的曲线绘制出PID运算的结果. 首先,PID算法的理论模型请参考自动控制理论,最早出现的是模 ...

  10. vs2017 打开cs文件提示无法识别的GUID格式

    总结一句话 no zuo no die. 是我自己在注册表中给vs增加了自动以管理员身份运行,把值给错了,弄成了 ~ RUNASADMIN WIN7RTM, 改成 ~ RUNASADMIN 后OK.还 ...