添加ViewResolverRegistry后MappingJackson2JsonView Bean失效问题排查
嘿,这个问题我之前踩过坑!Spring MVC里多个视图解析器的优先级确实很容易搞混,尤其是加了Jackson这类处理JSON的配置之后,很容易和原来的JSP视图解析器“抢活儿”,导致返回结果不符合预期。
问题根源
Spring MVC在处理视图时,会按ViewResolver的优先级顺序去匹配解析器。如果没手动设置优先级,它会用默认的排序逻辑,这就可能出现本该返回JSON的请求被导向JSP,或者JSP页面被解析成JSON的混乱情况——你提到的XML配置里的priority属性,其实对应的就是Java配置里的排序(Order)机制,因为所有ViewResolver都实现了Ordered接口,通过设置order值就能控制优先级。
解决方案:给视图解析器设置优先级
数值越小,优先级越高。我们需要让负责JSON的解析器先“干活”,再轮到JSP解析器。下面给你两种常见场景的Java配置示例:
场景1:同时用JSON内容协商解析器和JSP解析器
假设你用ContentNegotiatingViewResolver来根据请求头选择返回JSON或视图,搭配InternalResourceViewResolver处理JSP:
// 负责JSON的内容协商解析器,优先级最高 @Bean public ContentNegotiatingViewResolver contentNegotiatingViewResolver() { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setOrder(0); // 0是最高优先级,先处理内容协商 // 配置默认支持的媒体类型,优先JSON List<MediaType> defaultMediaTypes = new ArrayList<>(); defaultMediaTypes.add(MediaType.APPLICATION_JSON); resolver.setDefaultMediaTypes(defaultMediaTypes); // 设置默认的JSON视图 List<View> defaultViews = new ArrayList<>(); defaultViews.add(new MappingJackson2JsonView()); resolver.setDefaultViews(defaultViews); return resolver; } // JSP视图解析器,优先级稍低 @Bean public InternalResourceViewResolver jspViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setOrder(1); // 比JSON解析器的order大,优先级低 return resolver; }
场景2:单独用MappingJackson2JsonView作为JSON解析器
如果不需要内容协商,只是部分请求返回JSON,也可以直接给JSON视图对应的解析器设置高优先级:
@Bean public ViewResolver jsonViewResolver() { BeanNameViewResolver resolver = new BeanNameViewResolver(); resolver.setOrder(0); // 高优先级 return resolver; } // 定义JSON视图 @Bean("jsonView") public MappingJackson2JsonView jsonView() { return new MappingJackson2JsonView(); } // JSP解析器 @Bean public InternalResourceViewResolver jspViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setOrder(1); return resolver; }
这时在Controller里返回"jsonView"就能触发JSON解析,返回普通视图名称则会走JSP解析器。
额外小贴士
- 配合
@RequestMapping的produces属性:比如@RequestMapping(value = "/api/data", produces = MediaType.APPLICATION_JSON_VALUE),能明确告诉Spring这个请求要返回JSON,进一步避免冲突。 - 如果用
@ResponseBody注解,其实不需要视图解析器,它会直接通过HttpMessageConverter处理JSON,这种情况可以检查下是不是配置了多余的视图解析器导致冲突。
内容的提问来源于stack exchange,提问作者J E Carter II
相关产品推荐
相关产品推荐

