配置自定义视图解析器
自定义视图解析器类
/*
Order接口的作用是在springmvc内部遍历时,使自定义视图解析器第一个解析。
*/
@Component
public class MyViewResolver implements ViewResolver, Ordered {
private int order=1;
public void setOrder(int order) {
this.order = order;
}
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (viewName.startsWith("keyi:")){
return new MyView();
}else{
return null;
}
}
@Override
public int getOrder() {
return order;
}
}
自定义视图类
public class MyView implements View {
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
if (model!=null){
Set<? extends Map.Entry<String, ?>> entries = model.entrySet();
for (Map.Entry<String, ?> s:entries){
String key = s.getKey();
Object value = s.getValue();
request.setAttribute(key,value);
}
}
request.getRequestDispatcher("/success.html").forward(request,response);
}
}
注册自定义视图解析器
@Component
public class MyConfig {
/*配置WebMvcConfigurer,定制化SpringMVC的功能*/
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
/*配置自定义视图解析器*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(new MyViewResolver());
}
};
}
}
目标方法
@GetMapping("/test2")
public String test2(){
/*
自定义视图解析器原理
*/
System.out.println("测试");
return "keyi:success";
}
流程
请求以http://localhost:8080/test2,get请求,目标返回"keyi:success"
底层遍历容器中所有的视图解析器,找到自定义视图解析器,根据返回值字符串,创建自定义的视图对象
调用视图对象的render方法渲染数据跳转视图。
视图解析器原理
SpringBoot和SpringMVC不同在于,它有一个内容协商的功能,
在SpringMVC中,你配置了自定义视图解析器,底层直接给你遍历,找到并使用自定义解析器来创建视图对象
但在SpringBoot中,它配置了一个ContentNegotiatingViewResoulver,在这个解析器的resolveViewName方法
中,再次遍历容器中其余的视图解析器,并且,在该方法中,最后是根据视图对象的getContentType()方法来匹配
合适的媒体类型进行解析,所以,如果你的自定义视图对象没有重写该方法,则你的视图对象并不能被返回,而是返回
thymeleafView或者InternalView,这样就会导致你的自定义视图解析没有效果,终于通过debug找出来了,舒服。