본문 바로가기
Record/boostcourse

[boostcourse] 2. 웹 백엔드 프로그래밍 기초 생각해보기 #3 ~ #4

by doongjun 2021. 7. 21.

#3 Servlet

 

1) 동적인 페이지가 필요한 경우는 어떤 것일까요?

동적인 페이지가 필요한 경우는 많지만

입출력이 이루어질때마다 페이지의 구성요소를 다르게 보여줘야하는 경우에 더욱 필요하다고 생각한다.

 

2) HelloServlet 클래스 파일을 작성할 때 HttpServlet을 상속하지 않았다면 어떻게 동작할까요?
package examples;

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("/HelloServlet")
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public HelloServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//응답 형식
		response.setContentType("text/html;charset=UTF-8");
		//클라이언트와 연결통로
		PrintWriter out = response.getWriter();
		out.print("<h1>Hello Servlet</h1>");
	}

}

HttpServlet을 상속하지 않았다면

WAS와 연결점이 사라져 정상적인 웹 애플리케이션의 서블릿 역할을 하지 못하게 될 것이다.


#4 JSP

 

1) 1부터 10까지의 합을 구하는 Servlet과 JSP를 비교해봤을 때 JSP가 어떤 부분에서 편리한가요?

Sum10.java

package examples;

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("/sum")
public class Sum10 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public Sum10() {
        super();
        // TODO Auto-generated constructor stub
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		
		int total = 0;
		for(int i=1; i<=10; i++) {
			total += i;
		}
		
		out.println("<html>");
		out.println("<head><title>sum10</title></head>");
		out.println("<body>");
		out.println("1부터 10까지 합 : ");
		out.println(total);
		out.println("</body>");
		out.println("</html>");
	}

}

sum10.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		int total = 0;
		for(int i=1; i<=10; i++){
			total += i;
		}
	%>
1부터 10까지의 합 : <%=total%>
</body>
</html>

서블릿의 경우 태그들을 한줄한줄 print해줘야하는 반면 jsp는 태그들을 html처럼 그대로 입력하면 되고,

1부터 10까지 합을 구하는 로직은 스크립트릿(<%%>)에,

출력하고자하는 total은 표현식(<%=%>)에 넣어주면 되므로

JSP가 더 편하다고 생각한다.

 

2) 서블릿 라이프 싸이클에서 실행되는 메소드와
JSP 라이프 싸이클에서 실행되는 메소드의 이름을 비교해봅시다.

메소드 이름을 비교하기 전에 JSP라이프 싸이클을 확인해보면 다음과 같다.

1. JSP를 서블릿 코드로 변환.

2. 서블릿을 바이트코드로 컴파일

3. 서블릿 클래스를 로드 중입니다.

4. 서블릿 인스턴스 생성.

5. jspInit()메소드 호출에 의한 초기화

6. _jspService()메소드 를 호출하여 처리 요청

7. jspDestroy()메소드 를 호출하여 파괴

서블릿 라이프 사이클에서 실행되는 메소드와 비교해보면 아래 표와 같다.

Servlet JSP
init() jspInit()
service() _jspService()
destory() jspDestroy()

 

3) JSP들이 Servlet 소스로 변환될 때 스크립트릿, 표현식, 선언문이 어떻게 변환될 지 예상해봅시다.

1. JSP 표현식 : <%= expression %>

→ _jspService()에 out.print(expression); 으로 변환

2. JSP 스크립트릿 : <% code fragment %>

→ _jspService()내에 code fragment 그대로 삽입

3. JSP 선언문 : <%! decleration %>

→ servlet class body에 decleration 그대로 삽입

4. JSP 주석 : <%-- comment --%>

→ java파일로 변환하지 않음

※ html 주석 <!-- comment -->은 html 파일에서 볼 수 있음

※ java 주석 <% //comment %> or <% /* comment */%>은 java파일에서 보이나 .class로 컴파일하지 않음

 

4) 내장객체를 JSP 선언문에서 사용할 수 있을까요? 사용할 수 없다면 왜 그럴까요?
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	StringBuffer url = request.getRequestURL();
	out.print("url : " + url.toString());
	out.print("<br>");
%>

</body>
</html>

위의 jsp 파일은 스크립트릿 내에서 내장객체를 사용할 수 있다.

그럴 수 있는 이유는 아래 java로 변환된 코드와 같이 _jspService()함수 내에 선언되어있는 객체들이기 때문이다.

public void _jspService( ... ){
	
	...

    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\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>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");

	StringBuffer url = request.getRequestURL();
	out.print("url : " + url.toString());
	out.print("<br>");
	

      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    }
    
    ...

}

그런데 만약 스크립트릿이 아닌 선언문에서 사용한다면

_jspService() 바깥에 코드가 들어가기 때문에 에러가 발생할 것이다.

댓글