본문 바로가기
학습/Spring

[spring] 스프링 웹 MVC의 정적 리소스 지원

by KKambi 2020. 4. 23.

정적 리소스 제공

  • 정적 리소스 : 웹 브라우저나 클라이언트가 요청했을 때, 이미 만들어져 있는 리소스를 응답하는 경우
  • 서버에서 요청을 처리해서 view를 만들어내는 게 아니라, 이미 만들어진 리소스를 제공

 

기본으로 제공하는 정적 리소스 맵핑

  • "/**" (루트맵핑)
    1. classpath:/static
    2. classpath:/public
    3. classpath:/resources
    4. classpath:/META-INF/resources
  • ex) /hello.html → /static/hello.html 을 제공할 수 있음

 

정적 리소스 요청 핸들러

ResourceHttpRequestHandler

  • 리소스 객체의 Last-Modifed 헤더와, HTTP 요청의 If-Modified-Since 헤더를 비교
  • 둘이 같은 경우, 304 Response (Not Modified : 요청된 리소스를 재전송할 필요 없음)
  • 캐싱 프로세스
    1. 브라우저(클라이언트)의 최초 요청
    2. 서버는 최근 수정시각을 Last-Modified 헤더에 기록하여, 200 Response로 정적 리소스 제공
    3. 브라우저(클라이언트)는 해당 리소스에 대한 Last-Modified 정보와 복사본(캐시)를 보유하게 됨
    4. 브라우저(클라이언트)의 재요청 시, Last-Modified 값을 If-Modified-Since에 기록하여 HTTP요청
    5. 서버는 If-Modified-Since 헤더를 통해 해당 리소스가 변경되지 않았으면 304 Response로 리소스 전달X

 

기본으로 제공되는 루트 맵핑을 변경하고 싶다면

spring.mvc.satic-path-pattern=/static/**

  • /hello.html 요청해도 응답X
  • /static/hello.html 요청해야 함

 

기본 맵핑 변경 없이, 리소스 핸들러 추가

  1. public class WebConfig implements WebMvcConfigurer
  2. public void addResourceHandlers(ResourceHandlerRegistry) 오버라이딩
  3. 레지스트리 객체에 추가
    • 리소스 핸들러 추가
    • 리소스 위치 추가
    • 캐시 피리어드 설정
    • cf) 위치 추가 시, classpath:/m/ 처럼 슬래쉬로 끝내야, 특정 디렉토리 내로 맵핑시켜주겠다는 의미
1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class WebConfig implements WebMvcConfigurer {
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/m/**")
                .addResourceLocations("classpath:/m/")
                .setCachePeriod(20);
 
    }
}
cs

 

Index페이지 설정하기

  • 루트페이지
  • 동적 페이지를 보여주는 방법 (Template Engine)
  • 정적 페이지를 보여주는 방법 → 정적 리소스 맵핑 위치에 index.html 생성

 

Favicon 설정하기

 

HtmlUnit을 이용한 자세한 단위 테스트

DOM Element를 객체화시켜서 테스트할 수 있음

  • Html Unit Test Tool
  • 해당 의존성 추가
    1. org.seleniumhq.selenium:htmlunit-driver
    2. org.seleniumhq.selenium:htmlunit-driver
  • 사용법
    • WebClient객체 Autowired -> getPage() -> HtmlPage객체
    • 페이지 객체에서 xml이나 text 등 다양한 형태로 가져옴 (asXml(), asText())
    • contains()로 특정 문자열을 포함하고 있는지?
    • getFormByName()으로 form객체를 가져와서 submit해볼 수도 있음
    • 브라우저 타입을 지정할 수도 있음
    • xpath()로 xml문서의 특정 요소나 속성에 접근할 수 있음

cf) html도 xml의 일부이기 때문에 가능!

 

댓글