일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- DB
- Spring
- CentOS
- docker
- MYSQL
- WEB SOCKET
- 프로그래머스
- 생성자 주입
- JavaScript
- visualvm
- @jsonproperty
- 패스트캠퍼스
- 시큐리티
- 스프링의 정석
- java
- emqx
- Kafka
- 스웨거
- EC2
- 데이터베이스
- 남궁성과 끝까지 간다
- 항해99
- 스파르타코딩클럽
- 쇼트유알엘
- 개인프로젝트
- 웹개발
- Spring Security
- JWT
- 카프카
- AWS
- Today
- Total
Nellie's Blog
Servlet(서블릿)에 대해 알아보자 본문
서블릿을 알아보기 전에 WAS에 대해 먼저 알아보자.
WAS가 뭐야?
기존 웹에서는 웹서버로 정적자원만 반환을 하다가, 점점 동적 웹에 대한 수요가 커져갔다.
그에 따라 DB에 접근하고, 다양한 로직처리를 통해 동적 자원을 만드는 뭔가가.. 필요해졌다!
그 뭔가..가 DB에서 받아온 데이터들을 요리조리 요리해 줄수 있었으면 좋겠어!
그것이 WAS이다...!!!
DB 조회나 다양한 로직 처리를 요구하는 동적인 컨텐츠를 제공하기 위해 만들어진 Application Server.
HTTP를 통해 컴퓨터나 장치에 애플리케이션을 수행해주는 미들웨어(소프트웨어 엔진)이다.
“웹 컨테이너(Web Container)” 혹은 “서블릿 컨테이너(Servlet Container)”라고도 불린다.
Container란 JSP, Servlet을 실행시킬 수 있는 소프트웨어를 말한다.
즉, WAS는 JSP, Servlet 구동 환경을 제공한다.
대표적인 WAS는 톰캣이다.
서블릿이 뭔데?
서블릿은 SUN사에서 제안한 웹서비스를 위한 인터페이스로, 원칙적으로는 javax.servlet.Servlet 인터페이스의 구현체다. 서블릿은 톰캣(WAS) 위에서 동작하는 자바프로그램이다.
일반적인 자바 독립 실행프로그램과 달리 main 메서드가 없으며, 서블릿 컨테이너에 등록된 후 서블릿 컨테이너에 의해 생성, 호출, 소멸이 이루어진다.
서블릿은 서버에서 웹페이지 등을 동적으로 생성하거나 데이터 처리를 수행하기 위해 자바로 작성된 프로그램이다.
java코드 안에 html태그가 삽입되며 자바 언어로 되어있다. 확장자가 .java 이다.
서블릿 컨테이너는 이러한 서블릿을 관리하며 네크워크 통신, 서블릿의 생명주기 관리, 스레드 기반의 병렬처리를 대행한다. 즉, 웹 클라이언트로 부터 HTTP 요청이 전달되면 해당 HTTP 요청을 해석하여 적정한 서블릿의 service 메서드를 ServletRequet, ServletResponse 매개변수와 함께 호출한다.
GenericServlet은 service 메서드를 제외한 나머지 Servlet 인터페이스의 메서드를 구현해 놓은 abstract 클래스다.
이 클래스를 상속받아 실제 Http request 처리에 필요한 service 메서드를 구현해 놓은 것이 바로 HttpServlet 다.
참고로, 우리가 자주 접하였던 Spring framework 의 DispatcherServlet 은 아래와 그림과 같은 계층구조를 가지고 있다.
서블릿을 쓰면 실질적인 이득이 뭐야?
HTTP 요청과 응답을 보자.
만약 개발자들이 이 텍스트들을 직접 처리해서 아래 응답과 같은 형식으로 만들어 줘야한다면, 너무 힘들것이다.
모든 규약을 확인해가며 긴 텍스트로 들어온 요청을 분석하고 거기에 맞는 처리를 하고 처리한 값을 규약에 맞춰서 응답을 보내줘야 한다.
아래는 http servlet request가 제공하는 메서드 들이다.
아래 그림에서 , http형태의 요청을 직접 파싱하는것과 http servlet request의 메서드를 호출하는 것을 비교해보면 후자가 훨씬 정보얻기가 편할 것이다. 서블릿이 요구하는 구현규칙을 지켜주면서 서블릿을 정의해주면 http요청정보를 쉽게 사용할 수 있고 , 처리 결과를 쉽게 응답으로 변환할 수 있다.
서블릿을 이용하면 개발자들이 진짜 집중해야 하는 비즈니스 로직(처리 로직)에 더 집중할 수 있다는 것이다!
서블릿은 어떻게 생겼어?
서블릿은 인터페이스이다.
서블릿 인터페이스는 다음과 같이,
init()으로 서블릿 생성, service()로 필요한 처리 진행, destroy()로 서블릿 삭제를 하는 메서드로 이루어져 있다.
package jakarta.servlet;
public interface Servlet {
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public void destroy();
}
이제 이 서블릿 인터페이스를 구현한 HttpServlet 클래스를 한번 볼까?
public abstract class HttpServlet extends GenericServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
String msg = lStrings.getString("http.method_get_not_supported");
sendMethodNotAllowed(req, resp, msg);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String msg = lStrings.getString("http.method_post_not_supported");
sendMethodNotAllowed(req, resp, msg);
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String msg = lStrings.getString("http.method_put_not_supported");
sendMethodNotAllowed(req, resp, msg);
}
protected void doDelete(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
String msg = lStrings.getString("http.method_delete_not_supported");
sendMethodNotAllowed(req, resp, msg);
}
}
HttpServlet은 웹 사이트에 적합한 서블릿을 구현하기 위한 추상클래스이다.
HttpServlet을 상속한 클래스는 다음과 같은 메서드들 중 필요한 메서드를 오버라이딩 해야한다.
- doGet() : HTTP GET 요청에 대한 처리
- doPost() : HTTP POST 요청에 대한 처리
- doPut() : HTTP PUT 요청에 대한 처리
- doDelete() : HTTP DELETE 요청에 대한 처리
- init() : 서블릿 생성
- destroy() : 서블릿 파괴
위의 Servlet 인터페이스에서 봤던 service() 메서드를 따로 오버라이딩 해줄 필요는 없다.
HttpServlet의 service() 메서드가 HTTP 요청을 보고, doMethod() 꼴의 메서드를 실행해준다.
서블릿을 어떻게 만들어?
내가 직접 HttpServlet을 상속한 HelloServlet을 만들어보자.
public class HelloServlet extends HttpServlet {
public void init() {
System.out.println("init...");
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
System.out.println("doGet here");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html><body>Hello Servlet!</body></html>");
}
public void destroy() {
System.out.println("destroy!");
}
}
doGet메소드만 오버라이딩 해서 나만의 HelloServlet 서블릿을 만들었다.
서블릿이 어떻게 동작해?
1. 웹 서버가 WAS에게 클라이언트가 보낸 요청을 건네줌
1-1. HTTP request의 정보를 통해 HttpServletRequest 객체를 생성
1-2. 클라이언트에게 보낼 응답을 위해 HttpServletResponse 객체를 생성
1-3. 서블릿 컨테이너의 web.xml 설정에서 요청 url에 대응되는 서블릿을 선택
1-4. 선택된 서블릿에 HttpServletRequest와 HttpServletResponse를 넘겨줌
2. 서블릿 컨테이너가 선택된 서블릿 객체를 메모리에 올림
2-1. 서블릿 컨테이너가 선택된 서블릿 객체를 컴파일
2-2. 서블릿 객체를 만들어 메모리에 올림
2-3. 메모리에 올라가면서 서블릿의 init() 메서드 실행
3. 서블릿 컨테이너가 해당 서블릿 객체의 service() 메서드를 호출함
3-1. 하나의 쓰레드에서 요청에 대응되는 서블릿의 service() 메서드를 호출함
3-2. service() 메서드 내부에서 HttpServletResponse에 필요한 내용을 담아서 반환함
내가 만든 서블릿을 실행해보자!
1. 톰캣을 설치하고 실행해본다.
톰캣을 설치하고 실행한 뒤, EC2 인스턴스 주소의 8080 포트로 접속하면 톰캣 페이지가 뜨면 톰캣이 잘 실행되었다는 뜻.이제 톰캣을 끄고 서블릿을 만들어보자.
2. 서블릿을 만들어 "apache-tomcat-10.0.7/webapps/ROOT/WEB-INF/classes" 에 저장한다.
위에서 만든 HelloServlet 소스 코드와 이를 컴파일한 클래스 파일을 톰캣의 정해진 위치에 저장해준다.
- 소스 코드: apache-tomcat-10.0.7/webapps/ROOT/WEB-INF/classes
- 클래스 파일: apache-tomcat-10.0.7/webapps/ROOT/WEB-INF/src
3. web.xml 에 HelloServlet에 대한 정보를 정의해준다.
web.xml은 URL 경로와 해당 경로의 요청을 처리하는 서블릿 사이의 매핑을 정의한다.
다음과 같이 정의해 보자.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
<display-name>Welcome to Tomcat</display-name>
<description>
Welcome to Tomcat
</description>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
</web-app>
4. 다시 톰캣을 실행하고, 지정한 URL에 접속해본다.
내가 만든대로 화면에 잘 출력되었다!
출처 :
https://m.blog.naver.com/acornedu/221128616501
https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html