open:web.xml

web.xml

web.xml의 개요

DD(Deployment Descriptor)는 각 어플리케이션의 환경을 설정하는 부분을 담당한다.

WAR 파일이 패키지 될 때 같이 포함되며 root directory 밑에 /WEB-INF 디렉토리에 위치한다.

  • Web Application 의 Deployment Descriptor(환경파일: 배포서술자, DD파일)로서 XML 형식의 파일
  • 모든 Web application은 반드시 하나의 web.xml 파일을 가져야 함
  • 위치 : WEB-INF 폴더 아래
  • web.xml 파일의 설정들은 Web Application 시작시 메모리에 로딩됨. (수정을 할 경우 web application을 재시작 해야함)

1. 사용자의 URL 요청

어떤 사용자의 URL 요청이 서블릿 요청이라는 것을 웹 서버가 알기 위헤서는 사전에 서버 측에 URL과 서블릿 클래스를 미리 매핑시켜 놓은 배포 서술자가 필요하다.
배포서술자(Deployment Descriptor) : DD, 웹서버가 알아 챌 수 있도록 적어 놓은 파일(web.xml)

2. request, response

웹 컨테이너는 일단 지금 받은 요청을 처리하기 위해 HTTP 요청(Request)을 처리하기 위한 request 객체와 HTTP 응답(response)를 위한 response 객체를 생성한다. 

3. 서블릿 인스턴스와 스레드 생성

request, response 객체가 생성된 뒤 사용자의 URL 요청이 어떤 서블릿 클래스를 필요로 하는지 배포 서술자를 통해 알아낸다. 
 만일 그 클래스가 웹 컨테이너에서 한 번도 실행된 적이 없거나 현재 메모리에 생성된 인스턴스(프로세스)가 없다면 새로 인스턴스를 생성하고(메모리에 로드하고) init() 메소드를 실행하여 초기화 한 뒤 스레드를 하나 생성한다.
 이미 인스턴스가 존재할 경우엔느 새로 인스턴스를 생성하지 않고 기존의 인스턴스에 스레드만 하나 새로 생성한다. 각 서블릿 인스턴스는 웹 컨테이너당 하나만 존재하기 때문에 init() 메소드는 각 서블릿 당 한 번씩만 호출된다.

4. service() 메소드 호출과 서블릿 클래스 실행

스레드가 생성되면 각 스레드에서 service() 메소드가 호출된다. 
service() 메소드가 호출되면 HTTP 요청 방식이 GET 방식일 경우에는 서블릿 클래스의 doGet()메소드가, POST 방식일 경우네는 doPost()메소드가 request, response 객체를 인자로 자동으로 호출된다.

5. 응답과 스레드의 소멸

doGet() 또는 doPost() 메소드가 호출되어 사용자의 요청에 따른 동적인 웹 페이지를 생성하면 그 결과물이 담긴 response 객체를 웹 컨테이너가 HTTP 응답(Response) 형태로 바꾸어 웹 서버로 전송하게 된다. 그리고 사용이 끝난 Request와 Response 객체를 소멸시키고 스레드를 종료하게 된다. 
  • ServletContext 의 초기 파라미터
  • Session 의 유효시간 설정
  • Servlet/JSP에 대한 정의
  • Servlet/JSP 매핑
  • Mime Type 매핑
  • Welcome File list
  • Error Pages 처리
  • 리스너/필터 설정
  • 보안
  • 대소문자를 구분 해줘야 한다.
  • attribute 값은 반드시 “” 또는 '' 으로 감싸야 한다.
  • 태그는 반드시 닫아야 한다.
  • servlet-name : 아래 servlet-mapping에 알려주기 위한 식별자
  • servlet-class : 실제 서블리 클래스, 패키지까지 정확하게 기술
<servlet> 서블릿 객체 설정
  <servlet-name> : 객체의 이름  </servlet-name>
  <servlet-class> : 객체를 생성할 클래스 </servlet-class>
</servlet>
  • servlet-name : 위의 servlet에 명시한 이름
  • url-pattern : 어떠한 URL 경로로 접근할 수 있는지를 명시
<servlet-mapping>
  <servlet-name> 이름 </servlet-name>  서블릿 객체의 이름
  <url-pattern> 패턴 </url-pattern> 클라이언트가 요청할 URL 패턴
</servlet-mapping>
  • 기타 요소
<!-- 세션 기간 설정 -->
  <session-config>
    <session-timeout>
      30
    </session-timeout>
  </session-config>
  <!-- mime 매핑 -->
  <mime-mapping>
    <extension>txt</extension>
    <mime-type>text/plain</mime-type>
  </mime-mapping>
  <!-- 시작페이지 설정 -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <!-- 존재하지 않는 페이지, 404에러시 처리 페이지 설정 -->
  <error-page>
    <error-code>404</error-code>
    <location>/error.jsp</location>
  </error-page>
  <!-- 태그 라이브러리 설정 -->
  <taglib>
    <taglib-uri>taglibs</taglib-uri>
    <taglib-location>/WEB-INF/taglibs-cache.tld</taglib-location>
  </taglib>
  <!-- resource 설정 -->
  <resource-ref>
    <res-ref-name>jdbc/jack1972</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

### context-param

<context-param> 컨텍스트 초기화 파라미터

모든 웹 애플리케이션에서 파라미터를 공유하기 위해서 사용한다.

web.xml

<context-param>
        <param-name>id</param-name>
        <param-value>remns</param-value>
</context-param>

servlet

 public class ContextTestClass extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.print(getServletContext().getInitParameter("id");
    }
}

web.xml
<sxh xml>

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</sxh>

  • 어떠한 이벤트가 발생하면 호출되어 처리하는 객체
  • 구현할 기능과 관련된 각종 인터페이스만 제공함으로 클래스는 구현해야 함.
  1. ServletContextListener

웹 어플리케이션의 시작과 종료시 자동으로 발생되는 이벤트를 수행하기 위한 메소드를 정의한 인터페이스이다.

Listener 객체 설명
contexInitialized(ServletContextEvent sce) : void 웹 컨테이너가 처음 구동될 때 실행되는 메소드
contextDestroyed(ServletContextEvent sce) : void 웹 컨테이너가 종료될 때 실행되는 메소드

2. ServletContextAttributeListener

컨테이너에 저장된 속성 값들의 변화가 있을 때 수행하기 위한 메소드를 정의한 인터페이스이다.


3. HttpSessionListener

HTTP 세션이 활성화 되거나 비활성화 되려할 때 혹은 속성 값들이 추가, 삭제, 변경될 경우 수행하기 위한 인터페이스


4. HttpSessionAttributeListener

HTTP 세션에 대한 속성 값이 변경되었을 경우 수행하기 위한 인터페이스


5. HttpSessionActivationListener

세션에 대한 내용이 새로 생성되어 세션이 활성화 되었을 때 발생하는 이벤트를 수행하기 위한 인터페이스


6. HttpSessionBindingListenr

클라이언트의 세션 정보에 대한 바인딩이 이루어졌을 경우 감지되는 이벤트를 수행하기 위한 인터페이스

환경설정은 <web-app>으로 시작하고 </web-app>로 끝난다.

web.xml의 elements 순서

  • <icon>
  • <display-name>
  • <description>
  • <distributable>
  • <context-param>
  • <filter>
  • <filter-mapping>
  • <listener>
  • <servlet>
  • <servlet-mapping>
  • <session-config>
  • <mime-mapping>
  • <welcome-file-list>
  • <error-page>
  • <taglib>
  • <resource-env-ref>
  • <resource-ref>
  • <security-constraint>
  • <login-config>
  • <security-role>
  • <env-entry>
  • <ejb-ref>
  • <ejb-local-ref>

<sxh xml>
<?xml version=“1.0” encoding=“UTF-8”?>
<web-app version=“2.5”
xmlns=“http://java.sun.com/xml/ns/javaee
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd


<display-name>어플리케이션 이르</display-name>

<description>어플리케이션 설명</description>

<!-- 서블릿 매핑:  보안과 주소를 간략화 하기 위해 사용 -->
<servlet>
	<servlet-name>test1</servlet-name>
	<servlet-class>app.engine.test1</servlet-class>	
</servlet>
<!-- load-on-startup 옵션은 서버 구동시 자동으로 시작 되도록 하는 것이다. -->
<servlet>
	<servlet-name>test2</servlet-name>
	<servlet-class>app.servlet.test2</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

<!-- 서블릿 매핑 : 위에서 servlet 부분을 삭제한다. -->
<servlet-mapping>
	<servlet-name>test1</servlet-name>
	<url-pattern>/test1</url-pattern>
</servlet-mapping> 

