[Spring] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 강의 정리 - 2

JJAM·2022년 9월 15일
0
post-thumbnail

📖 서블릿

📒 프로젝트 생성

프로젝트를 생성하기 위해 스프링 부트 스타터에서 다음과 같이 설정한다.

War를 사용하는 이유는 JSP를 사용하기 위함이다.

프로젝트를 열고, Lombok 라이브러리를 설치하고 어노테이션 처리 활성화를 해준다.

📒 Hello 서블릿

src/main/java/hello/servlet/ServletApplication

스프링이 자동으로 내 패키지를 포함한 모든 하위패키지에 있는 서블릿을 찾아 자동으로 서블릿 등록해주기 위해 @ServletComponentScan 어노테이션을 추가한다.

@ServletComponentScan // 서블릿 자동 등록
public class ServletApplication {

✏️ 서블릿 등록하기

src/main/java/hello/servlet/basic/HelloServlet

서블릿으로 등록하기 위해 @WebServlet 어노테이션을 추가한다.

// name: 서블릿 이름, urlPatterns: URL 매핑
// "/hello" 이 호출되면 서블릿 컨테이너는 해당 메서드 실행
@WebServlet(name = "helloServlet", urlPatterns = "/hello")

본격적으로 코드를 작성하기 위해 서비스 메서드를 추가한다.

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

쿼리 파라미터request 요청 메시지을 받기 위해, 쿼리 파라미터를 읽는 코드를 작성한다.

String username = request.getParameter("username");

http://localhost:8080/hello?username=kim에 들어가고 쿼리 파라미터로 받은 값을 출력해보면 정상적으로 쿼리 파라미터 값을 받은 것을 확인할 수 있다.

또한 response 응답 메시지를 보낼 수 있다.

response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().write("hello " + username); // HTTP 메시지 바디에 write

서블릿 컨테이너 동작 방식

📖 Request

📒 HttpServletRequest - 개요

HTTP 요청 메시지를 파싱한 결과를 HttpServletRequest 객체에 담아 제공하여, HTTP 요청 메시지를 편리하게 조회할 수 있다.

HTTP 요청 메시지

POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
  • START LINE
    HTTP 메소드, URL, 쿼리 스트링, 스키마, 프로토콜

  • 헤더
    헤더 조회

  • 바디
    form 파라미터 형식 조회, message body 데이터 직접 조회

HttpServletRequest 객체는 임시 저장소, 세션 관리 등 추가적인 여러 부가기능도 제공한다.

📒 HttpServletRequest - 기본 사용법

src/main/java/hello/servlet/basic/request/RequestHeaderServlet

서블릿 어노테이션을 추가한다.

@WebServlet(name = "requestHeaderServlet", urlPatterns = "/request-header")

START LINE 정보

request.getMethod() // 메서드
request.getProtocol() // 프로트콜
request.getScheme() // 스키마
request.getRequestURL() // 요청 url
request.getRequestURI()  // 요청 uri
request.getQueryString() // 쿼리 파라미터
request.isSecure() // 보안(https)

헤더 정보

HTTP 요청 메시지의 모든 헤더의 내용을 출력하기 위한 메서드를 만들어 내용을 확인한다.

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

모든 정보말고 원하는 헤더의 내용을 출력하기 위한 메서드도 만들어 내용을 확인할 수 있다.

request.getServerName() // 이름
request.getServerPort() // 포트

request.getLocales().asIterator() // 언어
                .forEachRemaining(locale -> System.out.println("locale = " + locale));
request.getLocale()

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

request.getContentType() // content 타입
request.getContentLength() // content 길이
request.getCharacterEncoding() // 인코딩

기타 정보

추가적으로 HTTP 메시지의 정보는 아닌 기타 정보들도 확인할 수 있다.

request.getRemoteHost()
request.getRemoteAddr()
request.getRemotePort()

request.getLocalName()
request.getLocalAddr()
request.getLocalPort()

📒 HTTP 요청 데이터 - 개요

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

GET - 쿼리 파라미터

