spring boot 使用thymleaf时,出现: org.thymeleaf.exceptions.TemplateInputException: Error resolving template [xxxxx], template might not exist or might not be accessible by any of the configured Template Resolvers
说明配置或返回视图不正确。源码中视图解析之后找资源文件的目录: org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver#computeResourceName(org.thymeleaf.IEngineConfiguration, java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean, java.util.Map<java.lang.String,java.lang.String>, java.util.Map<java.lang.String,java.lang.Object>) 查看此方法,即可知道根本原因了。
/**
* <p>
* Computes the resource name that will be used for resolving, from the template name and other
* parameters configured at this <em>configurable</em> resolver.
* </p>
* <p>
* This method can be overridden by subclasses that need to modify the standard way in which the
* name of the template resource is computed by default before passing it to the real resource
* resolution mechanism (in method {@link #computeTemplateResource(IEngineConfiguration, String, String, String, String, Map)}
* </p>
* <p>
* By default, the resource name will be created by first applying the <em>template aliases</em>, and then
* adding <em>prefix</em> and <em>suffix</em> to the specified <em>template</em> (template name).
* </p>
*
* @param configuration the engine configuration in use.
* @param ownerTemplate the owner template, if the resource being computed is a fragment. Might be null.
* @param template the template (normally the template name, except for String templates).
* @param prefix the prefix to be applied.
* @param suffix the suffix to be applied.
* @param forceSuffix whether the suffix should be forced or not.
* @param templateAliases the template aliases map.
* @param templateResolutionAttributes the template resolution attributes, if any. Might be null.
* @return the resource name that should be used for resolving
* @since 3.0.6
*/
protected String computeResourceName(
final IEngineConfiguration configuration, final String ownerTemplate, final String template,
final String prefix, final String suffix, final boolean forceSuffix,
final Map<String, String> templateAliases, final Map<String, Object> templateResolutionAttributes) {
Validate.notNull(template, "Template name cannot be null");
String unaliasedName = templateAliases.get(template);
if (unaliasedName == null) {
unaliasedName = template;
}
final boolean hasPrefix = !StringUtils.isEmptyOrWhitespace(prefix);
final boolean hasSuffix = !StringUtils.isEmptyOrWhitespace(suffix);
final boolean shouldApplySuffix =
hasSuffix && (forceSuffix || !ContentTypeUtils.hasRecognizedFileExtension(unaliasedName));
if (!hasPrefix && !shouldApplySuffix){
return unaliasedName;
}
if (!hasPrefix) { // shouldApplySuffix
return unaliasedName + suffix;
}
if (!shouldApplySuffix) { // hasPrefix
return prefix + unaliasedName;
}
// hasPrefix && shouldApplySuffix
return prefix + unaliasedName + suffix;
}
资源文件最终为位置: prefix + unaliasedName + suffix
默认 spring boot thymleaf 默认前缀(prefix)为: spring.thymeleaf.prefix=classpath:/templates/
后缀(suffix)为: spring.thymeleaf.suffix=.html
比如登录: 返回视图为 login
, 则最终会查找资源位置: classpath:/templates/login.html
没问题,如果返回视图为: /login
, 则最终会查找资源位置: classpath:/templates//login.html
就会报找不到资源会无法解析了。