톰캣의 컨텍스트 외부로 경로 매핑하는 방법

일반적으로 웹 프로젝트를 진행해보면 디자인은 디자인팀에서, 프로그램은 프로그램 개발팀에서 별개로 진행하게 되어 별개의 산출물이 만들어진다. 그래서 개발팀의 프로젝트 소스에 디자인 산출물, 예를 들어 이미지나 CSS 파일을 일일이 받아 넣기가 곤란하거나 효율상 넣지 않기로 하는 경우가 대체적인 프로젝트 흐름이다. 이럴 때 개발팀에서 톰캣의 컨텍스트 외부로 경로 매핑하는 방법이 필요해진다.

원칙적으로 소스 버전 관리를 통해서 산출물을 공유하면 좋지만 디자인팀은 아.. 그런 거 골치아파요하거나 일단 진행하다가 나중에 넣을께요하며 시간 지연 작전을 쓴다. 또한 개발팀은 개발팀대로 이미지는 파일 크기가 상당히 큰 편이다 보니 프로젝트 폴더에 이미지를 넣고 주고 받는 게 심적으로 부담스러운 면도 있다.

아무튼 이렇게 정적인 자원(디자인 산출물)을 별개로 관리할 경우 개발팀에서 Tomcat으로 개발 중인 웹페이지를 띄울 때 어떻게 하는 게 좋을까? 예를 들어 컨텍스트 경로는 /, 즉 루트고 실제 경로는 d:\project\webapp이라고 하자. 그런데 이미지 경로는 /img이고 실제 경로는 d:\project\design\img일 경우 어떻게 할까? 또는 이미지의 실제 경로가 같은 컴퓨터에 있지 않고 예를 들어 http://123.45.67.89/img에 있다면?

우선 한 컴퓨터 안에 정적인 자원과 자바 컨텍스트가 같이 있되 폴더 위치는 다른 경우를 살펴보자.

아파치 HTTP 서버 + 톰캣

톰캣(Tomcat) 앞에 아파치(Apache) 웹서버를 프록시로 두는 경우는 서버 기계가 여러 대인 운영 서버 환경에서 자주 볼 수 있는 조합이다. 개발 환경에서는 꼭 이렇게 할 필요는 없겠지만 아무튼 이런 경우는 처음부터 아파치 웹서버가 독립적으로 정적인 자원을 서비스하므로 톰캣이 서비스하는 자바 컨텍스트와 아무 상관이 있을 게 없다. 웹서버는 웹서버대로 웹폴더 위치를 지정하고 톰캣은 톰캣대로 웹폴더 위치를 지정하면 된다.

혹시 아파치 웹서버 2.2 이상에서 웹서버와 톰캣을 연동해주는 프록시 설정을 알고 싶다면 여기를 보도록 한다.

톰캣 6 이상(6, 7, 8 공통)

톰캣 6부터는 2단계 이상 디렉터리 구조의 컨텍스트를 지원한다. 무슨 말인가하면 /www와 같은 컨텍스트 뿐 아니라 /www/img와 같은 경로를 별도의 컨텍스트로 독립시킬 수 있다.

방법은 컨텍스트 설정 xml 파일을 “경로1#경로2.xml”과 같은 이름으로 만들어 컨텍스트 설정 파일 경로인 $CATALINA_BASE/conf/[enginename]/[hostname] 폴더에 넣어두는 것이다. 기본 설치 상태인 경우 [enginename]은 “Catalina”고 [hostname]은 “localhost”가 된다. 그리고 파일 내용은 예를 들어 다음과 같이 될 것이다.

<Context path="/img" reloadable="true" docBase="d:\project\design\img">
</Context>

이클립스 같은 개발 환경에서는 위의 설정 파일이 위치하는 경로에 파일을 넣어주기 보다는 Servers 프로젝트에서 톰캣 설정 파일 server.xml 파일을 열어 <Context>를 추가해주는 게 더 편리하다.

톰캣 7

위 방법은 정적인 자원 폴더가 예를 들어 /www/img, /www/css, /www/js 등과 같이 여럿일 경우 설정하는 작업이 귀찮아진다. 또한 설정 파일을 별개로 서버에 작업해 넣어야 하므로 소스 버전 관리가 되지 않는 문제도 있다.

톰캣 7에서는 aliases를 설정할 수 있다.

<Context ...
    aliases="/img=d:\project\design\img,/js=d:\project\design\js,/css=d:\project\design\css"/>
</Context>

또한 가상 경로를 설정할 수도 있다. 동작상으로는 위의 aliases와 다를 건 없다. 컨텍스트 설정 파일에 다음과 같이 Resources 태그를 추가하면 된다.

