nyximos.log

[Spring] 서블릿 본문

Programming/Spring

[Spring] 서블릿

nyximos 2022. 2. 9. 13:55

스프링 부트는 톰캣 서버를 내장하고 있어서,

톰캣 서버를 설치하지 않더라도 편리하게 서블릿 코드를 실행할 수 있다.

 

🤔 서블릿이란?

동적인 웹 페이지를 만들 때 사용되는 자바 기반 웹 애플리케이션 프로그래밍 기술

클라이언트의 요청을 처리 후 결과를 반환해준다.

javax.servlet 및 javax.servlet.http 패키지는 서블릿을 작성하기 위한 인터페이스 및 클래스를 제공합니다.

개발자는 javax.servlet.http 패키지의 HttpServlet 클래스를 상속받아 서블릿을 구현할 수 있다.

 

 

🌳 서블릿 생명 주기

서블릿의 생명 주기는 서블릿이 배포된 컨테이너에 의해 제어된다.

클라이언트가 Servlet에게 요청하면 

1. servlet의 인스턴스가 존재하지 않는 경우, 웹 컨테이너는

        1-1 Servlet 클래스를 로드한다.

        1-2 Servlet 클래스의 인스턴스를 생성한다.

        1-3 init() 메소드를 호출하여 Servlet 인스턴스를 초기화한다. 

2. service() 메소드, request 객체와 response 객체를 호출한다.

만약 컨테이너가 서블릿을 제거해야 할 경우 servlet의 destroy() 메소드를 호출해서 끝낼 수 있다.

 

 

@ServletComponentScan

스프링 부트는 서블릿을 직접 등록해 사용할 수 있도록 @ServletComponentScan을 지원한다.

내장형 컨테이너를 사용할 때 @ServletComponentScan을 사용하여 @WebServlet, @WebFilter, @WebListener을 단 클래스를 서블릿 컨테이너에 자동 등록 할 수 있다.

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);
    }
}

 

 

@WebServlet : servlet과 url을 지정

속성

name : 서블릿 이름 지정

urlPatterns : 서블릿을 실행할 URL 매핑

value : urlPatterns과 같은 역할, name을 지정하지 않아도 된다.

 

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;

@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");
     
	 }
}

 

getParameter()

요청 매개 변수의 값을 문자열로 반환하거나 매개 변수가 없는 경우 null 을 반환한다.

요청 매개 변수는 요청과 함께 전송되는 추가 정보이다.

HTTP servlet의 경우 매개변수는 query string 또는 form data이다.

매개 변수에 값이 하나만 있을 경우에만 getParameter()를 사용하고,

값이 둘 이상일 경우 getParameterValues()를 사용한다.

만약 매개 변수가 여러개일 경우 getParameterValues() 에서 반환되는 배열의 첫번째 값과 같다.

 

setContentType()

컨텐츠 유형문자 인코딩을 변경하기 위해 호출한다.

 

setCharacterEncoding()

클라이언트로 보낼 응답의 문자 인코딩을 설정한다.

 

getWriter()

클라이언트에 문자 텍스트를 보낼 수 있는 PrintWriter 개체를 반환한다.

write(), print() 메소드를 통해 response body message 생성

 

 

실행한 후 http://localhost:8086/hello?username=nyximos주소로 이동하면 

다음과 같은 실행결과가 나온다.

HelloServlet.service
request = org.apache.catalina.connector.RequestFacade@2a1cccbc
response = org.apache.catalina.connector.ResponseFacade@6ffe4032
username = nyximos

 

 

🎠 서블릿 컨테이너 동작 방식

 

내장 톰캣 서버 생성

 

HTTP 요청, HTTP 응답 메시지

 

웹 애플리케이션 서버의 요청 응답 구조

😮 HTTP 응답에서 Content-Length는 웹 애플리케이션 서버가 자동으로 생성해준다.

 

 

🤗 welcome 페이지 추가

main/webapp에 index.html을 만들어 놓으면 http://localhost:포트번호 호출시 index.html 페이지가 열린다.

 

 

 

HttpServletRequest - 개요

서블릿은 HTTP 요청 메시지를 개발자 대신 파싱한다.

그리고 결과를 HttpServletRequest 객체에 담아서 제공한다.

 

  • Start Line - HTTP 메소드, URL, 쿼리 스트링, 스키마, 프로토콜
  • header - header 조회
  • 바디 - form 파라미터 형식 조회, message body 데이터 직접 조회

 

이밖에도 여러 기능이 있다.

 


HttpServletRequest - 기본 사용법

start-line 정보

  • request.getMethod()
  • request.getProtocol()
  • request.getScheme()
  • request.getRequestURL()
  • request.getRequestURI()
  • request.getQueryString()
  • request.isSecure() : https 사용 유무

 

header 모든 정보

