본문 바로가기
WEB/Servlet, JSP

[Servlet] 서블릿 기본 개념과 요청/응답 처리

by Amy IT 2022. 7. 9.

 

 

목차

     

     

    서블릿 (Servlet) 이란?

    서블릿은 자바 기반의 웹 서버 애플리케이션 기술로서, 웹 페이지를 동적으로 생성하는 웹 컴포넌트입니다. 

     

    서블릿 특징

    • 자바 기반의 웹 컴포넌트로서 java 확장자를 갖습니다.
    • 클라이언트의 요청에 의해서 동적으로 실행됩니다. 따라서 다양한 클라이언트 요구 사항을 처리할 수 있습니다.
    • 서블릿은 웹 컨테이너에 의해서 관리되며 , 스레드로 동작되어 효율적인 요청처리가 가능합니다.
    • MVC 패턴의 Controller 역할로서 서블릿이 사용됩니다.
    • 서블릿 하나는 하나의 클래스로서, javax.servlet.http.HttpServlet 클래스를 상속 받아 구현해야 합니다. HttpServlet에는 웹상에서 클라이언트 요청이 있을 때 해당 서블릿을 실행하는 모든 조건이 포함되어 있습니다.

     

    서블릿 컨테이너 (Container)

    • 컨테이너는 웹 컴포넌트를 저장하는 저장소 역할, 메모리 로딩, 객체 생성 및 초기화 등 서블릿의 생명주기를 관리하고 JSP를 서블릿으로 변환하는 기능을 수행하는 프로그램입니다.
    • 서블릿 컨테이너는 서블릿 컴포넌트를 실행하는 환경을 제공합니다.
    • 클라이언트의 HTTP 요청을 서블릿에 전달하고, 서블릿의 HTTP 응답 결과를 클라이언트에 돌려줍니다.
    • 서블릿 엔진이라고도 합니다.

     

     

     

    서블릿 실행

    서블릿 실행 순서와 서블릿 라이프 사이클 (Life Cycle)

    이미지 출처 https://coding-factory.tistory.com/742

     

    1. 클라이언트의 요청 : 클라이언트가 웹 브라우저에서 서비스를 요청합니다. 이때 HTTP 프로토콜 기반으로 요청 정보가 만들어져 웹 서버에 전달됩니다.
    2. 웹 서버는 클라이언트로부터 전달받은 요청 정보의 URI를 보고 서블릿인 경우 서블릿 컨테이너에 처리를 넘깁니다.
    3. 서블릿 컨테이너는 요청할 서블릿 클래스 파일을 찾아서 실행합니다.
    4. 최초의 요청 여부 판단 : 서블릿 컨테이너는 현재 실행할 서블릿이 최초의 요청인지 판단합니다. 실행할 서블릿 객체가 메모리에 없으면 최초의 요청이고, 이미 있으면 최초의 요청이 아닌 것으로 판단합니다.
    5. 서블릿 객체 생성 : 최초의 요청일 경우 해당 서블릿을 메모리에 로딩하고 객체를 생성합니다. 서블릿 객체가 메모리에 생성되는 시점은 서버 입장에서 클라이언트로부터 최초로 서블릿 실행 요청이 있을 때입니다. 
    6. init() 메소드 실행 : init()은 서블릿 객체가 생성된 다음에 호출되는 메소드로서, 주로 서블릿 객체의 초기화 작업을 구현합니다.
    7. 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성합니다.
    8. service() 메소드 실행 : service()는 클라이언트의 요청이 있을 때마다 실행되는 메소드로서, HttpServletRequest, HttpServletResponse 객체를 인자로 전달받아 실제 서블릿에서 처리해야 하는 내용을 구현합니다. 요청이 있을 때마다 생성되어 있는 서블릿 객체를 재사용합니다.
    9. 클라이언트에 응답 : 서버 프로그램이 실행 완료된 후 서블릿 컨테이너가 실행 결과를 웹 서버에 전달하고, 웹 서버는 서비스를 요청한 클라이언트에 응답합니다. 이로써 웹에서 하나의 요청에 대한 처리가 완료되고 HttpServletRequest, HttpServletResponse 객체는 소멸합니다.
    10. 서블릿 객체 소멸 : 서블릿 객체가 소멸하는 시점은 서버를 중지시켜 웹 애플리케이션 서비스를 중지할 때입니다. 이때 destroy() 메소드가 호출되어 실행됩니다.

     

    서블릿 매핑

    (1) web.xml 파일에 등록

    WEB INF/web.xml 파일에 다음과 같이 <servlet> 과 <servlet mapping> 태그를 사용하여 설정 가능합니다.

    <servlet>
        <servlet-name>서블릿별명</servlet-name>
        <servlet-class>패키지명.서블릿명</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>서블릿별명</servlet-name>
        <url-pattern>/매핑주소</url-pattern>
    </servlet-mapping>

     

    (2) @WebServlet 어노테이션 이용

    어노테이션은 JDK 5.X 부터 추가된 기능으로서 자바 코드에 직접 설정 가능합니다.

    @WebServlet("/매핑주소")

     

     

     

    서블릿 요청 처리

    ServletRequest의 주요 메소드

    함수 기능
    void setCharacterEncoding(String env) 클라이언트가 요청정보 몸체에 포함해서 보내는 문자열들을 지정된 문자셋을 이용해 인코딩해 준다.
    String getParameter(String name) 클라이언트가 보낸 질의 문자열 중에서 name과 일치하는 것을 찾아 name의 value를 반환한다.
    String[] getParameterValues(String name) 클라이언트가 보낸 질의 문자열 중에서 name과 일치하는 모든 값을 찾아 name의 value들을 String 타입 배열로 반환한다. ex) checkbox, radio 타입
    Enumeration<String> getParameterNames() 클라이언트가 보낸 질의 문자열의 모든 name 값을 Enumeration 객체에 담아 반환한다.
    Map<String, String[]> getParameterMap() 클라이언트가 보낸 질의 문자열을 Map 타입에 name, value의 형태로 담아 반환한다.
    void setAttribute(String name, Object o) ServletRequest 객체 안에 데이터를 저장한다.
    Object getAttribute(String name) ServletRequest 객체 안에 등록된 데이터를 추출하여 반환한다.
    void removeAttribute(String name) ServletRequest 객체에 setAttribute 메소드를 이용해 등록한 데이터를 삭제한다.
    ServletContext getServletContext() 서버가 시작될 때 웹 애플리케이션 단위로 생성된 ServletContext 객체의 주소를 추출하여 반환한다.
    RequestDispatcher getRequestDispatcher(String path) 다른 리소스로 ServletRequest 객체를 포워드(forward)할 수 있는 RequestDispatcher 객체를 생성하여 반환한다.

     

    HttpServletRequest에서 추가된 주요 메소드

    함수 기능
    HttpSession getSession() 서비스를 요청한 클라이언트가 사용하는 HttpSession 객체를 반환한다. 만일 반환할 HttpSession 객체가 없으면 새로 생성하여 반환한다.
    HttpSession getSession(boolean create) 서비스를 요청한 클라이언트가 사용하는 HttpSession 객체를 반환한다. 만일 반환할 HttpSession 객체가 없으면 true로 설정한 경우 새로 생성하여 반환하고, false로 설정한 경우 생성하지 않고 null을 반환한다.
    String getQueryString() 클라이언트가 GET 방식으로 서버에 보낸 질의 문자열들을 모두 추출하여 반환한다.

     

     

     

    서블릿 응답 처리

    ServletResponse의 주요 메소드

    함수 기능
    void setContentType(String type) 응답정보의 데이터 형식(MIME 타입)을 설정한다.
    PrinterWriter getWriter() 서비스를 요청한 클라이언트와 서버 간에 연결된 PrintWriter 객체를 생성하여 반환한다.

     

    HttpServletResponse에서 추가된 주요 메소드

    함수 기능
    void sendRedirect(String location) 클라이언트가 요청한 URL이 아니라 지정한 URL로 응답을 재전송한다.

     

     

     

    서블릿 예제

    String getParameter(String name)

    <!-- loginForm.html -->
    <h1>로그인폼</h1>
    <form action="LoginServlet" method="post">
    	아이디:<input type="text" name="userid"><br>
    	비밀번호:<input type="text" name="passwd"><br>
    	<input type="submit" value="로그인">
    </form>
    @WebServlet("/LoginServlet")
    public class LoginServlet extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		//요청처리 
    		request.setCharacterEncoding("utf-8");
    		//form 데이터 파싱
    		String userid = request.getParameter("userid");
    		String passwd = request.getParameter("passwd");
    		
    		//응답처리 
    		response.setContentType("text/html;charset=UTF-8");
    		PrintWriter out = response.getWriter();
    		out.print("<html><body>");
    		out.print("이름은:"+userid+"<br>비밀번호는:"+passwd);
    		out.print("</body></html>");
    	}
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }

     

    String[] getParameterValues(String name)

    <!-- form.html -->
    <h1>폼 실습</h1>
    <h3>좋아하는 과일 선택</h3>
    <form action="TestServlet" method="get">
    	사과:<input type="checkbox" name="fruit" value="apple"><br>
    	바나나:<input type="checkbox" name="fruit" value="banana"><br>
    	수박:<input type="checkbox" name="fruit" value="watermelon"><br>
    	<input type="submit" value="전송">
    </form>
    @WebServlet("/TestServlet")
    public class TestServlet extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		request.setCharacterEncoding("utf-8");
    		String[] fruits = request.getParameterValues("fruit");
    		
    		response.setContentType("text/html; charset=utf-8");
    		PrintWriter out = response.getWriter();
    		out.print("<html><body>");
    		String mesg = "";
    		for (String s : fruits) {
    			mesg += s+" ";
    		}
    		out.print(mesg);
    		out.print("</body></html>");
    	}
    }

     

    Enumeration<String> getParameterNames()

    <!-- loginForm.html -->
    <h1>로그인폼</h1>
    <form action="LoginServlet" method="post">
    	아이디:<input type="text" name="userid"><br>
    	비밀번호:<input type="text" name="passwd"><br>
    	<input type="submit" value="로그인">
    </form>
    @WebServlet("/LoginServlet")
    public class LoginServlet extends HttpServlet {
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		request.setCharacterEncoding("utf-8");
    		//키값만 Enumeration에 담아서 keys 변수에 저장 
    		Enumeration<String> keys = request.getParameterNames();
    		
    		response.setContentType("text/html; charset=utf-8");
    		PrintWriter out = response.getWriter();
    		out.print("<html><body>");
    		while (keys.hasMoreElements()) {
    			String key = keys.nextElement(); //key 하나씩 뽑아옴
    			String value = request.getParameter(key); //각 key에 해당하는 value 뽑아옴
    			out.print(key+": "+value+"<br>");
    		}
    		out.print("</body></html>");
    	}
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }

     

     

     

    참고

    처음 해보는 Servlet&JSP 웹 프로그래밍 (오정임 지음, 루비페이퍼)

     

     

    댓글