스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술을 공부하고 정리하는 포스트입니다.


서블릿(Servlet)

서블릿(Servlet)이란?

  • 클라이언트의 요청을 처리하고 결과를 반환하는 Servlet 클래스의 규칙을 지킨 자바 웹 프로그래밍 기술
  • 자바를 사용하여 웹을 만들기 위해 필요한 기술 (자바 기반 -> JDK / JVM 필수)
    • 즉, 자바를 이용해 웹 개발을 하기 위해서 필요한 “가장 low(기본적인)한 기술이 서블릿(Servlet)


  • urlPatterns(/hello)의 URL이 호출되면 서블릿 코드가 실행
  • HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest
  • HTTP 응답 정보를 편리하게 제공할 수 있는 HttpServletResponse
  • 개발자는 HTTP 스펙을 매우 편리하게 사용

특징

  • 클라이언트 요청에 대해 동적으로 작동하는 웹 애플리케이션 컴포넌트
  • HTML을 사용하여 요청에 응답
  • Java Thread를 이용하여 동작
  • MVC 패턴에서 Controller로 이용

동작

localhost:8080/hello 라고 요청했을 때


  • Client가 HTTP 요청
  • WAS는 HttpServletRequest / HttpServletResponse 객체를 생성
  • WAS는 요청 URL에 해당하는 서블릿 객체를 호출
    • 서블릿을 지원하는 WAS == 서블릿 컨테이너
  • 개발자는 HTTPServletRequest를 통해 요청 정볼르 편리하게 사용
  • 비즈니스 로직 수행
  • 개발자는 HttpServletResponse를 통해 응답 정보를 작성
  • WAS는 HttpServletResponse를 통해 HTTP Response Message 생성 후 Client에 전달

서블릿 컨테이너(Servlet Container)


  • 서블릿을 관리하기 위한 모든 작업을 수행 (생성 / 호출 / 관리)
  • Java Thread를 사용해서 서블릿을 호출
  • 톰캣(Tomcat)처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함
  • 서블릿 객체는 싱글톤으로 관리
    • 고객의 요청이 올 때 마다 생성하는 것은 비효율적
    • 공유 변수 사용에 주의해야 함
    • 서블릿 컨테이너가 종료 -> 서블릿도 종료
  • 동시 요청을 위한 멀티 쓰레드(Multi Thread) 처리를 지원

핵심


  • 실제 WAS를 직접 구현한다면 많은 사전 과정을 구현해야 함
    • TCP / IP 연결 & 소켓 연결
    • HTTP request message 파싱
    • HTTP response message 생성
    • TCP / IP 및 소켓 연결 종료
  • Servlet을 지원하는 WAS, 서블릿 컨테이너는 이러한 과정들을 대신 수행해줌
    • 개발자는 비즈니스 로직에 집중!

프로젝트 구성 & 설정


  • Spring initializr 라는 Starter를 이용한 프로젝트 구성
    • Packaging을 반드시 War로 선택 -> JSP를 사용하기 위해 필요함
  • Lombok 설정
    • lombok 플러그인 설치
    • Preferences -> Annotation Processors 검색 -> Enable annotation processing 체크
  • Postman 설치
    • API 요청을 보낼 수 있는 툴

서블릿 등록 & 사용

  • 서블릿은 톰캣 같은 웹 애플리케이션 서버를 직접 설치하고, 그 위에 서블릿 코드를 클래스 파일로 빌드해 올린 다음, 톰캣 서버를 실행하면 됨
    • 매우 번거로운 과정

@ServletComponentScan

  • @ServletComponentScan 설정
    • SpringBoot 환경에서 서블릿을 직접 등록해 사용할 수 있도록 도와주는 애노테이션


서블릿 등록


  • 단계
    • 1) @WebServlet으로 이름 / 연결 Url 지정 : @WebServlet(name = "helloServlet", urlPatterns = "/hello")
    • 2) HttpServlet 접속 : public class HelloServlet extends HttpServlet
    • 3) Protected 접근 지정자를 갖는 Service를 Override : protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    • 4) 비즈니스 로직 작성 : System.out.println("HelloServlet.service");

HttpServletRequest

역할

  • HTTP request 메시지를 편리하게 사용할 수 있도록 개발자 대신 parsing해서 제공된 객체
    • parsing된 결과를 HttpServletRequest 객체에 담아서 제공
  • HttpServletRequest를 사용해서 HTTP request message의 다양한 정보를 조회할 수 있음
    • start-line
    • headers
    • body
  • 추가적으로 다양한 부가 기능도 제공
    • 임시 저장소 기능 : 해당 HTTP 요청이 시작되고 끝날 때 까지 유지되는 임시 저장소
      • 저장 : req.setAttribute(name, value)
      • 조회 : req.getAttribute(name)
    • 세션 관리 기능
      • req.getSession(create : true)

HTTP request message 정보 조회

start-line 정보 조회



Header 정보 조회



Header 정보 조회(간소화)



Header 간편 조회



기타 정보 조회



요청 데이터(body) 전달 방법

  • 주로 3가지 방법
    • GET : 쿼리 파라미터
    • POST : HTML Form
    • HTTP message body에 직접 담아서 요청

GET 쿼리 파라미터 & POST HTML Form



  • 쿼리 파라미터
    • http request message의 body 없이 URL의 쿼리 파라미터에 데이터를 포함해서 전달
    • ex) /url?username=hello&age=20
    • 주 사용 : 검색 / 필터 / 페이징
  • HTML Form
    • HTML Form 형식에서 바로 데이터를 넘기는 방식
    • 무조건 POST로 요청하기 때문에 쿼리 파라미터와 다르게 Http request message body로 데이터 전송
    • 데이터 형식은 쿼리 파라미터와 동일한 형식 -> 같은 방법으로 조회 가능
    • Content-Type : application/x-www-form-urlencoded 반드시 지정!

HTTP 요청 데이터 API message body - 단순 text




  • 단순 데이터를 Stream으로 주고받는 경우
  • byte 코드를 우리가 읽을 수 있는 문자(String)으로 변환해야 함
    • Charset을 지정 -> UTF-8

HTTP 요청 데이터 API message body - JSON




  • 입력받은 문자를 jackson 라이브러리의 ObjectMapper를 통해 JSON 형식으로 변경해야 함
  • HelloData : JSON 객체로 변환된 정보를 받기 위한 임시 데이터 구조
  • stream을 JSON으로 파싱하는 등 할 일이 많음 -> 실제로는 Spring MVC로 편리하게 사용 가능

HttpServletResponse

역할

  • HTTP response 메시지를 편리하게 만들 수 있도록 제공되는 객체

HTTP response message 정보 조회


  • status-line : statusCode 지정
  • response-header : 데이터 타입 등을 지정


  • header 편의 메서드 : setHeader에 텍스트로 필드를 삽입하는 것이 아닌 하나하나 각각 setter로 지정

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


HTTP 응답 데이터 - API JSON