웹 애플리케이션이란?

톰캣과 같은 서버를 서블릿 컨테이너라고 부른다.
서블릿 컨테이너가 담아서 관리하는 것이 바로 웹 애플리케이션이다.
서블릿 컨테이너는 웹 애플리케이션이 선의 서블릿/JSP 스펙에 따라서 동작하는 것을 보장해야 한다.

웹 애플리케이션의 구성 요소

자바 진영에서 말하는 웹 애플리케이션은 다음과 같은 파일들로 구성된다.

  • HTML, 이미지, CSS, 자바스크립트
  • JSP
  • 서블릿
  • 자바 클래스, 자바 아카이브 파일(jar)
  • web.xml

위의 구성 요소 중 어떤 것은 위치해야 할 디렉토리가 정해져 있다.
서블릿과 자바 클래스는 WEB-INF/classes,
자바 아카이브 파일은 WEB-INF/lib,
web.xml 파일은 WEB-INF 에 두어야 한다.

웹 애플리케이션 디렉토리

톰캣에서 웹 애플리케이션의 디폴트 위치는 CATALINA_HOME/webapps 이다.
새로운 웹 애플케이션을 추가하고자 한다면 CATALINA_HOME/webapps 바로 아래 서브 디렉토리1를 만들고,
서브 디렉토리안에 다음과 같은 폴더를 만든다.

WEB-INF

웹 애플리케이션 배치 정의자, web.xml 이 위치한다.
WEB-INF 디렉토리 안에 있는 파일은 웹브라우저를 통해 직접 접근할 수 없다.

WEB-INF/classes

서블릿을 포함한 자바 클래스 파일(바이트 코드)이 이곳에 위치한다.

WEB-INF/lib

자바 아카이브 파일(jar)이 이곳에 위치한다.

똑같은 바이트 코드가 WEB-INF/classes 과 WEB-INF/lib 안의 자바 아카이브 파일 안에 동시에 있을 수 있다는 것에 유의해야 한다.
이런 경우, 톰캣 클래스 로더는 먼저 검색하는 WEB-INF/classes 를 뒤져서 클래스를 찾아 메모리에 로딩한다.
해당하는 클래스를 찾았으므로 WEB-INF/lib 에 있는 클래스는 당연히 무시된다.

톰캣 클래스로더
톰캣의 클래스로더는 환경변수 CLASSPATH 를 참조하지 않는다.
톰캣의 클래스로더는 아래 순서대로 클래스를 찾는다.
  1. 자바 코어 라이브러리
  2. 웹 애플리케이션 WEB-INF/classes
  3. 웹 애플리케이션 WEB-INF/lib
  4. CATALINA_HOME/lib

배치 정의자 (Deployment Descriptor): web.xml

웹 애플리케이션의 심장은 배치 정의자 (Deployment Descriptor)라고 불리는 web.xml 파일이다.
배치 정의자 web.xml 은 WEB-INF 디렉토리에 위치한다.
배치 정의자는 웹 애플리케이션의 모든 설정 정보를 담는다.

배치 정의자로 할 수 있는 주요 설정 항목

  • 서블릿컨텍스트 초기화 파라미터
  • 필터
  • 리스너
  • servlet 정의
  • servlet 초기화 파라미터
  • servlet 매핑
  • session 설정
  • welcome 파일 리스트
  • 에러 페이지

web.xml 파일의 예와 설명

web.xml 파일을 새로 만들때는 CATALINA_HOME/webapps 에서 디폴트로 설치되어 있는 다른 웹 애플케이션의 web.xml 파일을 복사하여 자신의 웹 애플리케이션의 WEB-INF에 붙여넣는다.
그런 다음 web.xml 파일을 열고 web-app 루트 엘리먼트안의 모든 내용을 지운후 사용한다.
아래 강조된 부분처럼 web-app 엘리먼트의 서브 엘리먼트가 웹 애플리케이션의 설정이 된다.

web.xml2
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  version="4.0">
	
	<servlet>
		<servlet-name>TestServlet</servlet-name>
		<servlet-class>net.java_school.TestServlet</servlet-class>
		<init-param>
			<param-name>name</param-name>
			<param-value>value</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>TestServlet</servlet-name>
		<url-pattern>/Test</url-pattern>
	</servlet-mapping>
	  
	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
	
</web-app>

servlet 엘리먼트는 서블릿 정의와 해당 서블릿의 초기 파라미터를 설정한다.
load-on-startup 엘리먼트의 값이 0이거나 양수이면 톰캣은 웹 애플리케이션이 시작하는 시점에 해당 서블릿 객체를 생성하고 init()메소드를 호출하여 바로 서비스를 할 수 있는 상태로 만든다.
servlet-mapping 엘리먼트는 서블릿과 URL 매핑을 하기 위해 사용한다.
위의 설정에 의해서 http://localhost:포트번호/컨텍스트패스/Test를 방문하면 net.java_school.TestServlet 서블릿이 응답한다.
session-timeout 엘리먼트는 HttpSession 객체의 라이프타임을 컨트롤한다.
session-timeout 이 30으로 설정되었다면 서블릿 컨테이너는 HttpSession 객체가 30분 동안 아무런 움직임이 없다면 소멸시킨다.

팩킹 (Packing)

웹 애플리케이션은 jar 툴(jar.exe)로 하나의 파일로 만들 수 있다.
이 파일은 다양한 서블릿 컨테이너에서 작동할 수 있다.
개발이 완료되었다면 웹 애플리케이션을 번들화하여 다른 서블릿 컨테이너에 배포를 할 수 있다.
배포를 하기 위해서는 웹 애플리케이션의 루트 디렉토리에서 다음과 같은 명령을 내려 확장자가 war인 파일을 만들어야 한다. 확장자가 jar 이 아닌 war 인 것에 주의한다.
새로 만든 웹 애플리케이션의 도큐먼트베이스가
C:\apache-tomcat-9.0.87\webapps\test라면, 아래와 같이 이동하여 jar -cvf test.war . 명령을 수행한다.

C:\apache-tomcat-9.0.87\webapps\test>jar -cvf test.war .

생성된 test.war 파일은 다른 톰캣서버나 다른 벤더의 서블릿 컨테이너의 디폴트 웹 애플리케이션 폴더에 복사만 하면, 해당 서블릿 컨테이너가 자동으로 test 애플리케이션을 배치하고 로드한다.

주석
  1. 이 서브 디렉토리는 새로 만들 웹 애플리케이션의 루트 디렉토리이다.
    톰캣의 경우 이 디렉토리를 DocumentBase 라고 한다.
    DocumentBase 에는 주로 웹 애플리케이션의 구성 요소 중 정적인 요소가 위치하게 된다.
    DocumentBase 아래 css 서브디렉토리에는 스타일 시트 파일를, js 에는 자바스크립트 파일을, images 에는 이미지 파일을 두는 식이다.
    동적인 요소중 JSP는 DocumentBase 에 두어도 된다.
    하지만 정책상 WEB-INF 아래에 WEB-INF/jsp 와 같은 디렉토리를 만들어서 그곳에 위치시키는 경우가 많다.
  2. 이 web.xml 파일의 설정대로 지금 테스트할 수 없다.
    테스트하려면 TestServlet를 만들어야 한다.
    서블릿 관련 예제는 서블릿에서 본격적으로 다룰 것이다.
참고