본문으로 바로가기

Servlet의 이해 및 간단예제

category Program/JSP 2016. 1. 14. 10:40

Servlet의 이해 및 간단예제

1. Servlet의 이해

1.1 Servlet 이란

  • Servlet은 웹에서 JAVA 프로그래밍을 구현하기 위해 탄생 함.
  • JAVA 로 구현된 CGI(Common Gateway Interface) 라고들 흔히 말함
  • HTTP protocol 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속하여 개발하며, Servlet은 Container에 의해서 실행되고, 관리된다.
  • HTML 변경시 Servlet을 재컴파일 해야 하는 단점이 있다.

1.2 Servlet Container란

  • HTTP 요청을 받아서 Servlet을 실행시키고, 그 결과를 사용자 브라우저에게 전달해주는 기능을 제공하는 컴포넌트 이다.
  • Servlet을 실행하고 생명주기를 관리하는 역할을 한다.
  • Servlet과 웹 서버(Apache, nginx..)가 서버 통신 할 수 있는 방법을 제공한다.
  • 멀티 스레딩을 지원하여 클라이언트의 다중 요청을 알아서 처리해준다.
  • 대표적인 Conatainer에는 Tomcat, jetty, jboss 등이 있다.

1.3 Servlet 동작과정

  • ① 사용자가 URL을 클릭하면 HTTP Request를 Servlet Container에 보낸다.
  • ② Servlet Container는 HttpServletRequest, HttpServletResponse 두 객체를 생성한다.
  • ③ 사용자가 요청한 URL을 분석하여 어느 서블릿에 대한 요청인지 찾는다. (DD를 참조하여 분석)
  • ④ 컨테이너는 서블릿 service() 메소드를 호출하며, POST, GET여부에 따라 doGet() 또는 doPost()가 호출된다.
  • ⑤ doGet() or doPost() 메소드는 동적인 페이지를 생성한 후 HttpServletResponse객체에 응답을 보낸다.
  • ⑥ 응답이 완료되면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킨다.
DD (배포서술자, Deployment Descriptor) = web.xml
  • Servlet, Error Page, Listener, Fillter, 보안 설정등 Web Application의 설정 파일이다.
  • URL과 실제 서블릿의 매핑 정보도 담고 있다.
  • 하나의 웹 어플리케이션에 하나만 존재한다.
  • 보통 Web Document Root 디렉토리에 WEB-INF 폴더 아래 web.xml 파일로 존재한다.

1.4 JSP의 동작구조

2. Servlet 간단예제

2.1 Servlet 예제 코드 작성

  • src/main/java 폴더 아래에 com.oracleclub.study.servlet 패키지를 생성하고 아래의 HelloServlet을 생성한다.
  • 모든 JAVA 파일은 직접 코딩해 주세요
com.oracleclub.study.servlet.HelloServlet.java
/*
 * HelloServlet.java 2012. 9. 14.
 *
 * Copyright www.gurubee.net All rights Reserved.
 */
package com.oracleclub.study.servlet;

import java.io.IOException;
import java.io.PrintWriter;

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

/**
 * Servlet 간단 예제
 * 
 * @author : oramaster
 * 
 */
@SuppressWarnings("serial")
public class HelloServlet extends HttpServlet {

    // 대부분의 Servlet은 doGet 또는 doPost만 작성하며,
    // 컨테이너가 생성한 Request와 Response 객체를 전달 받는다.
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html; charset=UTF-8");

        // Response 객체의 PrintWriter를 사용해 브라우저에 HTML을 출력한다.
        PrintWriter out = resp.getWriter();
        out.println("<HTML><HEAD><TITLE>HelloServlet</TITLE></HEAD>");
        out.println("<BODY>");
        out.println("<H2> Clinet IP: " + req.getRemoteAddr() + "</H2>");
        out.println("<H2> Client Host : " + req.getRemoteHost() + "</H2>");
        out.println("<H2> Request URI : " + req.getRequestURI() + "</H2>");
        out.println("</BODY></HTML>");
    }
}

2.2 URL과 Servlet 매핑하기

  • HelloServlet 작성이 완료 되었다면, 배포서술자(DD=web.xml) 파일에 URL 매핑을 기술한다.
web.xml
<servlet>
   <servlet-name>hello</servlet-name>  <!-- DD 안에서 사용될 이름을 지정한다. -->
   <servlet-class>com.oracleclub.study.servlet.HelloServlet</servlet-class>  <!-- Servlet 클래스 이름을 기술한다. -->
</servlet>

<servlet-mapping>
   <servlet-name>hello</servlet-name>        <!-- Servlet 클래스의 DD안에서 정의한 이름 -->
   <url-pattern>/servlet/hello</url-pattern>  <!-- 클라이언트가 요청하게 될 이름. -->
</servlet-mapping>
  • 배포서술자에서 서블릿 관련 항목을 간단히 설명하면 아래와 같다.
    • <servlet> : <servlet-name>과 <servlet-class>를 연결 한다.
    • <servlet-name> : DD 안에서 사용될 이름
    • <servlet-class> : 자바 클래스 이름
    • <url-pattern> : 클라이언트가 요청하게 될 이름
    • <servlet-mapping> : <servlet-name>과 <url-pattern>을 연결 한다.

