spring可以配置多个视图解析器,解析顺序根据viewResolver的order属性来控制
@Bean
public ThymeleafViewResolver thymeleafViewResolver(TemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine((ISpringTemplateEngine) templateEngine);
viewResolver.setCharacterEncoding(String.valueOf(StandardCharsets.UTF_8));
viewResolver.setViewNames(new String[]{"pages/*"});
viewResolver.setCache(false);
viewResolver.setOrder(3);
return viewResolver;
}
/**
* 内部资源视图解析器
* @return
*/
@Bean
public ViewResolver jspViewResolver(){
InternalResourceViewResolver resolver=new InternalResourceViewResolver();
//设置视图的前置路径
resolver.setPrefix("/WEB-INF/views/");
//设置视图名称
resolver.setViewNames("jsp/*");
//设置视图后缀 resolver.setSuffix(".jsp");
//视图缓存
resolver.setCache(false);
//视图解析顺序,越小越靠前
resolver.setOrder(2);
return resolver;
}
org.springframework.web.servlet.DispatcherServlet
/**
* Resolve the given view name into a View object (to be rendered).
* <p>The default implementations asks all ViewResolvers of this dispatcher.
* Can be overridden for custom resolution strategies, potentially based on
* specific model attributes or request parameters.
* @param viewName the name of the view to resolve
* @param model the model to be passed to the view
* @param locale the current locale
* @param request current HTTP servlet request
* @return the View object, or {@code null} if none found
* @throws Exception if the view cannot be resolved
* (typically in case of problems creating an actual View object)
* @see ViewResolver#resolveViewName
*/
@Nullable
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
Locale locale, HttpServletRequest request) throws Exception {
if (this.viewResolvers != null) {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}
遍历视图解析器,进入org\springframework\web\servlet\view\AbstractCachingViewResolver.java,如果有缓存,就取出缓存,没有就创建
@Override
@Nullable
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (!isCache()) {
return createView(viewName, locale);
}
else {
Object cacheKey = getCacheKey(viewName, locale);
View view = this.viewAccessCache.get(cacheKey);
if (view == null) {
synchronized (this.viewCreationCache) {
view = this.viewCreationCache.get(cacheKey);
if (view == null) {
// Ask the subclass to create the View object.
view = createView(viewName, locale);
if (view == null && this.cacheUnresolved) {
view = UNRESOLVED_VIEW;
}
if (view != null && this.cacheFilter.filter(view, viewName, locale)) {
this.viewAccessCache.put(cacheKey, view);
this.viewCreationCache.put(cacheKey, view);
}
}
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace(formatKey(cacheKey) + "served from cache");
}
}
return (view != UNRESOLVED_VIEW ? view : null);
}
}
以 org\thymeleaf\spring5\view\ThymeleafViewResolver.java视图解析类为例,
protected boolean canHandle(final String viewName, @SuppressWarnings("unused") final Locale locale) {
//要处理的视图名称
final String[] viewNamesToBeProcessed = getViewNames();
//例外
final String[] viewNamesNotToBeProcessed = getExcludedViewNames();
//判断当前视图解析器能不能处理
return ((viewNamesToBeProcessed == null || PatternMatchUtils.simpleMatch(viewNamesToBeProcessed, viewName)) && (viewNamesNotToBeProcessed == null || !PatternMatchUtils.simpleMatch(viewNamesNotToBeProcessed, viewName))); } @Override protected View createView(final String viewName, final Locale locale) throws Exception { // First possible call to check "viewNames": before processing redirects and forwards if (!this.alwaysProcessRedirectAndForward && !canHandle(viewName, locale)) { vrlogger.trace("[THYMELEAF] View \"{}\" cannot be handled by ThymeleafViewResolver. Passing on to the next resolver in the chain.", viewName); return null; } // Process redirects (HTTP redirects) 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, viewName); } // Process forwards (to JSP resources) if (viewName.startsWith(FORWARD_URL_PREFIX)) { // The "forward:" prefix will actually create a Servlet/JSP view, and that's precisely its aim per the Spring // documentation. See http://docs.spring.io/spring-framework/docs/4.2.4.RELEASE/spring-framework-reference/html/mvc.html#mvc-redirecting-forward-prefix vrlogger.trace("[THYMELEAF] View \"{}\" is a forward, and will not be handled directly by ThymeleafViewResolver.", viewName); final String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length(), viewName.length()); return new InternalResourceView(forwardUrl); } // Second possible call to check "viewNames": after processing redirects and forwards if (this.alwaysProcessRedirectAndForward && !canHandle(viewName, locale)) { vrlogger.trace("[THYMELEAF] View \"{}\" cannot be handled by ThymeleafViewResolver. Passing on to the next resolver in the chain.", viewName); return null; } vrlogger.trace("[THYMELEAF] View {} will be handled by ThymeleafViewResolver and a " + "{} instance will be created for it", viewName, getViewClass().getSimpleName()); return loadView(viewName, locale); }
温馨提示! 以下是付费内容 你可以随意修改付费可见的字段或内容,这里仅测试标题:springmvc 模板查找 请直接修改模板中需要显示的付费字段
发表评论 取消回复