본문 바로가기

Servlet

[Servlet]Servlet의 주요 클래스와 실제 웹페이지 제작

Servlet의 주요 클래스

  • HttpServlet
    • 서블릿을 만들기 위해 반드시 상속해야 할 필수 클래스
    • 존재 목적 자체가 서블릿을 생성하기 위해 제공된다.
    • Servlet(Interface) - GenericServlet(abstract class) - HttpServlet의 상속구도를 갖는다.
    • Init(), service(), destroy() :  서블릿의 생명주기를 담당하는 메서드는 Servlet Interface에 정의되어있다.
    • doGet(), doPost()등 :  브라우저의 서블릿 호출방식의 요청 처리를 위한 메서드로 HttpServlet클래스에 정의되어있다.
  • HttpServletRequest
    • 클라이언트가 데이터를 입력하거나 또는 클라이언트의 정보에 대한 요청 값을 가지고 있는 클래스이다.
    • getParameterXXX(name) :  name에 할당된 값을 배열 또는 원소로 받을 수 있다.
    • setCharacterEncoding(evn) : post 방식으로 요청된 문자열의 인코딩 처리를 위한 메서드.
  • HttpServletResponse
    • 클라이언트가 요청한 정보를 처리하고 다시 응답하기 위한 정보를 담고 있는 클래스
    • setHeader(), setContentType(), getCharacterEncoding(), sendRedirect()등 응답에 포함될 Header와 출력되는 페이지의 콘텐츠타입 그리고 지정된 URL로 재전송을 담당하는 메서드가 제공된다.
  • HttpSession
    • 클라이언트가 세션에 정보를 저장하고 기능을 유지하기 위해서 제공되는 클래스
    • 세션에 관련된 정보를 얻어오는 메서드와, 세션 값을 설정하는 메서드가 제공된다.

Servlet 클래스의 상속구조 및 동작방식

  • 클라이언트의 첫 요청시 Servlet 인터페이스에 정의된 생명주기에 의해 init()메서드가 호출되어  Servlet이 메모리에 올라가고,  Service()메서드를 호출한다.
  • Service()메서드에서는 요청 형식에 따라 doGet(), doPost()등의 메서드를 호출하여 비지니스 로직을 처리한 뒤 결과를 반환한다.

Servlet의 Mapping 방식

  • 서블릿 실행을 위해서는 브라우저에서 url상에 표시되는 서블릿의 가상의 이름을 설정해야한다.
  • 서블릿 맵핑을 만드는 이유는 클래스 이름으로 실행하기 위한 이름은 너무 길고 보안에 노출되어 있는 경로를 간단하게 표시하기 위해서이다.
  • 서블릿 맵핑 방식은 web.xml에서 설정하는 방식과 @WebServlet annotaion으로 설정하는 방법이 제공된다.

web.xml(배치기술자)

  • Deployment Descriptor(환경 파일)로 XML 형식을 갖는다.
  • 주로 WEB-INF 폴더 밑에 저장되며, Servlet/JSP에 대한 정의, Servlet/JSP 매핑, Mime Type 매핑, Error Pages 처리 등 많은 환경에 대한 설정들이 저장되는 파일이다.
  • 즉 웹 어플리케이션을 Servlet/JSP 컨테이너에 배치해서 사용하기 위한 내용을 기술한 파일이다.
  • 하나의 웹 어플리케이션에 대한 배치를 기술하기 위한 것이기 떄문에 각각의 웹 어플리케이션마다 하나의 배치기술자가 필요하다.
  • 웹 어플리케이션 실행시에 필요한 기본적인 내용들을 웹 컨테이너가 인식할 수 있도록 하는 내용들이 담겨있다.

Servlet 프로그램 만들기

1. Annotation을 사용한 방법

  1. HttpServlet 클래스를 상속받는다.
  2. @WebServlet Annotaion을 사용해 urlPatterns 속성에 클라이언트가 해당 Servlet을 요청하기 위한 URL을 지정한다.
  3. service()메서드의 HttpServletResponse 객체로부터 PrintWriter 객체를 얻어온 뒤, HTML을 작성한다.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

//어노테이션을 통한 매핑
@WebServlet(name = "myServlet1", urlPatterns = {"/myServlet1"})
public class MyServlet1 extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		resp.setCharacterEncoding("UTF-8");
		PrintWriter writer = resp.getWriter();
		writer.println("<html>");
		writer.println("<head>");
		writer.println("<title>MyServlet1</title>");
		writer.println("</head>");
		writer.println("<body>");
		writer.println("<h1>MyServlet Test1</h1>");
		writer.println("</body>");
		writer.println("</html>");
	}
	
}

2. Web.xml을 사용한 방법

  1. HttpServlet 클래스를 상속받는다.
  2. web.xml파일에 태그를 통해 해당 Servlet의 매핑방식을 지정한다.
    1. <servlet>태그의 servlet-class태그를 통해 해당 servlet의 위치가 어디지인지 명세하고, servlet-name을 통해 명세한 servlet의 이름을 지정한다.
    2. <servlet-mapping>태그의 url-pattehrn태그를 통해 해당 servlet의 요청 URL을 지정하고, servlet-name을 통해 URL에 매칭될 servlet 클래스의 이름을 명세한다.
  3. service()메서드의 HttpServletResponse 객체로부터 PrintWriter 객체를 얻어온 뒤, HTML을 작성한다.

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


