스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (김영한) 강의 수강 후 정리한 자료입니다.

❗서블릿에 대해 알아보자❗

  • 프로젝트 생성 시 Packaging을 Jar이 아닌 War로 선택해야 JSP를 사용할 수 있다.
  • 톰캣 서버를 따로 넣어주고 싶을 때 사용한다.
  • 서블릿과 스프링부트는 연관이 없지만, 톰캣 서버 관련 세팅을 하려면 시간이 오래 걸리기 때문에 위 강의에서는 서버를 내장하고 있는 스프링 부트를 사용한다.

✨ 서블릿 기본 설정

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet(name = "helloServlet", urlPatterns = "/hello") // "/hello"로 오면 service 메서드 호출
public class HelloServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
}

  • “/hello”로 url 입력이 들어오면 service 메서드를 호출해준다.

service 메서드 로직

@override
protected void service (HttpServletRequest request, HttoServletResponse response) throws ServletException, IOException {
    System.out.println("request = " + request);
    System.out.println("response = " + response);

    String username = request.getParameter("username");
    System.out.println("username = " + username);

    // contentType -> header 정보에 들어가게 됨.
    response.setContentType("text/plain");
    response.setCharacterEncoding("utf-8");

    response.getWriter().write("hello" + username); // http body에 값 할당
}

request, response 객체

System.out.println("request = " + request);
System.out.println("response = " + response);
  • 내부에 request, response 객체를 찍게 되면 새로고침할 때마다 (요청 및 응답을 보낼 때마다, 접속할 때마다) 새로운 request, response 객체가 만들어지는 것을 확인할 수 있다.

image

-> RequestFacade@의 값이 매번 다름

요청

String username = request.getParameter("username");
System.out.println("username = " + username);
  • 쿼리 파라미터의 값을 쉽게 받아올 수 있도록 한다.
    -> ex) localhost:8080/hello?username=kim
  • 위 사진에서 봤던 것처럼, username = kim 글자가 찍혀서 출력됨.

응답

// contentType -> header 정보에 들어가게 됨.
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");

response.getWriter().write("hello" + username); // http body에 값 할당

image image

  • 개발자 도구를 켜서 보게 되면 Response Header과 Body에 값이 잘 들어갔음을 확인할 수 있다. (text/plain(Header), utf-8(Header), hellokim(Body))

✨ HttpServletRequest

: Http 요청 메시지를 편리하게 조회할 수 있도록 해 준다

  • Start Line : Http 메서드, URL, 쿼리 스트링, 스키마, 프로토콜
  • Header : 헤더 조회
  • Body : form 파라미터 형식 조회 message body 데이터 직접 조회

✨ HTTP 요청 메시지를 통해 메시지를 전달하는 방법

: 클라이언트 -> 서버

1. GET - 쿼리 파라미터

  • 메시지 바디 없이, url의 쿼리 파라미터에 데이터를 포함해 전달
    ex) 검색, 필터, 페이징 등에서 많이 사용
  • 시작은 ?, 추가 파라미터는 &

전체 파라미터 조회

request.getParameterNames().asIterator()
      .forEachRemaining(paramName -> System.out.println(paramName  + " = " + request.getParameter(paramName)));
  • paramName으로 key 값을, getParameter()로 value 값을 꺼내올 수 있다.

단일 파라미터 조회

String name = request.getParameter("name");
  • 아까 전 전체 파라미터에서는 asIterator()로 하나씩 뽑아냈다면, 단일 파라미터에서는 getParameter()을 하나만 활용해 하나의 값을 뽑아낸다.

참고로, name=hello&name=hello2처럼, 값을 중복해서 넘길 수도 있다. 그러나, 덮어씌워지는 문제가 발생하기 때문에 getParameterValues()를 활용해 이를 해결한다.

String[] usernames = request.getParameterValues("username");
  for (String username : usernames) {
    System.out.println("username = " + username);
  }

2. POST - HTML form

  • content-type : application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파라미터 형식으로 전달 username=hello&age=20
    ex) 회원 가입, 상품 주문, HTML Form 사용

request.getParameter은 GET 방식의 쿼리 파라미터와 POST 방식의 HTML form 방식을 모두 지원한다. 따라서, 1번 방식과 2번 방식 모두 getParameter()을 사용하면 된다.

3. HTTP message body에 데이터를 직접 담아 요청

  • HTTP API에서 주로 사용, JSON, XML, TEXT
  • 데이터 형식은 주로 JSON 사용
  • POST, PUT, PATCH

요즘은 거의 JSON으로 사용한다.

ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
  • ServletInputStream 을 사용하면 데이터를 쉽게 읽어올 수 있다.

그러나 이렇게 출력하게 되면, JSON 또한 결국 문자이기 때문에, JSON 형식임을 인지하지 못하고 그대로 출력하게 된다.

이를 파싱해주기 위해서는 jackson 라이브러리가 필요하다.

Jackson

  • Jackson 은 자바 객체와 JSON 데이터 간의 변환을 쉽게 처리할 수 있는 강력한 라이브러리로, JSON 직렬화(serialization) 및 역직렬화(deserialization)를 지원한다.

즉, Java Object를 JSON으로 변환하거나 JSON을 Java Object로 변환하는 데 사용할 수 있는 Java 라이브러리이다.

선언

private ObjectMapper objectMapper = new ObjectMapper();

사용

objectMapper.readValue(messageBody, HelloData.class);

여기서 HelloData는 미리 만들어 둔 객체로, 내용은 다음과 같다.

import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class HelloData {

    private String username;
    private int age;
}

✨ HttpServletRespose

HttpServletResponse는 HTTP 응답 메시지를 생성해준다.

  • HTTP 응답코드 지정
  • 헤더 생성
  • 바디 생성

추가로, Content-Type, 쿠기, Redirect와 같은 편의 기능도 제공된다.

HTTP 응답코드 지정

response.setStatus(200);
response.setStatus(HttpServletResponse.SC_OK);

둘다 같은 의미지만, 두 번째를 사용하면 상수로 지정해 둠으로써 의미를 더 명확히 파악 가능하다는 장점이 있다.

✨ HTTP 응답 메시지를 보내는 법

1. 단순 텍스트 응답

PrintWriter writer = response.getWriter();
writer.println("ok");

직접 java 코드를 쳐서 보냄

2. HTML 응답

writer.println("<html>");
writer.println("<body>");
writer.println("    <div>안녕?</div");
writer.println("</body>");
writer.println("</html>");

서블릿을 사용할 때는 직접 html 코드를 쳐야 한다.

3. HTTP API - MessageBody JSON 응답

✨ 참고자료

https://velog.io/@tjfdbfls/프로젝트Spring-Jackson-라이브러리란-JSON-데이터-처리

카테고리:

업데이트: