//跳转至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"拼接完成。
