정적 리소스 지원

정적 리소스는 웹 브라우저나 클라이언트에서 요청이 왔을 때, 이미 생성된 정적 리소스를 응답하는 경우에 주로 사용된다. 컨트롤러에서 작업을 처리하고 뷰를 만들어내는게 아닌, 이미 만들어져 있는 리소스를 제공할 수 있다.

정적 리소스 맵핑 "/**"

  • classpath:/static
  • classpath:/public
  • classpath:/resources/
  • classpath:/META-INF/resources

위 네가지 위치에 존재하는 리소스들은 “/**”에 매핑이 돼서 제공된다. 예를 들어 “/hello.html”라는 요청이 들어오면, /static/hello.html 라는 파일을 찾아 응답한다.

실습

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
Hello Static Resources
</body>
</html>

이번 실습은 간단하다. /resources/static 폴더에 hello.html 파일을 생성해보자. 앱을 실행하면 localhost:8080/hello.html에 요청을 보낼 경우, /resources/static/hello.html 리소스가 응답된다.

ResourceHttpRequestHandler

정적 리소스를 처리하는 작업은 ResourceHttpRequestHandler가 처리한다. ResourceHttpRequestHandler는 Last-Modified라는 응답의 헤더 정보를 보고 304 상태코드를 응답하기도 한다.

브라우저에서 리소스에 최초로 요청을 보내는 경우, 응답의 Last-Modified 헤더값을 기억하고 있다가 다음 요청 헤더 중 If-Modified-Since 헤더에 포함하여 전송한다.

서버에서는 If-Modified-Since 헤더값과 리소스의 변경 시점이 같다면 304 상태코드를 응답하면서 다시 리소스를 응답하지 않는다.

만약, If-Modified-Since 헤더값과 리소스의 변경 시점이 다르다면 변경된 리소스와 200 상태코드를 응답하게 되면서 브라우저는 다시 응답의 Last-Modified 헤더값을 다음 요청의 If-Modified-Since 헤더값에 포함하여 전송한다.

커스터마이징

정적리소스의 URL 패턴은 전부 루트 경로인 '/' 부터 시작하지만, spring.mvc.static-path-pattern 프로퍼티를 이용하여 매핑 설정을 변경할 수 있다. spring.mvc.static-locations 프로퍼티를 이용하면 리소스를 찾을 위치를 변경할 수 있다.

하지만, spring.mvc.static-locations는 기본 설정된 네가지 path를 사용하지 않게 되므로 권장하지 않는다. 커스터마이징에 권장되는 방법은 WebMvcConfigurer의 addRersourceHandlers를 사용하는 것이다.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/m/**")
                .addResourceLocations("classpath:/m/")
                .setCachePeriod(20);
    }
}

위의 코드는 /m/으로 시작하는 요청이 들어오면 /m/이라는 디렉토리의 리소스를 반환한다. WebMvcConfigurer의 addResourceHandlers를 이용하여 커스터마이징하면, 스프링부트가 제공하는 기본 리소스핸들러는 유지하면서 새로운 리소스핸들러를 추가할 수 있다. ResourceHandlerRegistry의 addResourceLocations() 메소드에 전달되는 resourceLocations는 반드시 /로 끝나야한다는 점을 주의해야 한다.

해당 포스팅은 스프링 부트 개념과 활용 강의 내용을 토대로 작성하였습니다.