다양한 관심 :)

java - servlet (서블릿 ) 동작방식 본문

프로그래밍 공부/JAVA

java - servlet (서블릿 ) 동작방식

뚜뚜:) 2020. 11. 27. 11:07

서블릿의 기본적인 동작방식

 

 

서블릿의 동작방식

    1. 사용자(클라이언트)가 URL을 클릭하면 HTTPRequest를 Servlet Container로 전송(요청)한다.

    2. 컨테이너 web.xml에 정의된 url패턴을 확인하여 어느 서블릿을 통해서 처리해야할 지를 검색

       (로딩이 안된 경우 로딩을 하며 이때 init() 메서드가 호출된다)

       ( Servlet버전 3.0 이상에서는 어노테이션(@WebServlet)으로 url패턴을 설정할 수 있다.

    3. Servlet Container는 요청을 처리할 개별 쓰레드 객체를 생성하여 해당 서블릿 객체의 Service()메서드를 호출

        ( 이 때, HttpServletRequest 객체와 HttpServletResponse 객체를 파라미터로 넘겨준다)

               => 자동으로  파라미터를 넘겨준다.

    4. service() 메서드는 요청 메서드 타입을 체크하여 적절한 메서드를 호출한다.

         (doGet(), doPost(), doPut(), doDelete() 등...) => 실질적으로는 doGet, doPost로 처리한다

    5. 요청 처리가 완료 되면 HttpServletRequest객체와 HttpServletResponse객체는 자동으로 소멸된다.

    6. 컨테이너로부터 서블릿이 제거되는 경우에는 destroy() 메서드가 호출된다.

       -> 예제에서 destory()는 소스를 수정하거나 변경하면 재부팅 되어 실행된다.

 

 

더보기

* 가장 중요한 것은 get방식과 post방식의 요청 차이점을 구분하는것

  • Get : 데이터를 Header(헤더)에 포함하여 전송하고, URL에 데이터가 노출되어 보안에 취약

  • post : URL에 변수(데이터)를 노출하지 않고 요청, 데이터를 Body(바디)에 포함시킨다.
     (URL에 데이터가 노출되지 않아서 보안이 된다.)

* 가장 중요한 것은 get방식과 post방식의 요청 차이점을 구분하는것

  • Get : 데이터를 Header(헤더)에 포함하여 전송하고, URL에 데이터가 노출되어 보안에 취약

  • post : URL에 변수(데이터)를 노출하지 않고 요청, 데이터를 Body(바디)에 포함시킨다.
     (URL에 데이터가 노출되지 않아서 보안이 된다.)

 

get방식과 post방식에 맞는 메서드 호출 할 때  방법 2가지

        (service는 mvc패턴을 할 대 소스를 적합하게 작성하는것이 효율적이다) 

 

1. HttpServlet의 service() 메서드로 위임 하는 방법 : super(객체의 부모지칭) 사용

    ( 간단한 작업의 경우는 1번 방식을 사용하는 것이 효율적 )

2. 클라이언트의 전송방식 (get, post 등)을 구분해서 직접 메서드를 호출

 

  //req = HttpServletRequest req 
    
String method = req.getMethod();
	if("GET".equals(method)) {
		this.doGet(req, resp);
	}else {
		this.doPost(req, resp);
	}
    
  

 

 

5가지의 메서드를 다 사용하는 예제 

@WebServlet("/servletTest03.do")
public class ServletTest03 extends HttpServlet{
	
	private static final long SerialVersionUID = 1L;
	

	@Override
	public void init() throws ServletException {
		System.out.println("Servlet : " + this.getServletName() + "에서 init()메서드를 호출합니다.");
	}
	
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("Service() 메서드 시작...");
		
		super.service(req, resp);	
		
	}
	

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doGet() 메서드 시작 ...");
		resp.setCharacterEncoding("utf-8");
		resp.setContentType("text/html; charset=utf-8");
		
		PrintWriter out = resp.getWriter();
		out.println("<html><head><meat charset-='utf-8'></head>"
				+ "<body><h1>doGet()메서드 처리 내용</h1></body></html>");
	
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doPost() 메서드 시작 ...");
		resp.setCharacterEncoding("utf-8");
		resp.setContentType("text/html; charset=utf-8");
		
		PrintWriter out = resp.getWriter();
		out.println("<html><head><meat charset-='utf-8'></head>"
				+ "<body><h1>doPost()메서드 처리 내용</h1></body></html>");
	
	}
	
	@Override
	public void destroy() {
		System.out.println("SerVlet : " + this.getServletName() + "에서 destroy()메서드를 호출합니다.");
	}

 

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Servlet 요청 연습</h1>
	<hr>
	<!-- 	웹 브라우저의 URL주소창에 직접 입력하여 요청하는 경우에도  GET방식으로 처리된다. -->
	<h2>Get방식 요청 1 ==> 링크 방식 </h2>
	<a href="http://Localhost/servletTest/servletTest03.do">Get방식 요청 1</a>
	<hr>
	
	<h2>Get방식 요청 2 ==> form태그의 method속성을 생략하거나 'get'으로 설정한 경우 </h2>
	<form action="http://Localhost/servletTest/servletTest03.do" method="">
		<input type="submit" value="Get방식 요청2">
	</form>
	<hr>
	
	<h2>POST 방식 요청 ==> form태그의 method속성에 'post'로 설정한 경우 </h2>
	<form action="http://Localhost/servletTest/servletTest03.do" method="post">
		<input type="submit" value="post방식 요청">
	</form>
	

</body>
</html>

 

 

 

처리 과정 
init 메서드가 끝나면 서비스로 자동 호출 -> 메서드 시작 호출됨 ->  
서비스가 실행되면서 super를 만나 위임을 하게 되어 작업을 처리해준다

-> get방식이므로 doget의 메서드가 시작된다 .  (method ="post"로 변경시 post방식으로 doPost메서드가 시작 )