스프링 공부 (인프런 김영한 선생님)/스프링 MVC 1편

[스프링 웹 MVC 1편] 6. HTTPServletResponse - 기본 사용법

ProgYun. 2023. 5. 20. 12:23

HTTPServletResponse는 HTTP 응답 메세지 생성에 더해 편의기능을 제공합니다.

여러가지 메서드를 이용해서 HTTP 응답코드를 지정하고, 헤더를 생성하거나 바디를 생성할 수 있습니다.

그에 더해, Content-Type 지정, 쿠키 설정, 리다이렉트에 관한 정보를 지정할 수 있습니다

 

코드를 통해 자세한 사용법에 대해 알아봅니다

package hello.servlet.basic.response;

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


@WebServlet(name = "responseHeaderServlet", urlPatterns = "/response-header")
public class ResponseHeaderServlet extends HttpServlet {

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

        response.setStatus(HttpServletResponse.SC_OK);

        //[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"); // custom header


    }

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

    private void cookie(HttpServletResponse response){
        Cookie cookie = new Cookie("myCookie", "good");
        cookie.setMaxAge(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");
        // 위 두 줄의 내용이 한번에 하단부 .sendRedirect 메소드를 통해 한번에 입력될 수 있음.


        response.sendRedirect("/basic/hello-form.html");
    }

}

response.setStatus() 를 통해 응답코드를 생성할 수 있다.

HttpServletResponse를 타고 들어가보면 많은 코드들이 상수로 선언되어있는것을 알 수 있는데

가독성 측면에서 상수로 선언된 것이 숫자로 선언한 것 보다 더 좋다.

 

response.setHeader()의 경우 Key, Value 형태로 Argument가 들어간다.

위 코드와 같이 request.setHeader("Content-type", "text/plain;charset=utf-8) 로 설정하면

헤더의 Content-Type 필드가 text/plain;charset=utf-8로 세팅되는 것을 알 수 있다.

 

이러한 기본 필드 외에도 response.setHeader("my-header","hello) 처럼 직접 헤더 필드를 만들어서 값을 넣어줄 수 있다.

 

pragma의 no-cache 설정은 캐시를 무효화하는것을 말한다 - 자세한 내용은 HTTP 스펙 참고


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

 HTTP 응답 메세지는 주로 다음 세가지로 분류된다

1) 단순 텍스트 응답

2) HTML 응답

3) HTTP API - Message Body JSON 응답

 

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

 

package hello.servlet.basic.response;

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

@WebServlet(name = "responseHtmlServlet", urlPatterns = "/response-html")
public class ResponseHtmlServlet extends HttpServlet {

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

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

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

    }
}

HTTP 응답 데이터 - JSON API

Jackson 라이브러리가 제공하는 ObjectMapper를 사용해야하지만

Request와는 다르게 우리가 직접 데이터를 가공해서 보내는 것이기 때문에,

ObjectMapper 객체를 새로 생성해줘야하고 objectMapper.writeValueAsString()을 사용하여 객체를 JSON 문자로 변경할 수 있다.

package hello.servlet.basic.response;

import com.fasterxml.jackson.databind.ObjectMapper;
import hello.servlet.basic.HelloData;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "responseJsonServlet", urlPatterns = "/response-json")
public class ResponseJsonServlet extends HttpServlet {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        response.setHeader("content-type", "application/json");
        response.setCharacterEncoding("utf-8");

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

        String result = objectMapper.writeValueAsString(data);

        response.getWriter().write(result);
    }
}

HTTP 응답으로 JSON을 반환하면 Content-Type를 Application/json으로 지정해야한다.

Jackson 라이브러리가 제공하는 객체를 사용하면 객체를 JSON 문자로 변경할 수 있다.

 

추가로 json은 utf-8을 지원하지 않는다. 스펙에서 charset=utf-8과 같은 파라미터를 지원하지 않기 때문에,

application/json이라고만 사용해야지 application/json;charset=utf-8이라고 하는 것은 의미 없는 파라미터를 추가한게 되고

response.getWriter()를 사용하면 추가 파라미터를 자동으로 추가해버리는데 이때는 response.getOutputStream()으로 출력하게 되면 그런 문제가 없어진다