解决Error resolving template [x] template might not exist or might not be accessible by any of the con

导读:本篇文章讲解 解决Error resolving template [x] template might not exist or might not be accessible by any of the con,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1. 复现问题

今天配置好shiro + jwt后,可以正常启动spring boot,但调用auth/login登录方法时,却报出如下错误:

2022-08-21 12:35:18.205 [ http-nio-8081-exec-1 ] - [ ERROR ] [ org.thymeleaf.TemplateEngine : 1136 ] - [THYMELEAF][http-nio-8081-exec-1] Exception processing template "auth/login": Error resolving template [auth/login], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [auth/login], template might not exist or might not be accessible by any of the configured Template Resolvers
	at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)
	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
	at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366)
	at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1396)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1141)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:114)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:112)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:450)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:204)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

这么多错误信息,我们只要关注这句话:Error resolving template [auth/login], template might not exist or might not be accessible by any of the configured Template Resolvers,这句话是什么意思呢?

即解析模板 [auth/login] 时出错,模板可能不存在或任何已配置的模板解析程序都无法访问。

为什么会出现这个错误,让我一步一步往下分析。

2. 分析问题

2.1 检查pom依赖

  • 我在.pom文件中配置了如下依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

这个依赖是配置thymeleaf模板引擎,我们可以使用它设计发送的模板邮件等。

上述错误信息即是这个依赖发出的,我们不妨看看thymeleaf模板引擎是什么?

2.2 详解thymeleaf引擎

  • thymeleaf模板引擎
  1. thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎。
  2. thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板 -HTML可以在浏览器中正确显示,也可以作为静态原型工作,从而可以在开发团队中加强协作。
  3. thymeleaf拥有适用于Spring Framework的模块,与您喜欢的工具的大量集成以及插入您自己的功能的能力,对于现代HTML5 JVM Web开发而言,thymeleaf是理想的选择-尽管它还有很多工作要做。
  • thymeleaf有如下特点:
  1. thymeleaf在有网络无网络的环境下都可以运行,所以可以直接在浏览器打开查看静态页面效果。它支持HTML原型,可以在HTML标签里面添加其他属性来实现数据渲染。
  2. thymeleaf具有开箱即用的特性,thymeleaf是Spring boot推荐使用的模版引擎,直接以html显示,前后端可以很好的分离。
  • 它在spring boot有如下引用:
  1. 国际化 :渲染不同国家的语言
  2. 共同页面显示:比如统一异常页面处理,共同的页面处理

2.2 检查yml配置

我发现在application.yml中并没有thymeleaf的配置信息,问题可能出现在这里,于是在application.yml中进行如下配置:

spring:
  thymeleaf:
    cache: false 
    prefix: classpath:/templates 
    encoding: UTF-8 #编码
    suffix: .html # 模板后缀
    mode: HTML #模板

配置说明:

  1. cache这一行是将页面的缓存关闭,不然我们改变页面之后可能不能及时看到更改的内容,默认是true。
  2. prefix是配置thymeleaf模板所在的位置。
  3. encoding是配置thymeleaf文档的编码。

在很多情况下,引入thymeleaf依赖,就要在yml文件中的配置上述信息,即可解决问题。如果这种无法解决你的问题,可以继续往下看我的分析

但我在application.yml文件中配置了如上信息并成功启动spring boot后,调用/auth/login方法, 依然报出上述的错误,那么,问题出现在哪里呢?

3. 解决问题

经过反复断点调试,才发现问题在哪里,原来是在我的统一异常处理,我的源代码是这样写的:

/**
 * @author baoya
 * @datetime 2022/8/10 21:50
 * @desc 全局异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = AuthenticationException.class)
    public ReturnResult incorrectCredentialsException(HttpServletRequest request, AuthenticationException e) {
        log.error("用户名或密码不正确: {}, 请求接口: {}", e, request.getRequestURI());
        return ReturnResult.error(USER_CREDENTIALS_ERROR);
    }
}

使用ResponseEntity<T>作为统一异常的返回值,即可解决上述问题,如下代码:

/**
 * @author baoya
 * @datetime 2022/8/10 21:50
 * @desc 全局异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = AuthenticationException.class)
    public ResponseEntity<ReturnResult> incorrectCredentialsException(HttpServletRequest request, AuthenticationException e) {
        log.error("用户名或密码不正确: {}, 请求接口: {}", e, request.getRequestURI());
        return buildResponseEntity(ReturnResult.error(USER_CREDENTIALS_ERROR));
    }

    /**
     * 统一返回
     */
    private ResponseEntity<ReturnResult> buildResponseEntity(ReturnResult apiError) {
        return new ResponseEntity<>(apiError, HttpStatus.valueOf(HttpStatus.BAD_REQUEST.value()));
    }
}

重新启动 spring boot并调用/auth/login方法,使用postman测试,如下图所示:

在这里插入图片描述

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99162.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!