서블릿 작동 원리와 xml파일 servlet 생성 후 매핑 및 doGet(), init()
읽히는 블로그
2024. 7. 12. 11:35
▤ 목차
✔ 서블릿 작동 원리
⌨ 서블릿이란?
클라이언트가 요청을 하면 해당 요청에 맞는 처리를 한 후 결과를 반환하는 자바 웹 프로그래밍 기술이다.
자바 서블릿(Java Servlet)은자바를 사용하여 웹페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 사양을 말하며, 흔히 "서블릿"이라 불린다. ... 서블릿은 JSP와 비슷한 점이 있지만, JSP가 HTML 문서 안에 Java 코드를 포함하고 있는 반면, 서블릿은 자바 코드 안에 HTML을 포함하고 있다는 차이점이 있다.
-wiki
클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트이다.
html을 통해 요청 받고 응답한다.
java 기반의 프로그래밍 기술이기에 java Thread를 이용하여 동작한다.
MVC 패턴에서 controller로 이용된다.
HTTP 프로토콜 서비스를 지원하는 import javax.servlet.http.HttpServlet 클래스를 상속받는다.
servlet 파일을 변경한 경우 재컴파일을 해야 한다.
동적인 페이지를 제공하기 위해서 웹서버는 다른 곳에 도움을 받아 동적인 페이지를 작성해야 한다.
이때 웹서버가 동적인 페이지를 제공할 수 있도록 도와주는 어플리케이션이 서블릿이며 동적인 페이지를 생성하는 어플리케이션이 CGI이다.
CGI(Common Gateway Interface)란? CGI는 웹서버와 프로그램 간 교환방식(interface)을 의미한다. 서블릿과 비슷한 기술이라 생각하면 된다. CGI는 요청이 있을 때마다 새로운 프로세스가 생성되어 응답한다. (Servlet은 외부 요청마다 프로세스보다 가벼운 스레드로써 응답하므로 보다 가볍다.) - 특정 플랫폼에 의존하지 않는다. 웹서버 등으로부터 외부 프로그램을 호출하는 조합을 가리킨다. https://zrr.kr/yo23
✨ 라이프 사이클
서블릿 컨테이너가 하는 일은 통신지원, 라이프 사이클 관리, 멀티 스레딩.. 이 있다.
Life Cycle 클래스 로딩 > 서블릿 인스턴스화(생성자 실행) > init() > service() 또는 doGet()/doPost() > destroy()
클라이언트로 서블릿 파일을 요청받으면 서블릿을 바로 호출하지 않고 컨테이너(톰켓)에게 요청을 넘긴다.
컨테이너는 request, response 객체를 만들어 이를 인자로 서블릿 doGet(), doPost() 메서드 중 하나를 호출한다.
+ jsp 페이지도 서블릿 클래스로 변환된 후 같은 라이프 사이클을 수행한다.
https://cafe.daum.net/flowlife/HqLp/61
위의 그림과 같이 일반 사용자 요청 처리를 서블릿 컨테이너 내부에서 스레드 단위로 요청 처리를 한다.
이렇게 개발자가 아닌 컨테이너가 제어하는 것을 제어의 역전(IoC)라고 한다.
간단하게 보면 위와 같은 흐름을 탄다.
서블릿의 흐름을 조금 더 자세하게 알아보자.
위에서 언급했듯이 과정은init() > service() > destroy() 방식으로 흘러간다.
실제로 웹서버 실행과 서블릿 컨테이너로 가는 사이에 해당 요청의 file 유무를 검사한다.
+ 서블릿 엔진이라고도 하며 서블릿 컨테이너는 서블릿 컴포넌트를 실행하는 환경을 제공한다.
👏 중요
서블릿을 수정했으면 서버를 재실행해야 한다.
서블릿은 하나의 상태만 가지고 있다.
초기화가 되지 않았다?
1. 초기화되는 중이다. (생성자를 실행하거나 init 메서드가 실행 중)
2. 소멸되는 중이다.(destroy 메서드가 실행 중)
3. 존재하지 않는다.
✔ xml파일 servlet 생성 후 매핑
⌨ servlet 매핑 이유
클라이언트에서 URL을 이용해 서버에게 파일을 요청한다.
클라이언트의 요청이 들어오면 servlet은 xml을 먼저 읽어본다.
위와 같은 방식으로 진행된다.
물리적 클래스명을 사용하면 편하지만 아래와 같은 단점이 생긴다.
클래스 명이 길어지면 입력이 불편해지고 클래스 이름이 노출되기에 보안에 취약하다는 단점이 생긴다.
때문에 논리적 클래스명(별명)을 매핑해 주는 방식을 사용한다.
매핑하는 방법
web.xml 직접 작성하기
서블릿 어노테이션 이용하기
어노테이션은 나중에 나온 기술이고 편리하지만 동작방식을 알기 위해서는 xml을 만져보는 것이 좋다.
🔷 web.xml 직접 작성
<servlet>
<servlet-name>abc</servlet-name> <!-- @WebServlet("/HelloServlet") 해당 어노테이션이 나오기 전 xml 처리 -->
<servlet-class>pack.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
<url-pattern>/Hello.kor</url-pattern> <!-- 논리적 파일명(별명)을 적어줌. 같은 이름인 servlet-name을 찾아가서 해당 class를 사용한다. -->
<url-pattern>/dajeong</url-pattern> <!-- 논리적 파일명(별명)-->
</servlet-mapping>
url-pattern 태그를 만들어 논리적 명을 설정해 주면
클라이언트가 url을 요청할 때 논리적 파일명을 통해 들어오면 같은 servlet-name으로 매핑된 클래스로 들어오게 된다.
service() 메서드가 끝나면, 스레드를 소멸하거나 컨테이너가 관리하는 스레드 풀(pool)로 돌려보낸다.
request와 response 객체는 가비지 컬렉션이 될 준비를 할 것이다.
👏 중요
service() 메서드가 없으면 get, post형식으로 나눠 처리된다.
나누고 싶지 않으면 service 메서드를 사용하면 된다.
즉, get, post 보다 우선순위가 높다.
서블릿의 대부분의 일생을 이 부분에서 보낸다.
✔doGet()
웹이 실행될 때 서블릿이 해당 파일을 받아본 후, 파일이 자바로 되어 있으면 톰캣으로 넘긴다.
톰캣은 해당 파일을 들고 JDK을 시켜 컴파일을 시킨다.
해당 doGet() 메서드에 출력값이 있으면 웹브라우저에 출력하게 된다.
⌨ 형식
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");//mime type과 문자코드
PrintWriter out = response.getWriter();//웹브라우저 출력
}
http get방식이기에 URL에 해당 변수의 데이터가 노출(header)된다.
💻 코드로 보기
자바와 같다. 하지만 자바는 System.out.println을 통해 해당 출력장치인 console창에 출력하지만
response.getWriter() 메서드를 통해 웹브라우저에 출력시킨다.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// get 요청 시 수행
num +=1;
System.out.println("get 요청시 실행 num = "+num);
}
기본 메서드 요청 방식은 get이기에 만약 service()가 없으면 자동으로 수행되는 메서드이다.
✔getPost()
⌨ 형식
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// post 요청 시 수행
num +=1;
System.out.println("poet 요청시 실행 num = "+num);
}