[스프링 웹 MVC 1편] 6. HTTPServletResponse - 기본 사용법
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()으로 출력하게 되면 그런 문제가 없어진다