request.getHeaderNames()
       .asIterator()
       .forEachRemaining(headerName -> System.out.println(headerName + ":" + request.getHeader(headerName)));

 

쿠키 조회

if (request.getCookies() != null) {
     for (Cookie cookie : request.getCookies()) {
     	System.out.println(cookie.getName() + ": " + cookie.getValue());
     }
 }

 

content 조회

  • request.getContentType()
  • request.getContentLength()
  • request.getCharacterEncoding()


HTTP 요청 데이터

HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법

주로 세가지 방법을 사용한다.

  1. GET - 쿼리 파라미터
  2. POST - HTML Form
  3. HTTP message body에 데이터를 직접 담아서 요청

 

GET - 쿼리 파라미터

  • /url?name=nyximos&mbti=ENFJ
  • 메시지 바디 🙅‍♀️
  • URL의 쿼리 파라미터에 데이터 포함해서 전달
  • ? 를 시작으로 보낸다.
  • 추가 파라미터는 &로 구분
  • ex) 검색, 필터, 페이징 등에서 많이 사용

 

쿼리 파라미터 조회 메서드

 

 

POST - HTML Form

  • content-type: application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파라미터 형식으로 전달
  • ex) 회원 가입, 상품 주문, HTML Form 사용
  • POST의 HTML Form을 전송하면 웹 브라우저는 HTTP메시지를 만든다.
  • 클라이언트 입장에서는 쿼리 파라미터 방식과 차이가 있지만,
  • 서버 입장에서는 형식이 동일하므로 아까와 같이 쿼리 파라미터 조회 메서드를 사용하자.
  • 단 POST HTML Form 방식은 HTTP 메시지 바디에 데이터를 포함해서 보내므로
  • content-type을 꼭 지정하자.

👨‍🔧 Postman을 사용하여 HTML Form을 만들지 않고 테스트 할 수 있다.

  • Body에 x-www-form-urlencoded 체크했는지 확인

  • Headers에서 Content-Type이 application/x-www-form-urlencoded로 지정했는지 확인하자.

 

 

HTTP message body에 데이터 직접 담아서 요청

  • HTTP API에서 주로 사용
  • JSON, XML, TEXT
  • 주로 JSON 사용 (POST, PUT, PATCH)

1) 단순 텍스트

  • content-type : text/plain
  • InputStream을 사용해서 HTTP 메시지 바디의 데이터를 읽을 수 있는데 byte 코드를 반환하기 때문에
  • 문자(String)으로 보려면 문자표(Charset)를 지정해야한다.
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

2) JSON

  • content-type : application/json
  • message body : {"name":"nyximos", "mbti":"ENFJ"}
  • JSON 결과를 파싱해서 사용할 수 있는 자바 객체를 변환하려면 JSON 변환 라이브러리(Jackson, Gson)를 추가해서 사용해야 한다.
  • 스프링 부트로 Spring MVC를 선택하면 기본으로 Jackson 라이브러리(ObjectMapper)를 함께 제공한다.
  • Postman으로 실행할때 Body에서 raw를 선택후 JSON을 선택한다.

 

 

HttpServletResponse - 기본 사용법

  • HTTP 응답 메시지 생성 - HTTP 응답코드 지정, 헤더 생성, 바디 생성
  • 편의 기능 제공 - Content-Type, 쿠키, Redirect

 

 

HTTP 응답 데이터 - 단순 텍스트

  • 단순 텍스트 응답 writer.println("ok");

 

HTTP 응답 데이터 - HTML

  • HTTP 응답으로 HTML을 반환할 때는 content-type을 text/html로 지정

 

HTTP 응답 데이터 - API JSON

  • HTTP 응답으로 JSON을 반환할 때는 content-type을 application/json로 지정
  • application/json은 스펙상 utf-8 형식을 사용하도록 정의되어 있다.
  • 따라서 application/json; charset=utf-8이라고 전달하는 것은 의미없는 파라미터를 추가한 것이 된다.
  • response.getWriter()를 사용하면 추가 파라미터를 자동으로 추가하는데,
  • 이때 response.getOutputStream()을 출력하면 문제가 생기지 않는다.

 

 

 

참조

김영한, 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

https://docs.oracle.com/javaee/5/tutorial/doc/bnafe.html

 

What Is a Servlet? - The Java EE 5 Tutorial

What Is a Servlet? A servlet is a Java programming language class that is used to extend the capabilities of servers that host applications accessed by means of a request-response programming model. Although servlets can respond to any type of request, the

docs.oracle.com

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.embedded-container.context-initializer

 

Spring Boot Reference Documentation

This section goes into more detail about how you should use Spring Boot. It covers topics such as build systems, auto-configuration, and how to run your applications. We also cover some Spring Boot best practices. Although there is nothing particularly spe

docs.spring.io