서블릿 실습 진행을 위해 다음과 같이 스프링 부트를 설정한다.
Project - Gradle Groovy Project
Language - Java
Spring Boot - 2.4.x - 3.x로 설정할 경우 자바 17 이상이 필요하다(아닌 경우 Gradle부터 에러 발생)
-> 전에 스프링 실습할때 여기서부터 삽질하게 된 ㅠㅠ
Packaging : War
Jar에서는 JSP 실행이 안된다, Jar는 내장 Tomcat 사용시 바로 돌릴 수 있다는 장점이 있다.
War도 톰캣으로 돌릴 수 있긴 한데 별도로 톰캣을 설치하는 경우 사용한다.
사실 스프링 부트가 없어도 서블릿 실습을 하는데는 문제가 없다
-> 사실 문제가 있다, 코드가 안돌아가진 않는데 코드 실행을 위한 환경설정(Tomcat 등)만 한내잘 걸리는데
스프링 부트를 사용하면 이런 번거로운 과정을 아름답게 알아서 해결해주는 장점이 있기 때문에 배우는 과정에서는 쓰는게 이득이다!
스프링 부트 서블릿 환경을 구성하겠다
package hello.servlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
다음과 같이 @ServletComponentScan Annotation을 추가하게 되면, 스프링 부트가 해당 패키지 hello.servlet 하위의 모든 Servlet들을 자동으로 뒤져서 등록해준다.
이후 HelloServlet 클래스를 생성하겠다.
package hello.servlet.basic;
import java.io.IOException;
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(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);
}
}
Servlet을 사용하기 위해서는 먼저 HttpServlet 클래스를 상속해야한다.
그리고 @WebServlet Annotation을 사용하여, 서블릿의 이름과 urlPatterns를 지정해줘야하는데
이때 urlPatterns의 경우 www.xxx.com/hello 식으로 요청이 들어오면 이 서블릿을 호출하겠다는 의미로 사용된다.
또한 주의할 점이 있는데 서블릿의 이름과 urlPatterns는 Unique해야한다.
이후, Mac 기준으로 Control + O를 통해 상속한 클래스의 메서드를 오버라이드 할 수 있는데
서블릿에서 HTTP 메세지를 편리하게 사용할 수 있도록 하는 HttpServletRequest와 HttpServletResponse를 사용하기 위해서는
protected로 설정된 service 메서드를 오버라이드 해 주어야 한다.
이 때, HttpServletRequest와 HttpServletResponse의 경우 인터페이스이며 이 인터페이스의 구현체는 WAS에 구현된다.
따라서 두 객체는 WAS에 의해 생성되며 WAS에 의해 전달되어진다고 생각하자.
실제로 위 코드에서 response와 request 객체를 호출하게 되면 RequestFacade@~~~ 식으로 호출문이 출력되는데
가장 최상위를 보면 org.apache.catalina -> 즉 아파치 서버의 무언가임을 알 수 있다 (TOMCAT 관련)
HTTP 요청을 통해 매핑된 URL이 호출되면 서블릿 컨테이너는 service 메서드를 실행한다.
HTTP 요청 메세지 로그로 확인하기
다음 설정을 추가하면 HTTP 요청 메세지를 로그 형식으로 확인할 수 있다.
logging.level.org.apache.coyote.http11=debug
Spring Boot의 logger가 지원한다.
운영서버에서 이런식으로 요청정보를 다 남기면 성능저하가 발생할 수 있기 때문에 개발 단계에서만 적용하는게 좋다.
Servlet 컨테이너 동작방식
요청이 들어오면 톰캣 서버가 서블릿 컨테이너에 helloServlet을 생성한다.
다음과 같은 방식으로 WAS에 의해 request, response 객체가 생성되고 helloServlet은 그것을 받아 response를 다시 수정한다.
WAS에 의해 그 뒤 생성된 response message가 나간다.
참고로 HTTP 응답에서 content-length의 경우 WAS가 자동으로 생성해준다
'스프링 공부 (인프런 김영한 선생님) > 스프링 MVC 1편' 카테고리의 다른 글
[스프링 웹 MVC 1편] 6. HTTP 요청 데이터 (0) | 2023.05.20 |
---|---|
[스프링 웹 MVC 1편] 5. HttpServletRequest - 개요/기본사용법 (0) | 2023.05.19 |
[스프링 웹 MVC 1편] 3. 동시요청 - 멀티스레드 (0) | 2023.05.17 |
[스프링 웹 MVC 1편] 2. 서블릿 / 서블릿 컨테이너 (0) | 2023.05.16 |
[스프링 웹 MVC 1편] 1. 웹 서버, 웹 애플리케이션 서버 (0) | 2023.05.16 |