//web.xml을 통한 매핑
//@WebServlet(name = "myServlet2", urlPatterns = { "/myServlet2" })
public class MyServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	resp.setContentType("text/html");
    	resp.setCharacterEncoding("UTF-8");
    	
    	PrintWriter writer = resp.getWriter();
		writer.println("<html>");
		writer.println("<head>");
		writer.println("<title>MyServlet2</title>");
		writer.println("</head>");
		writer.println("<body>");
		writer.println("<h1>MyServlet Test2</h1>");
		writer.println("</body>");
		writer.println("</html>");
    }

}

결과화면

Servlet의 Life Cycle

  • 앞서 이론적으로 다루었은 Life Cycle이 실제로 그렇게 동작하나 확인하기 위한 Servlet 클래스를 만들고 실행시켜보자
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/ServletLifeCycle")
public class ServletLifeCycle extends HttpServlet {
	private static final long serialVersionUID = 1L;


	public void init(ServletConfig config) throws ServletException {
		System.out.println("init() 실행");
		
	}


	public void destroy() {
		System.out.println("destroy() 실행");
	}


	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("service() 실행");
	}


}

1. Servlet에 Mapping된 URL을 통해 Servlet 호출

2. 첫 호출시 init(), service() 메서드가 실행된다.

3. 이후 반복되는 Servlet 호출에 대해서는 service()메서드만 호출된다.

  • 이후 웹 어플리케이션의 종료 또는 재컴파일시 destory()메서드가 호출되어 메모리를 관리하게된다.
  • 또한 service()메서드에서는 HTTP의 Request의 Method의 타입에 따라 doGet(), doPost()를 호출하기도 한다.

 

Servlet의 요청방식 - GET, POST

  • 브라우저에서 페이지 간 통신을 할 수 있는 대표적인 방법은 HTML의 form 태그에서 제공되는 Method의 방식에 따르는 방법이다. 즉 form 태그의 Method는 HTTP의 메서드를 의미하며, 대표적으로 GET방식과 POST방식이 있다.
  • Get : URL에 Form에서 넘겨지는 정보를 queryString으로 전달하는 방식이다. 일반적으로 검색이나 조건을 다른 페이지로 전송할 때 사용하며, url에 노출이 되는 특징이 있어 보안적으로 중요하지 않은 정보를 페이지간 주고받을 때 사용된다.
  • Post : HTML헤더에 요청 정보와 같이 전달되며, Get방식과 달리 URL상에 전송되는 데이터가 노출되지 않고 html헤더 값에 같이 전송되는 방법으로 보안에 유리하다.
  • Get, Post의 한글처리 : get방식은 요청정보 헤더의 URI에, POST 방식은 요청정보의 몸체에 포함되어 데이터가 전달되므로 get방식은 URI에 대한 인코딩 처리 작업을 해야한다. 반면 POST 방식은 HttpServletRequest의 상위 객체인 ServletRequest에서 제공하는 setCharacterSet()메서드를 통해 인코딩 타입의 설정이 가능하다.

1. GET, POST 방식의 차이를 보기위한 Servlet 클래스 작성

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/myServlet3")
public class MyServlet3 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html");
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();
		writer.println("<html>");
		writer.println("<head>");
		writer.println("<title>MyServlet1</title>");
		writer.println("</head>");
		writer.println("<body>");
		writer.println("<h1>doGet</h1>");
		writer.println("<div>"+request.getParameter("id")+"</div>");
		writer.println("<div>"+request.getParameter("pw")+"</div>");
		writer.println("</body>");
		writer.println("</html>");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html");
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();
		writer.println("<html>");
		writer.println("<head>");
		writer.println("<title>MyServlet1</title>");
		writer.println("</head>");
		writer.println("<body>");
		writer.println("<h1>doPost</h1>");
		writer.println("<div>"+request.getParameter("id")+"</div>");
		writer.println("<div>"+request.getParameter("pw")+"</div>");
		writer.println("</body>");
		writer.println("</html>");
	}

}

3. 요청을 위한 HTML 페이지 작성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Page</title>
<style>
	fieldset {
		border : 1px solid black;
		width: 250px;
	}
	hr {
		margin: 20px 0;
	}
</style>
</head>
<body>

	<% String strName = "방문자"; %>
	<h1>Hello <%= strName %></h1>
	
	<form action="myServlet3" method="get">
		<fieldset>
			<legend>get 로그인</legend>
			<div>id : <input type="text" name="id"></div>	
			<div>pw : <input type="password" name="pw"></div>	
			<div><input type="submit" value="log-in"></div>	
		</fieldset>
	</form>
	<hr>
	<form action="myServlet3" method="post">
		<fieldset>
			<legend>post 로그인</legend>
			<div>id : <input type="text" name="id"></div>	
			<div>pw : <input type="password" name="pw"></div>	
			<div><input type="submit" value="log-in"></div>	
		</fieldset>
	</form>
	
</body>
</html>

4. 작성한 HTML을 통해 요청보내기

5. GET와 POST방식의 차이점 비교하기

  • GET방식을 이용한 데이터 전송시 Servlet의 URL에 ?id=&pw=의 형태로 queryString이 그대로 노출된다.
  • 반면 POST방식을 이용한 데이터 전송시 Servlet의 URL에 노출이 되지 않으나, 성공적으로 데이터를 받아올 수 있다.

 

Servlet에서 세션 사용하기

  • 세션 :  HTTP 프로토콜의 무상태성의 단점을 보완하기 위해 사용되며, 클라이언트(브라우저)와 서버(톰켓 등)와 통신의 연속성을 유지하기 위해 사용되는 기술이다.
  • HttpServletRequest로부터 session을 얻어와 사용하면 된다.

 

'Servlet' 카테고리의 다른 글

[Servlet] Servlet과 Container의 개념  (0) 2023.03.14