본문 바로가기

Spring 3/Static Resources

Static Resources in Spring

Spring 에서 정적(static) 파일 설정하기


개요

Spring 을 사용하면서 서버에서 선행처리할 필요가  없는 정적 리소스 파일은 (xml, html, js, css, jpg, gif) 웹브라우저를 통해 직접 접속할 수 있도록 해야 하며 Controller 를 경유하지 않아도 화면에 출력되거나 다운로드가 될 수 있도록 설정해주어야 한다


Spring 프레임워크 기반의 프로젝트와 정적파일 관련 폴더

Eclipse에서 STS 플러그인을 사용하여 Spring 프로젝트를 구성하면 프로젝트 내의 폴더에 따라서 다음과 같은 상태를 확인할 수 있다


webapp : jsp, html, jpg, css, js, txt 등의 웹페이지에서 보여주기 위한 다양한 내용을 가진 포맷을 저장할 수 있는 루트 폴더

  - 정적 리소스 파일은 클라이언트가 직접 접근할 수 없다.

  - JSP 파일은 클라이언트가 직접 호출하여 서버에서 실행할 수 있다


webapp/resources : 정적파일은 이 폴더 내에 있는 것만 클라이언트가 URL을 사용하여 직접 접근할 수 있다. 이 이외의 다른 폴더에 있는 정적파일은 클라이언트 측에서 직접 접근할 수 없고, 서블릿 설정파일(servlet-context.xml)에서 다음과 같이 설정한 경우에만 정적파일에 대한 클라이언트의 직접적인 접근이 가능하다


<resources mapping="/resources/**"  location="/resources/" />

          - mapping : 접속 URL 패턴  - location : 물리적 폴더 경로


webapp/WEB-INF/, 혹은 그 하위폴더 : 정적 리소스나 JSP 등 모든 파일에 대해 클라이언트의 직접적인 접근이 불가능

  - 서버측(Servlet, JSP)에서 해당 JSP로 FORWARD, INCLUDE 등은 가능

  - MVC 패턴의 View를 저장하는 용도로 사용할 수 있다


JSP 파일의 저장 경로에 따른 특성

webapp 폴더 혹은 그 하위 폴더에 JSP 파일이 저장된 경우

  - 클라이언트에서 직접 호출(접근) 가능

  - MVC 패턴을 구성하지 않는 JSP가 주로 저장됨

webapp/WEB-INF 폴더 혹은 그 하위 폴더에 JSP 파일이 저장된 경우

  - 클라이언트에서 직접 호출불가

  - MVC 패턴을 구성하는 View 콤포넌트가 주로 저장됨

  - 다른 서블릿이나 JSP에서 FORWARD 등의 방법으로는 호출가능



정적 리소스를 저장하기 위한 경로설정

서블릿 설정파일(servlet-context.xml) 내용 중에는 다음과 같은 내용이 포함되어 있는데 그 의미는 다음과 같다.

[webappRoot]/resources 디렉토리에 정적 리소스를 저장해두면 웹브라우저에서 그 리소스의 URL을 사용하여 접속할 때 스프링은 Controller 를 경유하지 않고도 그 리소스를 웹브라우저에 전달하게 된다. 


servlet-context.xml

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->

<resources mapping="/resources/**" location="/resources/" />


이클립스에서 STS 를 사용한다면 [webappRoot] 는 webapp 라는 폴더에 해당하므로 webapp/resources 안에 정적 리소스 파일들을 저장해두면 소스코드나 웹브라우저의 주소창에서 그 리소스의 URL 을 사용하여 직접 접속할 수 있다는 것이다. 

[mapping="/resources/**"] 요청 URL 패턴 ( resources 하위에 있는 모든 경로를 의미 )

[location="/resources/"] 파일 시스템 상의 물리적 경로 ( 'webapp/resources' 를 의미 )


리소스 설정의 예

<mvc:resources mapping="/pages/**"           location="/WEB-INF/pages/" />

<mvc:resources mapping="/staticContents/**"  location="/WEB-INF/staticContents/" >

<mvc:resources mapping="/resources/**"       location="/resources/" />


정적 리소스에 클라이언트가 직접 접근하는 테스트

이클립스에서 webapp/resources/static 폴더를 생성하고 그 안에 간단한 test.html 혹은 jpg와 같은 정적 리소스 파일을 저장해 두고 웹브라우저 주소창에 다음과 같이 입력하면 웹브라우저의 화면에 해당 정적 파일의 내용이 출력되는 것을 확인할 수 있다


[웹브라우저 주소창에서 직접 접속하는 경우]

http://localhost:8080/myspring/resources/static/test.html


JSP 나 HTML 안에서 참조하는 경우

<script type="text/javascript" src="resources/jquery-2.1.4.min.js"></script>

위와 같이 상대경로를 사용하는 경우는 웹브라우저 주소창의 현재 경로에 따라서 절대경로로 해석되어 요청되므로 주소창의 경로에 따라서 실제의 파일의 경로와 다르게 요청될 수 있기 때문에 오류가 발생할 수도 있다. 이러한 문제 때문에 JSTL의 <c:url> 태그를 사용하는 것이 좋다


위의 테스트용 사용된 URL 중에서 'myspring' 은 웹컨텍스트 명이다.


정적 리소스를 참조하기 위한 JSTL <c:url> 

웹브라우저 주소창에서 직접 접속하는 경우가 아니라 JSP 등의 소스코드에서 URL을 사용하려면 다음과 같이 JSTL을 사용하는 것이 편리하다.

<c:url> 태그는 상대경로를 절대경로로 변환해주는 기능이 있는데 웹브라우저 주소창에 있는 주소를 기준으로 절대경로로 변환하는 것이 아니라 주어진 경로에 [http:// ~ /컨텍스명] 을 추가하여 절대경로를 생성해주기 때문에 리소스에 대한 정확한 URL을 생성할 때 유용하다.


다음은 jQuery 라이브러리를 JSP 파일에서 설정하는 예이며 webapp/resources 폴더에 위치한 *.js 파일을 참조하는 경우이다


설정파일의 내용이 다음과 같다면

<mvc:resources mapping="/resources/**" location="/resources/" />


위의 설정에 따르면 실제 파일 시스템의 물리적 경로는 webapp/resources/ 안의 모든 하위 경로를 의미하므로 소스파일에서 해당 경로의 리소스파일을 참조하려면 다음과 같이 하면 된다

<script src="<c:url value="/resources/jquery-2.1.1.min.js"/>"></script>

위와 같이 설정하면 현재 웹브라우저의 주소창이 기준이 아니라 항상 웹컨텍스트 하위패스인 resources 경로를 참조할 수 있으므로 리소스를 찾지 못하는 오류를 방지할 수 있다