最近在做一个springboot的小项目,需要对SpringMVC进行扩展配置,首先在Controller里面进行了测试,发现怎么都是对的,这里设置端口号为8088,通过 lohost:8088:/ 或者 local:8088/index.html 或者 localhost:8088/a 都是可以正常访问到首页的。
@Controller
public class HelloController {
@RequestMapping({"/","/index.html","a"})
public String index(){
return "index";
}
}
验证了controller代码没问题后,开始写一个springmvc的配置进行扩展,对WebMvcConfigurer接口中的addViewControllers方法进行重写,以实现扩展。正常情况下,我们扩展的MVC会与官方提供的视图解析器一起共同组合使用,这个可以通过源码进行查看。
@Nullable // 注解说明:@Nullable 即参数可为null
public View resolveViewName(String viewName, Locale locale) throws Exception {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());
if (requestedMediaTypes != null) {
// 获取候选的视图对象
List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
// 选择一个最适合的视图对象,然后把这个对象返回
View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
if (bestView != null) {
return bestView;
}
}
// .....
}
我们继续点进去看,他是怎么获得候选的视图的呢?
getCandidateViews中看到他是把所有的视图解析器拿来,进行while循环,挨个解析!
Iterator var5 = this.viewResolvers.iterator();
所以得出结论:ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的
怎么看我们自己写的视图解析器有没有起作用呢?
我们给 DispatcherServlet 中的 doDispatch方法 加个断点进行调试一下,因为所有的请求都会走到这个方法中
找到视图解析器,我们看到我们自己定义的就在这里了;
所以说,我们如果想要使用自己定制化的东西,我们只需要给容器中添加这个组件就好了!剩下的事情SpringBoot就会帮我们做了!
我们要做的就是编写一个@Configuration注解类,并且类型要为WebMvcConfigurer,还不能标注@EnableWebMvc注解;我们去自己写一个;我们新建一个包叫config,写一个类MyMvcConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
/**
* 添加视图控制器
*
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
System.out.println("come in ");
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
此时访问localhost:8088没有问题,但是访问localhost:8088/index.html就一直有问题,出现如下错误。
然后通过不断的调试,最终发现问题在于,config居然放错位置了,放到了工程外面,其实是应该放到工程里面才对,也就是demo下面,和controller目录同级才对,花了我很久很久的时间才找出来这个错误,哎,太难受了。
总结下对于排查这类错误的技巧:
- 首先查看是否导入thymeleaf模板引擎
- thymeleaf的模板引擎的版本号是否与springboot版本号对应,有时候不对应也会造成冲突
- 看下configuration配置文件的路径放错没有(重点!!!)
参考资料:
狂神说:https://mp.weixin.qq.com/s/9AY48uLjR9bI9TUlulcBNA