  • /url?username=hello&age=20
  • URL의 쿼리 파라미터에 데이터를 포함해 전달
  • ex) 검색, 필터, 페이징

POST - HTML Form

  • 메시지 바디에 쿼리 파리미터 형식으로 전달
  • ex) 회원 가입, 상품 주문, HTML Form

HTTP message body

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

📒 HTTP 요청 데이터 - GET 쿼리 파라미터

메시지 바디 없이, URL의 쿼리 파라미터를 사용해서 데이터를 전달한다.

쿼리 파라미터는 URL에 ? 를 시작으로 보내고 추가 파라미터는 & 로 구분한다.

✏️ 전체, 단일 쿼리 파라미터 조회

src/main/java/hello/servlet/basic/request/RequestParamServlet

서블릿 어노테이션을 추가한다.

@WebServlet(name="requestParamServlet", urlPatterns = "/request-param")

전체 파라미터를 조회하는 메서드를 만들어, 파라미터의 key와 value를 출력하는 코드를 작성한다.

request.getParameterNames().asIterator()
                        .forEachRemaining(paramName -> System.out.println(paramName + "=" + request.getParameter(paramName)));

단일 파라미터를 조회하는 코드를 작성한다.

String username = request.getParameter("username");
String age = request.getParameter("age");

http://localhost:8080/request-param?username=hello&age=20로 파라미터를 전송하면 정상적으로 전체 파라미터와 단일 파라미터가 조회된다.

✏️ 복수 쿼리 파라미터 조회

이름이 같은 복수 파라미터 조회하는 방법은 아래 코드로 작성한다.

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

http://localhost:8080/request-param?username=hello&age=20&username=hello2 해당 파라미터를 전송하면 복수 파라미터가 조회된다.

📒 HTTP 요청 데이터 - POST HTML Form

HTML의 Form을 사용해서 클라이언트에서 서버로 데이터를 전송한다.

HTML Form

  • Content-Type: application/x-www-form-urlencoded
  • 메시지 바디쿼리 파리미터 형식으로 데이터를 전달 ex) username=hello&age=20

src/main/webapp/basic/hello-form.html 에 html Form을 추가하여 /request-param 로 데이터를 보내도록 코드를 작성한다.

Form에 내용을 입력하고 전송 버튼을 누르면 앞서 만든 RequestParamServlet 의 메서드가 호출되어 아래와 같이 파라미터가 조회된다.

application/x-www-form-urlencoded 형식은 GET 쿼리 파라미터 형식과 같아, 위에서 만든 쿼리 파라미터 조회 메서드를 그대로 사용하면 된다.

따라서 request.getParameter()GET 쿼리 파라미터, POST HTML Form 형식 둘 다 지원한다.

추가적으로 Postman을 사용하면 html을 만들 필요없이 쉽게 Test를 할 수 있다.

📒 HTTP 요청 데이터 - API 메시지 바디

API 메시지 바디

  • HTTP message body에 데이터를 직접 담아서 요청
  • HTTP API에서 주로 사용, 데이터 형식은 주로 JSON
  • POST, PUT, PATCH

✏️ 단순 텍스트

src/main/java/hello/servlet/basic/request/RequestBodyStringServlet

서블릿 어노테이션을 추가한다.

@WebServlet(name = "requestBodyStringServlet", urlPatterns = "/request-body-string")

그리고 HTTP 요청 메시지의 메시지 body를 가져오는 코드를 작성한다.

// body의 내용을 byte 코드로 가져옴
ServletInputStream inputStream = request.getInputStream();

// byte 코드를 string으로 바꿈
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

작성한 코드를 테스트 하기 위해 content-type: text/plain 형식의 단순 텍스트를 Postman으로 요청하면 정상적으로 동작한다.

✏️ JSON

HTTP API에서 주로 사용하는 JSON 형식으로 데이터를 전달하기 위해 우선 JSON 형식으로 파싱할 수 있게 HelloData라는 새로운 객체를 하나 생성한다.

