Servlet - response(응답)

최준호·2021년 7월 6일
0

Spring

목록 보기
11/47

HTTP 응답 메세지 생성

HTTP Response에서 우리가 해야할 작업은

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

다음과 같다. 그럼 코드로 위의 작업들을 어떻게 수행하는지 확인해보자.

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "responseHeaderServlet", urlPatterns = "/response-header")
public class ResponseHeaderServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //status-line
        response.setStatus(HttpServletResponse.SC_OK);    //http 응답코드 200으로 적어도 되지만 이미 선언되어있는 상수를 사용하는게 의미 있는 값으로 사용할 수 있음.

        //response-header
        //response.setHeader("Content=Type", "text/plain;charset=urf-8"); //응답하는 데이터의 타입
        response.setHeader("Cache=Control", "no-cache, no-store, must-revalidate"); //캐시를 저장하지 않게
        response.setHeader("Pragma", "no-cache");   //캐시를 저장하지 않게2
        response.setHeader("my-header", "hello");   //커스텀 헤더

        //header 편의 메서드
        content(response);
        cookie(response);
        //redirect(response);

        //message body
        PrintWriter writer = response.getWriter();
        writer.write("ok");
    }

    private void content(HttpServletResponse response) {
        //Content-Type: text/plain;charset=utf-8
        //Content-Length: 2

        //response.setHeader("Content-Type", "text/plain;charset=utf-8");

        response.setContentType("text/plain");
        response.setCharacterEncoding("utf-8");
        //response.setContentLength(2); //(생략시 자동 생성)
    }

    private void cookie(HttpServletResponse response) {
        //Set-Cookie: myCookie=good; Max-Age=600;

        //response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");

        Cookie cookie = new Cookie("myCookie", "good");
        cookie.setMaxAge(600); //600초
        response.addCookie(cookie);
    }

    private void redirect(HttpServletResponse response) throws IOException {
        //Status Code 302
        //Location: /basic/hello-form.html

        //response.setStatus(HttpServletResponse.SC_FOUND); //302
        //response.setHeader("Location", "/basic/hello-form.html");

        response.sendRedirect("/basic/hello-form.html");
    }
}
  1. HTTP 응답코드 지정
  • response.setStatus("응답코드")로 응답코드를 지정할 수 있다. 상수이므로 우리가 직접 200이나 304, 404, 500으로 직접 넣어줘도 되지만 사람은 항상 실수를 하고 반복한다. 그렇기 때문에 오타가 나서 오류가 나지 않도록 제공되는 의미 있는 상수를 사용하는 것이 오류를 최소화 시킬수 있다.
  1. 헤더 생성
  • response.setHeader("key", "value")로 헤더를 생성하고 응답할 수 있다. 기본 지정된 내용 뿐만 아니라 개발자가 추가로 넣고 싶은 내용 또한 만들어 넣을 수 있다.
  1. 바디 생성
  • response.getWriter()를 통해 writer 객체를 얻고 해당 객체를 통해 write나 print를 통해 response body message를 생성하여 응답할 수 있다.
  1. 편의 기능 제공
  • Content-Type
    • content type에 대한 정보를 코드에서 직접 setHeader를 통해 지정해도 되지만 response.setContentType()과 setCharacterEncoding()을 통해 좀 더 간결하고 눈에 보이기 쉽게 값들을 지정할 수 있다.
  • 쿠키
    • client에서 사용되는 쿠키를 setHeader로 지정할 수 있지만 지정해야하는 내용이 너무 많고 복잡하다. Cookie라는 객체를 제공해주므로 해당 객체를 사용하여 값들을 세팅하여 addCookie(쿠키)로 간단하게 쿠키를 생성하여 전달할 수 있다.
  • redirect
    • redicet도 304 상태코드를 반환함과 동시에 header에 location url 정보를 내보내면 페이지에서 rediect가 일어난다. 하지만 이것도 간단하게 response.sendRedicet("url")로 상태코드도 세팅할 필요 없이 간단하게 전달할 수 있다.

html 응답 예시

우리가 웹 프로젝트를 사용하면 api 통신이 아닌 내부 통신의 경우 html 소스를 그대로 반환해야하는 경우가 있다. 이럴때 servlet에서 html 코드를 어떻게 처리해주는지 확인하는 예시를 코드로 보자.

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;
import java.io.PrintWriter;

@WebServlet(name = "responseHtmlServlet", urlPatterns = "/response-html")
public class ResponseHtmlServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Content-Type: text/html; charset=utf-8
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        PrintWriter writer = response.getWriter();
        writer.println("<html>");
        writer.println("<body>");
        writer.println("    <div>hi 에이치 아이</div>");
        writer.println("</body>");
        writer.println("</html>");
    }
}

간단해 보이지만 우리가 사실 저렇게 간단한 html을 보내진 않는다... 엄청나게 복잡한 html 소스를 보낼텐데 그걸 다 저렇게 해줘야하는 것이다. 서블릿 너무 감사하다... 하여튼 저런식으로 소스를 response를 보내면

이런 결과를 얻을 수 있는데. 아까 메세지 바디에 텍스트만 담은것과 차이가 없다고 생각할 수 있다. 하지만 소스보기를 눌러 보거나 개발자 도구를 켜서 response를 확인해 보면

다음과 같이 html 소스가 그대로 내려온 것을 확인할 수 있다.

json 응답 예시 (api 방식)

위의 html로 응답하는 방법도 있지만 요즘 가장 많이 사용되는 api 방식으로 응답하는 방법도 있다. 이것도 소스로 확인해보자!

import com.fasterxml.jackson.databind.ObjectMapper;
import hello.servlet.basic.HelloData;
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 = "responseJsonServlet", urlPatterns = "/response-json")
public class ResponseJsonServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Content-Type: application/json
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

        HelloData helloData = new HelloData();
        helloData.setUsername("choi");
        helloData.setAge(28);

        //{"username":"choi", "age":28}
        String result = objectMapper.writeValueAsString(helloData);//class를 파싱하여 json 형식 string으로 변환
        response.getWriter().write(result);
    }
}

방법은 똑같은데 우리가 세팅해주는 방법이 좀 달라진다. 먼저 Content-Type을 application/json으로 세팅해줘야하고 응답하는 데이터를 직접 손으로 {"key":"value"} 형식의 String을 만들어서 보내도 되겠지만 ㅎㅎ 우리는 class를 만들어서 json library를 통해 파싱하여 데이터를 간단하게 변환할 수 있으니까 저번에 사용했던 helloData를 통해 값을 세팅하고 jackson을 통해서 String으로 변환 후 response에 담아서 내보내면 된다. 이건 그냥 단순한 json으로 응답하는 과정을 만들어 봤다.

출처 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글