정적리소스 처리

정적 리소스 처리 Servlet 설정

  • (정적 리소스 처리를 아파치로 하지 않는 경우)

  • 일반적으로 DispatcherServlet을 *.do와 같은 url을 매핑하여 로직을 통한 동적인 리소스를 처리하고, 정적인 리소스는 DefaultServlet으로 처리한다.

    • DefaultServlet에 대한 설정은 톰캣의 web.xml에 설정되어 있으며, *.jsp 요청에 대한 처리를 담당하는 JspServlet도 설정되어있다.
// DefaultServlet 설정  
<servlet>  
    <servlet-name>default</servlet-name>  
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>  
    <init-param>  
        <param-name>debug</param-name>  
        <param-value>0</param-value>  
    </init-param>  
    <init-param>  
        <param-name>listings</param-name>  
        <param-value>false</param-value>  
    </init-param>  
    <load-on-startup>1</load-on-startup>  
</servlet>
<servlet-mapping>  
    <servlet-name>default</servlet-name>  
    <url-pattern>/</url-pattern>  
</servlet-mapping>  
​  
// JspServlet 설정  
<servlet>  
    <servlet-name>jsp</servlet-name>  
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>  
    <init-param>  
        <param-name>fork</param-name>  
        <param-value>false</param-value></param-value>  
    </init-param>  
    <init-param>  
        <param-name>xpoweredBy</param-name>  
        <param-value>false</param-value>  
    </init-param>  
    <load-on-startup>3</load-on-startup>  
</servlet>  
<servlet-mapping>  
    <servlet-name>jsp</servlet-name>  
    <url-pattern>*.jsp</url-pattern>  
    <url-pattern>*.jspx</url-pattern>  
</servlet-mapping>



  • 그런데 Restful URL로 개발하는 경우 DispatcherServlet에 매핑할 url로 *.do와 같은확장자를 붙이지 않기 때문에, *.do와 같은 url 패턴을 정의하기 어렵다.

    • 그래서 애플리케이션 루트(/)로 지정하게 되는 경우 /로 시작하는 모든 URL 요청이 DispatcherServlet으로 들어오게 되는데, 이렇게 되면 *.js나 *.css파일에 대한 처리를 하는 핸들러가 없기때문에 404 에러가 발생한다.

    • 이를 해결하기 위해 /app/*과 같이 디렉토리를 추가하는 방법과 UrlRedirectFilter를 구현하는 방안으로 사용했다지만, 불필요하게 추가 디렉토리 url이 늘어나는 부분은 좋아보이지 않는다.



  • 이런 불편함을 위해 스프링 3.0.4부터는 <mvc:default-servlet-handler/> 설정을 제공한다.

  • DispatcherServlet에 애플리케이션 루트(/)를 매핑하고 해당 설정을 추가하면, 모든 URL 요청을 DispatcherServlet이 받은 후, 정적 리소스 요청은 DefaultServlet으로 포워딩해준다.

  • 포워딩 하는 과정은 다음과 같다.

    • DispatcherServlet으로 들어와서, 요청 URL과 매핑되는 핸들러가 있는지 찾는다.

    • @RequestMapping으로 등록한 핸들러가 없다면, 해당 설정이 내부적으로 등록한 DefaultServletHttpRequestHandler를 찾는다.

    • DefaultServletHttpRequestHandler는 /**과 매핑되어 있어 가장 낮은 우선순위로 매핑되는 것이다.

    • DefaultServletHttpRequestHandler는 정적 리소스 요청을 DefaultServlet으로 넘기는 역할을 한다.

  • 추가적으로 DispatcherServlet에 /*를 매핑하지 말아야한다.

  • 그 이유는 jsp 요청마저 DispatcherServlet으로 들어와서 매핑된 핸들러가 없으면 404 에러가 발생하기 때문이다.



  • 다른 방법으로는 기존의 DefaultServlet의 매핑 url 패턴을 애플리케이션 루트(/)를 대신에 변경하는 것이다.

  • 자바 웹 개발 완벽 가이드 책에서는 위와같이 DispacherServlet으로 모두 받고 포워딩하는 작업이 불필요하고 성능도 좋지 안하고 하는데, 어떤 방법을 사용할지는 알아서 선택하면 된다.

<servlet-mapping>  
    <servlet-name>default</servlet-name>  
    <url-pattern>/resources/*</url-pattern>  
    <url-pattern>*.css</url-pattern>  
    <url-pattern>*.js</url-pattern>  
    ...  
</servlet-mapping>
servletContext.getServletRegistration("default").addMapping("/resources/*", "*.css", "*.js");


댓글