//跳转至login.html页面
@GetMapping("/login")
public String goToLogin(){
return "login"
}
Thymeleaf是如何将String字符串"login"
解析成"classpath:/templates/login.html"
的?
一、前端控制器DispatcherServlet
前端控制器中的doDispacth
在处理请求时,渲染页面过程:
先通过
//DispatcherServlet.class 1043行
mappedhandler = getHandler(processedrequest)
查找url是否存在,若存在则返回执行链和适配器,在
//DispatcherServlet.class 1067行
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
真正执行Handler
然后在
//DispatcherServlet.class 1084行
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
渲染视图,而Thymeleaf提供了视图解析器,所以在这里渲染视图的是Thymeleaf的视图解析器。
二、ThymeleafAutoConfiguration
在ThymeleafAutoConfiguration
中,SpringBoot2 就已经为我们默认注册了一个thymeleafViewResolver
@Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
ThymeleafViewResolver thymeleafViewResolver(ThymeleafProperties properties,
SpringTemplateEngine templateEngine) {
......
return resolver;
}
只要没有手动自己添加,则会默认使用该视图解析器。
在ThymeleafViewResolver
中的createView
创建视图方法,会传入一个视图名称,如下代码所示的viewName
@Override
protected View createView(final String viewName, final Locale locale) throws Exception {
......
}
然后通过viewName.startWith()
方法截取
// Process redirects (HTTP redirects)
//此处的REDIRECT_URL_PREFIX的值为:
//public static final String REDIRECT_URL_PREFIX = "redirect:";
if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
vrlogger.trace("[THYMELEAF] View \"{}\" is a redirect, and will not be handled directly by ThymeleafViewResolver.", viewName);
final String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length(), viewName.length());
final RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
return (View) getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, REDIRECT_URL_PREFIX);
}
然后通过RedirectView
构建视图返回。forward
前缀同理。
如果前缀不符合上述两种,则执行
return loadView(viewName, locale);
@Override
protected View loadView(final String viewName, final Locale locale) throws Exception {
......
}
利用loadView
最终实例化
view = (AbstractThymeleafView) beanFactory.initializeBean(viewInstance, viewName);
通过AbstractThymeleafView
将例如"login"拼接完成。