首页 技术 正文
技术 2022年11月15日
0 收藏 935 点赞 2,362 浏览 5292 个字

我们已经知道 对于 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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,078
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,553
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,402
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,177
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,814
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,898