본문 바로가기

Java/SpringBoot

template might not exist or might not be accessible by any of the configured Template Resolvers

문제발생상황

회원가입버튼을 누르면 500에러가 발생. 로그를 확인해보니 Error resolving template “/fragments/footer”, template might not exist or might not be accessible by any of the configured Template Resolvers (template: “layout/layout” - line 38, col 21) 이란 메시지가 확인 되었다. 로컬에서는 돌릴때는 아무 이상이 없었는데 aws에 jar배포후에 문재가 발생한 상황이었다.
해당 라인으로 가보니, 아래와 같이 되어 있었다.

<footer th:replace = "/fragment/footer :: footer">
 ...
</footer>

StackOverflow에서 문제를 찾아보니/를 빼라는 글이 있었다. 그래서 아래와 같이 돌린후 재배포 하니 문제상황이 해결되었지만 왜그런지 궁금했다. 예상되는 상황은 defalut 값의 끝에 '/'가 있을 꺼라는 생각뿐이었다.

<footer th:replace = "fragment/footer :: footer">
 ...
</footer>

문제발생이유

문제 상황을 이해하기 위해 일단 레퍼런스를 찾아보았다. 아래는 SpringBoot 2.0.4 레퍼런스의 내용이다.

When you use one of these templating engines with the default configuration, your templates are picked up automatically from src/main/resources/templates.

Depending on how you run your application, IntelliJ IDEA orders the [classpath] differently. Running your application in the IDE from its main method results in a different ordering than when you run your application by using Maven or Gradle or from its packaged jar. This can cause Spring Boot to fail to find the templates on the classpath. If you have this problem, you can reorder the [classpath] in the IDE to place the module’s classes and resources first.

The resulting jar contains the classes produced by compiling the application and all of the application’s dependencies so that it can then be run by using java -jar. The jar file also contains entries from the application’s classpath. You can add and remove explicit paths to the jar by using --include and --exclude. Both are comma-separated, and both accept prefixes, in the form of “+” and “-”, to signify that they should be removed from the defaults. The default includes are as follows:

public/, resources/, static/, templates/, META-INF/**, *

- SpringBoot 2.0.4 Reference -

결론은 jar 파일에 Classpath의 default값이 위와 같다. jar파일을 열어보면 templates/아래에src/main/re sources/templates 의 내용이 위치하게 된다. 따라서 아래와 같이 Classpath를 변경해주지 않는이상 기본 클래스 패스는 templates/가 된다.

spring.thymeleaf.prefix=classpath:/templates

문제의 결론

그래서 내 코드에서 view에 대한 path를 /fragment/footer라고 했었기 때문에 //fragment/footer가 되어 path해석이 불가능 했던것 같다. 그러면 왜 Intellij에서는 실행이 되었던 것일까? 그것에 대한 대답은 아래에 있다.

When you’re running in your IDE the resource is available straight off the filesystem and the double slash doesn’t cause a problem. When you’re running from a jar file the resource is nested within that jar and the double slash prevents it from being found.

//에대한 처리는 IDE에서는 처리를 해 주고, jar 배포시에는 처리를 못한다. 이것에 대해 몇가지 테스트를 더 해보았다. 우선 코드를 다시 아래와 같이 고첬다.

<footer th:replace = "/fragment/footer :: footer">
 ...
</footer>

그리고 .yml파일에서 classpath를 다음과 같이 변경해 주었다.

spring.thymeleaf.prefix=classpath:/templates

그리고 다시 jar 파일을 배포하고 회원가입버튼을 누르니 정상동작이 확인 되었다. 따라서 default가 /templates/라는 것이 확인 되었다. 그리고 IDE가 //을 처리 해 주는지 확인해 보기 위하여 로그인 veiw에 대한 path를 다음과 같이 변경후 Junit 테스트를 진행 하였다. 원래 path는 users/login이다.

 @GetMapping("/login")
 public String displayLoginPage(){
	 return "users//login";
 }

image
View name에 //가 포함되어 있고, 서버 Status는 200으로 확인되어 정상적으로 로그인 처리를 하는 것을 확인 할 수 있었다.
tempsnip

'Java > SpringBoot' 카테고리의 다른 글

리다이렉션 횟수가 너무 많습니다.  (0) 2018.09.26
리멤버미 권한 오류  (0) 2018.09.02