src/main/java/hello/servlet/basic/HelloData

// lombok 라이브러리를 통해 getter, setter 코드 추가
@Getter @Setter
public class HelloData {
    private String username;
    private int age;
}

src/main/java/hello/servlet/basic/request/RequestBodyJsonServlet

서블릿 어노테이션과 앞서 나온 메시지 body를 가져오는 코드를 작성한다.

@WebServlet(name = "requestBodyJsonServlet", urlPatterns = "/request-body-json")

JSON 결과를 파싱해서 객체로 변환하기 위해 JSON 변환 라이브러리를 추가 한다.

private ObjectMapper objectMapper = new ObjectMapper();

그래서 JSON 변환 라이브러리로 메시지 body를 파싱할 객체를 읽고, 객체의 getter를 사용하여 값들을 출력한다.

HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);

Postman을 사용해 JSON 형식HTTP 요청 메시지를 보내고 출력 값을 보면 정상적으로 작동하는 것을 볼 수 있다.

📖 Response

📒 HttpServletResponse - 기본 사용법

HttpServletResponse 역할

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

✏️ HTTP 응답 메시지 생성

src/main/java/hello/servlet/basic/response/ResponseHeaderServlet

서블릿 어노테이션을 작성한다.

@WebServlet(name = "responseHeaderServlet", urlPatterns = "/response-header")

HTTP 응답 메시지에 넣을 값들을 작성한다.

//[status-line]
response.setStatus(HttpServletResponse.SC_OK); // http 응답코드 200

//[response-headers]
response.setHeader("Content-Type","text/plain;charset=utf-8");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("my-header","hello");

작성 후 위에서 작성한 응답 데이터들이 적상적으로 받은 것을 확인할 수 있다.
http://localhost:8080/response-header

✏️ 편의 기능 제공

HTTP 응답 메시지 생성에서 넣은 값들을 보다 편리하게 넣는 방법이 있다.

// Content 편의 메서드
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
// 쿠키 편의 메서드
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600); //600초
response.addCookie(cookie);
// redirect 편의 메서드
response.sendRedirect("/basic/hello-form.html");

Content 편의 메서드, 쿠키 편의 메서드, redirect 편의 메서드의 내용이 제대로 들어간 것을 확인할 수 있다.

📒 HTTP 응답 데이터

✏️ 단순 텍스트, HTML

src/main/java/hello/servlet/basic/response/ResponseHtmlServlet

서블릿 어노테이션을 작성한다.

@WebServlet(name = "responseHtmlServlet", urlPatterns = "/response-html")

응답 메시지의 헤더 값을 설정해 준다.

response.setContentType("text/html");
response.setCharacterEncoding("utf-8")

message bodyHTML 응답을 보내준다.

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

http://localhost:8080/response-html에 들어가면 다음과 같이 응답 데이터가 정상적으로 보내지는 것을 확인할 수 있다.

✏️ API JSON

src/main/java/hello/servlet/basic/response/ResponseJsonServlet

서블릿 어노테이션을 작성한다.

@WebServlet(name = "responseJsonServlet", urlPatterns = "/response-json")

헤더 값을 설정해 준다.

response.setHeader("content-type", "application/json");
response.setCharacterEncoding("utf-8");

username과 age 값을 넣어 HelloData 객체를 만든다.

HelloData helloData = new HelloData();
helloData.setUsername("kim");
helloData.setAge(20);

객체를 JSON 형식으로 변경하기 위해, JSON 변환 라이브러리인 ObjectMapper를 사용한다.

String result = objectMapper.writeValueAsString(helloData);
response.getWriter().write(result);

http://localhost:8080/response-json에 들어가면 아래와 같이 정상적으로 응답 데이터가 보내지는 것을 확인할 수 있다.


지금까지 김영한 - 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술(유료강의) 강의를 참고하여 서블릿 에 대해 공부하였다.

profile
☘️

0개의 댓글