2.3 Tomcat 연동 하기

  • 톰캣 다운로드 클릭 후 압축해제 한다.
  • 배포서술자까지 작성이 완료되었다면 톰캣을 연동하여 실행해 보자
  • 이클립스 <Servers>에서 <New>→<Server>를 실행한다.
  • <그림2-3>과 같이 <Tomcatv6.0 Server>를 선택한 후 <Server name> 을 web-project로 입력한다.
  • <Server runtime environment> 가 설정되어 있지 않다면 <Add> 버튼을 클릭하여 압축해제 한 Tomcat 디렉토리를 선택한다.
  • 강의에서는 Tomcat 6.x 버전을 기준으로 하였으며, 개인의 버전에 맞추어서 선택하면 된다.
  • Next 버튼을 클릭하고 위와 같이 spring-project를 [STUDY:Add]한 후 Finish 버튼을 클릭한다.

2.4 서블릿 실행

2.5 Apache+Tomcat연동 후 서블릿 실행

  • 정상적으로 호출이 된다면 Apache와 연동을 해보자. 좀 전에 테스트한 http-vhost.conf 파일의 DocumentRoot를 spring-project의 webapps 디렉토리로 변경하고 Apache를 restart하면 된다.
  • JkMount 설정에 /servlet/ 디렉토리도 추가해 주자
http-vhost.conf 파일 설정
<VirtualHost *:80>
    ServerName test.apache.org
    DocumentRoot C:\workspace\project\spring-project\webapps 
 
# URL중 jsp로 오는 Request만 Tomcat에서 처리 함
JkMount  /*.jsp  spring-project 

# 아래의 spring-project는 workers.properties에서 등록한 worker이름 이다.
# servlet 예제 실행을 위해서 추가
JkMount  /servlet/*  spring-project
</VirtualHost> 

2.6 URL과 Servlet을 간단하게 매핑하기

  • 위 예제에서 간단하게 HelloServlet을 실행하였는데, 만약 서블릿 클래스가 굉장히 많아 진다면, <servlet> , <servlet-mapping> 설정이 서블릿의 두 배만큼 많아 질 것이다.
  • 톰캣에서는 서블릿 매핑 설정을 간단하게 할 수 있는 기능을 제공하며, 톰캣 서버의 web.xml(이클립스에서는 <Servers> <spring-project-config>의 web.xml) 에서 아래 부분의 주석만 해제하면 된다.
web.xml 파일 설정
<!-- 122라인 -->
<servlet>
      <servlet-name>invoker</servlet-name>
      <servlet-class>
        org.apache.catalina.servlets.InvokerServlet
      </servlet-class>
      <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
      </init-param>
      <load-on-startup>2</load-on-startup>
  </servlet>

<!-- 382라인 -->
  <servlet-mapping>
      <servlet-name>invoker</servlet-name>
      <url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>
  • Tomcat Server의 web.xml 수정 후 이클립스를 다시 실행한다.
  • spring-project의 web.xml 에서 아래와 같이 servlet 이름만 지정하고 <servlet-mapping> 설정은 제거한다.
web.xml
<servlet>
   <servlet-name>hello</servlet-name>  <!-- DD 안에서 사용될 이름을 지정한다. -->
   <servlet-class>com.oracleclub.study.servlet.HelloServlet</servlet-class>  <!-- Servlet 클래스 이름을 기술한다. -->
</servlet>
  • Tomcat Server를 재시작 한 후 http://test.apache.org/servlet/hello URL로 접속하여 정상 접속이 되는지 확인해보자
  • Invoker를 이용한 매핑의 경우 클라이언트 URL은 /servlet/servlet-name 이 된다.

3. 톰캣 startup 시 오류

3.1 404 Not Found 오류

  • <Server> → <spring-project> → <Web Moduls>에서 Path가 아래와 같이 공백으로 되어 있는지 확인한다.

3.2 java.lang.SecurityException

  • 톰캣이 startup시 "Caused by: java.lang.SecurityException: Servlet of class org.apache.catalina.servlets.InvokerServlet is privileged and cannot be loaded by this web application" 에러가 발생한다면 Tomcat Server의 server.xml 파일에서 <Context> 태그에 privileged="true" 옵션을 추가하면 된다.

3.3 java.lang.ClassNotFoundException

  • 톰캣이 startup시 "java.lang.ClassNotFoundException" 오류가 발생하면 .classpath의 MAVEN2_CLASSPATH_CONTAINER 부분을 확인한다.
  • 아래와 같이 attributes의 /WEB-INF/lib 폴더를 추가한다.
  • Project Clean, Tomcat Clean 한 후 다시 start 해보자
.classpath의 MAVEN2_CLASSPATH_CONTAINER 설정
    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER" >
       <attributes>
            <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
        </attributes>
    </classpathentry>

-- STS 버전
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
	    <attributes>
            <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
        </attributes>
	</classpathentry>
  • <Project> → <Clean>
  • <Server> → <Clean>

문서정보