<!-- /test2/* 과 동일한 패턴의 요청이 들어오면 처리-->
<servlet-mapping>
	<servlet-name>test2</servlet-name>
	<url-pattern>/test2/*</url-pattern>
</servlet-mapping>
<!-- 세션 기간 설정 -->
<session-config>
	<session-timeout>30</session-timeout>
</session-config>
<!-- mime 매핑 -->
<mime-mapping>
	<extension>txt</extension>
	<mime-type>text/plain</mime-type>
</mime-mapping>
<!-- 시작페이지 설정 -->
<welcome-file-list>
	<welcome-file>index.jsp</welcome-file>
	<welcome-file>index.html</welcome-file>
</welcome-file-list>

<!-- 존재하지 않는 페이지, 404에러시 처리 페이지 설정 -->
<error-page>
	<error-code>404</error-code>
	<location>/error.jsp</location>
</error-page>

</web-app>

</sxh>

이 상태로 실행을 하게 되면 아래와 같은 에러가 발생한다.

[INFO] 심각: javax.servlet.ServletContext log: unavailable
[INFO] javax.servlet.UnavailableException: Servlet class app.engine.test1 is not a javax.servlet.Servlet

오류가 발생한 아래의 클래스를
<sxh java>
package app.engine;

public class test1 {

}
</sxh>

아래와 같이 변경한다.
<sxh java>
package app.engine;

import javax.servlet.http.HttpServlet;

public class test1 extends HttpServlet{

}
</sxh>

에러 없이 서버가 실행되므로, 해당 클래스가 호출되는 것을 확인하기 위하여, 클래스를 아래와 같이 변경합니다.

<sxh java>
package app.engine;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class test1 extends HttpServlet {

private int count;
@Override
public void init(ServletConfig config) throws ServletException {
	super.init(config);
	getServletContext().log("test1 init() called");
	count = 0;
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
		IOException {
	getServletContext().log("test1 service() called");
	count++;
	response.getWriter().write("test1 Incrementing the count: count = " + count);
}
@Override
public void destroy() {
	getServletContext().log("test1 destroy() called");
}

}

</sxh>

서블릿은 자바 플랫폼에서 동적인 웹을 개발할 때 사용하는 기반 기술로서 웹에서 Java 프로그래밍을 할 수 있습니다.
사용자의 요청(Request)을 받아 요청한 대로 처리해주는 (doGet() 또는 doPost() 메서드) 일을 한 후 처리결과를 사용자에게 응답(Response) 해줍니다.

Filter 의 이해

  • 필터는 HTTP 요청과 응답을 변경할 수 있는 재사용가능한 코드 이다.
  • 필터는 객체의 형태로 존재하며 클라이언트로부터 오는 요청(request)과 최종 자원(서블릿/JSP/기타 문서) 사이에 위치하여 클라이언트의 요청 정보를 알맞게 변경할 수 있으며, 또한 필터는 최종 자원과 클라이언트로 가는 응답(response) 사이에 위치하여 최종 자원의 요청 결과를 알맞게 변경할 수 있다.
  • 세션관리, 로그파일관리, 인코딩관리, 데이터 압축 등의 작업을 할 수 있다.

클라이언트 → (request) → 필터 → 자원(Servlet/JSP/etc)

클라이언트 ← (response) ← 필터 ← 자원(Servlet/JSP/etc)

  • 여러 개의 필터가 모여서 하나의 체인을 형성할 때 첫번째 필터가 변경하는 요청 정보는 클라이언트의 요청 정보가 되지만, 체인의 두번째 필터가 변경하는 요청 정보는 첫번째 필터를 통해서 변겨된 요청 정보가 된다.
  • 즉, 요청 정보는 변경에 변경에 변경을 거듭하게 되는 것이다. 응답 정보의 경우도 요청 정보와 비슷한 과정을 거치며 차이점이 있다면 필터의 적용 순서가 요청 때와는 반대라는 것이다.

filter
<sxh java>
package com.example.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class LoginCheckFilter implements Filter {
public void init(FilterConfig config) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,

 FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpSession session = httpRequest.getSession(false);

boolean login = false;

String id = request.getParameter("id");
String pw = request.getParameter("pw");
System.out.println(id+pw);

if(id.equals(pw)) {
 session.setAttribute("MEMBER",id);
}

if(session != null){
 if(session.getAttribute("MEMBER") != null){
  login = true;
 }
}
if(login){
 chain.doFilter(request, response);
}
else{
 System.out.println("로그인에 실패!");
 RequestDispatcher dispatcher = request
   .getRequestDispatcher("/loginForm.jsp"); // getRequestDispatcher() 컨텍스트명/*.jsp
 
 dispatcher.forward(request, response); //forward 는 브라우져의 url이 변경되지 않고 화면 이동.(서버쪽에서 화면을 변경한다.)
}

}
public void destroy() {
}
}
</sxh>

web.xml
<sxh xml>
<filter>

<filter-name>LoginCheck</filter-name>
<filter-class>com.example.web.LoginCheckFilter</filter-class>

</filter>

<filter-mapping>
<filter-name>LoginCheck</filter-name>
<url-pattern>/Login.jsp</url-pattern>

</filter-mapping>
</sxh>

- http://jwchoi85.tistory.com/58
- http://wiki.gurubee.net/pages/viewpage.action?pageId=26740333
- https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EC%84%9C%EB%B8%94%EB%A6%BF
- http://dkatlf900.tistory.com/68
- https://www.imaso.co.kr/doc=bbs/gnuboard.php&bo_table=article&wr_id=40915
- http://remns.tistory.com/8
- http://wiki.gurubee.net/pages/viewpage.action?pageId=26740229
- http://wiki.gurubee.net/pages/viewpage.action?pageId=26740333
- http://devbox.tistory.com/entry/Spring-webxml-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95
  • open/web.xml.txt
  • 마지막으로 수정됨: 2023/03/31 14:10
  • 저자 MORO