Spring Boot HTML 파일 templates에서도 읽도록 설정하기

ds_chanin

·

2020. 5. 18. 20:45


static 아닌 폴더에서 정적 정보 읽어오기

스프링 부트에 web 의존성을 추가하고 localhost:8080으로 접근하면
기본적으로 resources 폴더에 있는 static 에 위치한 index.html 파일을 읽게됩니다.

프로젝트를 생성하고 다음과 같이 index.html을 생성하여 static 에 위치시키고

image

애플리케이션을 실행후 localhost:8080으로 접근하면 다음과 같이 index 페이지가 출력되는것을 확인할 수 있습니다.

image

static 에서 접근하는 것은 문제가 없습니다.
그러나 html 파일들은 static이 아닌 resources 밑에 templates 폴더에서 관리를 하고 싶어진다면 문제가 발생합니다.

아래와 같이 home.htmlresourcestemplates에 위치시키고

image

간단한 컨트롤러를 통해 접근을 시도해 보겠습니다.

image

결과는 실패합니다. 404 not found가 발생합니다.

image

해결하기

먼저 이를 해결하는 방법은 다음과 같습니다.

스프링 부트에서 제공하는 WebMvc 설정을 유지하며 기능을 확장하기 위해
WebMvcConfigurerimplements하도록 합니다.

그리고 addResourceHandlers를 오버라이드하여 다음과 같이 작성합니다.

image

  1. / 를 시작으로 하는 모든 요청을 다룬다는 것을 의미합니다.
  2. 1번에 해당하는 요청을 처리할 자원을 찾을 위치를 나타냅니다.
  3. 요청에 대한 Cache를 10분으로 설정한 것입니다. 이 부분은 신경쓰지 않으셔도 좋습니다.

설정을 마치고 다시 localhost:8080/home으로 접근해 보겠습니다.

image

정상적으로 접근이 되는군요!

그러나 다시 localhost:8080 로 접근하여 index 페이지를 보려한다면 실패하게 됩니다.

image

이는 우리가 모든 요청 /**에 대해 자원을 찾을 위치를 classpath:/templates/ 로 설정하였기 때문에
기존 classpath:/static/ 에 위치한 index.html 을 찾지 못하여 발생하는 문제입니다.

templates를 리소스 경로에 추가해준것 처럼 static 경로를 추가하면 문제는 해결됩니다.

image

어째서?

먼저 Spring boot는 기본적으로 바라보는 정적 자원의 위치가 있습니다.

ResourceProperties 클래스를 보면 명시가 되어있는데요. 그 위치는 다음과 같습니다.

image

처음 addResourceHandlers 를 오버라이드 하지 않았을때는 위 경로로만 정적 파일을 탐색하였기 때문에
templates 폴더를 탐색하지 않아 우리가 원하는 home.html을 렌더링 하지 못하고 있었던 것입니다.

그런데 왜 핸들러를 추가했다고 static 경로에 있던 index.html 을 찾지 못하게 된 것 일까요?

WebMvcConfiguration

조금 전 기본적으로 Spring boot 가 제공하는 기능을 위해 WebMvcConfigurerimplements 를 했었습니다.
이때 기본적으로 제공하는 기능은 WebMvcAutoConfiguration가 제공해줍니다.

그리고WebMvcAutoConfigurationaddResourceHandlers 메서드를 오버라이드 하는 부분을 보면
다음과 같이 코드가 작성되어 있습니다.

image

코드에서 볼 수 있듯 /** 경로로 아무런 핸들러가 설정되어 있지 않다면
기본으로 제공하는 정적파일의 위치와 함께 핸들러를 제공하게됩니다.

그러나 우리가 만든 핸들러는 /**를 경로로 하였기때문에 if구문을 지나치게 되고
/static를 비롯한 다른 정적 파일 위치를 등록하지 않아 탐색에서 벗어나게 됨으로써
index.html에 접근하지 못한 것 입니다.

.html suffix 설정

매번 .html을 써주기 귀찮고 보기에도 좋지 않습니다.

이때 application.properties 혹은 .yml을 이용해서 손쉽게 바꿀수 있습니다.

.properties 기준 다음과 같이 작성하면 되고

spring.mvc.view.suffix=.html

.yml 기준 다음과 같이 작성하면 됩니다.

spring:
  mvc:
    view:
      suffix: .html

그리고 Controller에서 return하던 String 에서.html을 제거한뒤 사용하면 됩니다.

맺으며

우아한 테크코스 레벨2를 진행하며 templates에 위치한 html을 읽게 해주고 싶었는데 방법을 명확히 알지 못했습니다.
사용하지도 않을 템플릿 엔진 의존성을 단지 templates 경로 탐색을 위해 추가해야 한다는 점에서
handlebars나 thymeleaf 의존성을 추가하기 싫었습니다.

이왕 해결하는 김에 정확히 어떻게 동작하는지 천천히 확인해 봤는데 좋은 학습 방법을 찾은 것 같아 기분이 좋습니다.