부스트 코스 강의를 듣다가 서블릿 부분이 이해가 안돼서 서블릿을 확실히 이해하고 넘어가야겠다는 생각을 했다.
강의를 반복해서 듣고 검색을 해봐도 잘 이해가 안돼서 이전에 들었던 spring-mvc-1 편의 servlet부분만 다시 공부했다.
서블릿은 웹 요청과 응답의 흐름을 간단한 메서드 호출만으로 체계적으로 다룰 수 있게 해주는 기술이다. 좁게 보면 이러한 기능을 하는 자바의 클래스를 뜻하며, 넓게 봤을 땐 위 기능을 수행하기 위한 자바의 패키지를 뜻한다고 한다.
@WebServlet(name= "helloServlet",urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet.service");
System.out.println("request = " + request);
System.out.println("response = " + response);
String username = request.getParameter("username");
System.out.println("username = " + username);
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().write("hello"+username);
}
}
먼저 웹 브라우저에서 요청이 들어오면 WAS에서 해당 요청에 매핑되는 서블릿을 호출한다. ( 이 기능을 WAS의 쓰레드가 수행한다고 이해했음 ) 이와 동시에 request, response 객체를 생성해서 서블릿에 전달한다.
그리고 해당 서블릿의 service 메서드를 실행한다.
만약 서블릿이라는 기능이 없었다면 요청온 http에 대한 정보를 직접 해석하고 정보를 추출했어야 했을텐데 WAS와 Servlet 을 통해 간편하게 정보를 추출하고 정보를 담아서 전송할 수 있다.
내가 이해가 안됐던 부분은 도대체 서블릿이 무엇인지와 도대체 어떻게 싱글톤으로 관리되는가였는데, 서블릿이 작게 봤을 땐 클래스로 볼 수 있다는 것과 서블릿이 통틀어서 하나가 아니라 해당 url매핑에 해당하는 서블릿을 싱글톤으로 관리한다는 것으로 이해하기로 했다.
package hello.servlet.web.servlet;
import hello.servlet.domain.member.MemberRepository;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "memberFormServlet",urlPatterns = "/servlet/member/new-form")
public class MemberFormServlet extends HttpServlet {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter w = response.getWriter();
w.write("<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
"<form action=\"/servlet/members/save\" method=\"post\">\n" +
" username: <input type=\"text\" name=\"username\" />\n" +
" age: <input type=\"text\" name=\"age\" />\n" +
" <button type=\"submit\">전송</button>\n" +
"</form>\n" +
"</body>\n" +
"</html>\n");
}
}
이렇게 response 에 직접 html 코드를 작성해서 넘겨준다.
굉장히 오류가 발생할 확률이 높으며, 오류 발생시 오류 발생 지점을 찾기가 매우 힘들다.
기본 html 파일과 달리, 중간에 변수나 자바 코드를 삽입하여 동적으로 화면을 구성할 수 있다.
ex)
for (Member member : members) {
w.write(" <tr>");
w.write(" <td>" + member.getId() + "</td>");
w.write(" <td>" + member.getUsername() + "</td>");
w.write(" <td>" + member.getAge() + "</td>");
w.write(" </tr>");
}
서블릿만으로 웹 애플리케이션을 구성하면, 서비스가 커질수록 html문서에 대한 부분을 유지 보수하기가 거의 불가능해질 것이다.
이러한 불편함을 해결하기 위해서 html에 자바 코드를 넣는 템플릿 엔진이 개발되었다.
대표적인 템플릿 엔진에는 JSP,Thymeleaf,Freemarker,Velocity 등 이있다.
먼저 WAS는 클라이언트로부터 서블릿 요청을 받으면 해당 서블릿이 메모리에 있는지 확인합니다.
(만약 해당 서블릿이 처음실행되어 메모리에 없다면) 서블릿 클래스를 메모리에 올리고 init() 메소드와 service() 메소드를 실행합니다.
(만약 해당 서블릿이 메모리에 있다면) service() 메소드를 실행합니다.
WAS가 종료되거나 웹 어플리케이션이 갱신되어 서블릿 종료 요청이 있을 경우 destroy() 메소드를 실행합니다.
1) init()
서블릿을 처음 메모리에 올릴때 실행되어, 서블릿을 초기화하며 처음에 한번만 실행됩니다.
2) service()
요청/응답(request/response)을 처리하며 요청이 GET인지 POST인지 구분하여 doGet() 또는 doPost() 메소드로 분기됩니다.
3) destroy()
서블릿 종료요청이 있을때 destroy() 메소드가 실행됩니다.
출처: https://kadosholy.tistory.com/47 [KADOSHoly]
JSP 란 JavaServer Pages 의 약자이며,
HTML 코드에 JAVA 코드를 넣어 동적웹페이지를 생성하는 웹어플리케이션 도구이다.
출처: https://javacpro.tistory.com/43 [버물리의 IT공부]
<%@ page import="java.util.List" %>
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
MemberRepository memberRepository = MemberRepository.getInstance();
List<Member> members = memberRepository.findAll();
%>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/index.html">메인</a>
<table>
<thead>
<th>id</th>
<th>username</th>
<th>age</th>
</thead>
<tbody>
<%
for (Member member : members) {
out.write(" <tr>");
out.write(" <td>" + member.getId() + "</td>");
out.write(" <td>" + member.getUsername() + "</td>");
out.write(" <td>" + member.getAge() + "</td>");
out.write(" </tr>");
}
%>
</tbody>
</table>
</body>
</html>
jsp를 사용하면 이렇게 html에 java코드가 삽입된 문서를 해석하여 서블릿 형태로 전환시켜준다.
하지만 다양한 코드가 노출되어 있고, jsp가 너무 많은 역할을 담당하기 때문에 유지보수가 굉장히 어려워진다는 단점이 있다.
JSP는 현재 다른 템플릿 엔진에 비해 기능이 뒤쳐지는 추세라고 한다. 따라서 세세한 정리는 생략했다.