JSP와 Servlet

심야·2023년 7월 14일
0

웹 개발

목록 보기
31/46
post-custom-banner

JSP (Java Server Page)

HTML 코드에 JAVA Code를 넣어 동적인 웹 페이지를 생성하는 웹 어플리케이션 도구이다.

View (프레젠테이션) 요소가 있어 HTML 코드를 작성하기 수월하다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
</body>
</html>

JSP 구성 요소

<%@ page %> - Page 지시자
<%@ include %> - Include 지시자
<%@ taglib %> - taglib 지시자 
<% Java Code %> - 스크립트 릿 (순수한 Java Code)
<%= Java Code %> - 출력식 (Java의 출력 값을 작성)
<%! Java Code %> - 선언문 (메서드 선언 시 사용)
<%-- JSP 주석 --%> - JSP 주

JSP 동작 원리

  1. 클라이언트는 WAS (Tomcat)에게 http://127.0.0.1:8080/MVC02/test01.jsp 파일을 요청한다.
  2. Tomcat은 test01.jsp 파일을 찾아 Java Code가 존재하는 <% %> 부분을 해석 후 렌더링한다.
  3. 클라이언트에게 렌더링 된 페이지를 응답한다.

JSP는 곧 Servlet이다.

  1. 클라이언트는 WAS (Tomcat)에게 http://127.0.0.1:8080/MVC02/test01.jsp 파일을 요청한다.
  2. JSP 파일은 Servlet 으로 변환되어 아래 그림에서 보듯이 Java 파일과 Class 파일이 생성된다.
  3. 컴파일한 Class 파일을 WAS의 메모리에 올려 Servlet 객체를 만든다.
  4. 메모리에 로드될 때 Servlet 객체를 초기화하는 init() 메서드가 실행된다.
  5. WAS는 Request가 올 때마다 thread를 생성하여 처리한다.
  6. 각 thread는 Servlet의 단일 객체에 대한 service() 메서드를 실행한다.
  7. service() 메서드는 요청에 맞는 적절한 메서드(doGet, doPost 등)를 호출한다.
  8. 수행 완료 후 생성된 데이터를 웹 페이지와 함께 클라이언트로 응답한다.

변환된 Java 파일과 Class 파일 경로

.SmartTomcat\MVC-02\MVC-02\work\Catalina\localhost\MVC-02\org\apache\jsp\

JSP → Servlet 변환 과정 이해

WAS는 JSP를 Servlet으로 변환시킨다. 브라우저에는 변환된 코드가 출력된다.

그렇다면 어떻게 코드가 변경됬는지 알아보자.

아래 코드는 내가 예측해 본 Servlet 코드와 WAS가 변환한 코드이다.

완벽하게 똑같지는 않지만 JSP의 핵심 코드가 예측한 대로 변환되었다.

내가 예측해 본 JSP → Servlet 코드

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class test01_jsp extends HttpServlet {
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExceoption {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		// JSP 주석	
		int sum = 0;
    		for(int i = 1; i <= 10; i++)
    		{
        		sum += i;
    		}
		
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		...
		out.println("<p>1 ~ 10까지의 합" + sum + "</p>");
		out.println("<p>55 ~ 350까지의 합" + sum(55, 350) + "</p>");
	}

	public int sum(int k, int j){
        int sum = 0;
        for(int i = k; i <= j; i++)
        {
            sum += i;
        }
        return sum;
    	}
}

실제로 WAS (Tomcat)이 변환한 Servlet 코드

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.68
 * Generated at: 2023-03-30 04:55:58 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class test01_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

    // 메서드 선언문
    public int sum(int k, int j){
        int sum = 0;
        for(int i = k; i <= j; i++)
        {
            sum += i;
        }
        return sum;
    }

  ...

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP들은 오직 GET, POST 또는 HEAD 메소드만을 허용합니다. Jasper는 OPTIONS 메소드 또한 허용합니다.");
        return;
      }
    }

		
    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      // 내장 객체
			_jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write('\r');
      out.write('\n');
      out.write('\r');
      out.write('\n');
      out.write('\r');
      out.write('\n');

    // 순수한 JAVA Code
    int sum = 0;
    for(int i = 1; i <= 10; i++)
    {
        sum += i;
    }

      out.write("\r\n");
      out.write("<!DOCTYPE html>\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta charset=\"UTF-8\">\r\n");
      out.write("<title>title</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("<h2>JSP</h2>\r\n");
      out.write("</dr>\r\n");
      out.write("1 ~ 10까지의 합 ");
      out.print( sum );
      out.write(" </dr>\r\n");
      out.write("55 ~ 350까지의 합 ");
      out.print( sum(55, 350) );
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    }

출처

https://gmlwjd9405.github.io/2018/11/03/jsp.html

profile
하루하루 성실하게, 인생 전체는 되는대로.
post-custom-banner

0개의 댓글