说明一点:虽然这里有些视图解析器是new出来的,但不用担心最后都会执行InitializingBean、ApplicationContextAware...等等的一些接口方法的。因为这些都是交给ViewResolverComposite统一代劳的~(因此并不需要放进Spring容器里亦可,减少容器的负担也是一种优化)
上面"复习"的时候提到了,Spring MVC准备好ViewResolverRegistry后会回调我们,因此实际使用中可以通过此入口进行配置(最佳实践):
@Configuration @EnableWebMvc public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.enableContentNegotiation(); // 开启内容协商视图解析器 } }在我准备介绍案例时,==为了便于对小伙伴对整个内容协商流程的把控和理解==,我提供如下这张执行原理流程图作为辅助理解(若图有错误可留言指出,多谢):
--- 使用示例是骡子是马,总归还是要拉出来溜溜。下面我用一个工作中非常具象的案例,来演示一下它的用法。
需求:同一个RESTful的URL,我希望得到一个PDF视图、JSON视图、Html视图???
实现代码因为是同一个URL,并且还要求是有不同视图的,因此这里用ContentNegotiatingViewResolver来做内容协商就非常得心应手了。
1、准备针对于处理这三种视图的ViewResolver实现类:
// 自定义三个视图分别用于处理对应的视图需求 private final ViewResolver pdf_viewresolver= (viewName, locale) -> new View() { @Override public String getContentType() { return MediaType.APPLICATION_PDF_VALUE; } @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { response.getWriter().write("<html><body>this is pdf view</body></html>"); } }; private final ViewResolver excel_viewresolver= (viewName, locale) -> new View() { @Override public String getContentType() { return MediaType.APPLICATION_JSON_UTF8_VALUE; } @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { response.getWriter().write("<html><body>this is json view</body></html>"); } }; private final ViewResolver html_viewresolver= (viewName, locale) -> new View() { @Override public String getContentType() { return MediaType.TEXT_HTML_VALUE; } @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { response.getWriter().write("<html><body>this is html view</body></html>"); } };请注意:三者的getContentType()、渲染内容、颜色都是不一样的
说明:因为此处我只是模拟,所以我全部以匿名类来实现,各位小伙伴理解起来理论上应该都没有啥障碍吧(有问题可给我留言~)
2、开启Spring MVC在视图上对ContentNegotiation内容协商的支持:
@Configuration @EnableWebMvc public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.viewResolver(pdf_viewresolver); registry.viewResolver(excel_viewresolver); registry.viewResolver(html_viewresolver); // 上面三个注册方法必须在此方法之上执行 registry.enableContentNegotiation(false); } }