<Context ...>
    <Resources className="org.apache.naming.resources.VirtualDirContext"
        extraResourcePaths="/img=d:\project\design\img,/js=d:\project\design\js,/css=d:\project\design\css"/>
</Context>

이러한 설정 내용은 META-INF/context.xml에 넣는 것이 프로젝트 소스를 관리하는 면에서 편리하다. 그런데 위에서 aliases의 경우는 경로 설정 문자열의 컴마나 등호 앞뒤로 빈칸이나 줄바꿈 같은 게 있을 수 있으나 가상 경로는 있으면 안된다.

또 한 가지 주의할 점은 (이미 다 알고 하고 있겠지만 확인 차원에서 말하자면) 스프링 같은 프레임웍을 사용할 경우 대개 WEB-INF/web.xml 파일에서

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

와 같이 모든 경로를 스프링의 디스패처 서블릿으로 서비스하도록 설정하는 경우가 일반적인데 이 경우 정적인 자원도 스프링에서 처리하도록 돼 있기 때문에 스프링 설정에서

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

와 같이 정적인 자원은 배제하는 게 필수라는 것이다.

톰캣 8

톰캣 7의 혼란스러운 설정들은 톰캣 8에서 과감히 정리됐다. <Context> 태그 안에 PreResources, JarResources, PostResources 등을 설정할 수 있게 바뀌었는데 JAR 파일에 정적인 자원을 넣어 서비스하는 경우가 아니라면 일반적으로 PreResources를 설정하면 된다.

<Context ...>
    <PreResources className="org.apache.catalina.webresources.DirResourceSet"
        webAppMount="/img" base="d:\project\design\img"/>
</Context>

정적인 자원이 원격지(다른 컴퓨터)에 있는 경우

마지막으로 정적인 자원이 자바 컨텍스트가 위치한 컴퓨터와는 다른 컴퓨터에 있는 경우를 알아보자. 이 경우는 좀 번거롭지만 정적인 자원의 경로 앞에 원격지의 주소를 일일이 붙여주는 수 밖에 없다.

<html>
...
<img src="http://123.45.67.89/img/category/abc123_on.png" >
...
</html>

원격지의 주소는 개발 중 바뀔 수도 있고 운영 서버로 최종 배포할 때도 바뀔 가능성이 많으므로 스프링 같은 프레임웍이나 JSTL을 사용한다면 원격지 주소를 설정 파일 같은 곳에서 변수로 뽑아오는 것이 편리하다.

<img src="${resourcePath}/img/category/abc123_on.png" >

이상으로 글을 마치며 디자인팀과 개발팀의 조화로운 프로젝트 진행을 꿈꿔본다. 😉

톰캣의 컨텍스트 외부로 경로 매핑하는 방법”에 대한 의견

  1. 정말 감사합니다..
    답글 잘 안쓰는데.. 진심으로 감사해서 인사드려요
    이미지가 안보여서 고생했거든요 ^^

    1. 별 글 아닌데 도움 받으셨다니 제가 다 기쁘네요. 방문해 주셔서 감사드립니다!

  2. 아 저도진짜감사합니다. 이것때문에 톰캣서버를 하나 더올리니 논쟁이많았는데.. 해결되네요ㅋ

    1. 톰캣에 찾아보면 다양한 기능이 있어서 활용하자면 개발용으로 쓰기에는 아까울 정도지요. ㅎㅎ 방문해주셔서 감사합니다.

  3. 오오 감사합니다! 그런데 컨텍스트를 대소문자 구분하지 않게 만들 수는 없을까요? /img/abc.jpg도 되고 /IMG/abc.jpg도 가능하게 하고 싶어서요.

    1. /img와 /IMG 모두 가상 경로로 등록하되 둘 다 같은 곳을 바라보게 하면 되지 않을까요? ^^ 방문 감사드립니다~

  4. 일주일동안 고생한게 이 블로그보고 한방에 해결 됐네요…

    진심으로 감사합니다^^

  5. 아.. 저도 정말 감사합니다.
    이미지파일 불러오는데 일주일간 고생하고 있었는데.. 한방에 해결하고 가네요^^

  6. 이클립스에서 이미지 파일 불러오는데 고생 중입니다. 혹시 톰캣 7 설정 파일 좀 올려주시면 안될까요?
    / 같은 컨텍스트 뿐 아니라 /Data 두개 컨텍스트를 써야하는데 설정을 잘 못하겠네요…

    1. 이클립스에서 톰캣 띄우는 데 설정 파일을 직접 수정할 경우는 거의 없는데요. 좀더 자세한 상황이나 파일을들 보여주시면 어떨까도 싶네요.

  7. 저 댓글 처음다는데 진짜 계속찾고있었는데 진짜감사합니다ㅠㅠㅠ정말..정말류ㅠㅠㅠㅠ

의견 있으시면 냉큼 작성해주세요~