Lined Notebook

[스프링 MVC - 백엔드 웹 개발 기술] 08. HttpServletResponse와 HTTP 응답 방식 - TEXT, HTML, API JSON

by ymkim

01. HttpServletResponse - 기본 사용법

01-1. HttpServletResponse 역할

  • 개발자가 일일이 HTTP 응답 메시지를 생성하기에는 힘들다
  • 서블릿은 HTTP 응답 메시지 생성하는 역할을 담당
    • HTTP 응답코드 지정
    • 헤더 생성
    • 바디 생성
  • 편의 기능 제공
    • Content-Type
    • 쿠키
    • Redirect

01-2. HttpServletResponse - 기본 사용법

package hello.servlet.basic.response;

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 = "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);

        // [response-header] - header 값 셋팅
        response.setHeader("Content-Type", "text/plain;charset=utf-8"); // 내용 정보
        response.setHeader("Cache-Control", "no cache, no-store, must-revalidate"); // HTTP 1.1 캐싱 방지
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0 캐싱 방지
        response.setHeader("my-header", "hello"); // 커스텀 헤더

        PrintWriter writer = response.getWriter();
        writer.println("OK");
    }
}
  • ResponseHeaderServlet 클래스 생성 후 /response-header 라는 URL 요청 시 Service 로직을 호출하게 한다
  • 위와 같이 Header 정보를 지정하면 개발자 도구를 통해 확인 가능하다
  • Content-Type : text/plan;charset=utf-8
    • 응답 콘텐츠의 유형 지정
    • 여기서는 text/plain으로 응답하고 인코딩(enc)은 utf-8로 반환
  • Cache-Control : no cache, no-store, must-revalidate
    • 캐시 제어자에 관련된 지시자를 설정
    • no cache
      • 응답 캐시 안함
    • no-store
      • 캐시 응답 저장 안함
    • must-revalidate
      • 캐시된 리소스 유효성 검증
  • Pragma : no-cache
    • HTTP 1.0 호환 위해 사용

01-3. HttpServletResponse 편의 메서드 - ContentType

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"); // 응답 데이터 인코딩 지정
}

 

  • 다음과 같이 setHeader를 사용할 수도 있지만, setContentType이나 setCharacterEncoding을 사용할수도 있다
    • response.setHeader(”Content-Type”, “text/plain;charset=utf-8”)
    • response.setContentType(”text/plain”);
    • response.setCharacterEncoding(”UTF-8”);

01-4. HttpServletResponse 편의 메서드 - Cookie

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); //쿠키 추가
}
  • AS-IS
    • response.setHeader(”Set-Cookie”, “mycookie=good; Max-Age=600”);
  • TO-BE
    • Cookie cookie = new Cookie(”myCookie”, “good”);
    • cookie.setMaxAge(600);
    • response.addCookie(cookie);

01-5. HttpServletResponse 편의 메서드 - redirect

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"); // 위랑 동일함
}
  • AS-IS
    • response.setStatus(HttpServletResponse.SC_FOUND); // 302 - redirect
    • response.setHeader(”Location”, “url”);
  • TO-BE
    • response.sendRedirect(”url”);

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

  • HTTP 응답 메시지는 주로 다음 내용을 담아서 전달 한다
    • 단순 텍스트 응답
      • 앞에서 살펴봄 (writer.printlng(”ok”))
      • "ok" 라는 문자열을 사용자의 화면에 출력한다
    • HTML 응답
      • 다음과 같은 HTML 태그를 직접 생성하여 화면에 내려준다 
      • <html><body><div>안녕하세요</div></body></html>
    • HTTP API - Message Body JSON 반환
      • {"name":"kim", "age":20} 와 같은 데이터를 내려준다

02-1. 서블릿으로 직접 HTML 랜더링

package hello.servlet.basic.response;

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"); // HTML
        response.setCharacterEncoding("utf-8"); // encoding type

        //Servlet은 자바 로직으로 HTML 을 만들어야 하기 때문에 불편한 점이 존재함
        PrintWriter writer = response.getWriter();
        writer.print("<html>");
        writer.print("<body>");
        writer.print("  <div>안녕</div>");
        writer.print("</body>");
        writer.print("</html>");
    }
}
  • 서블릿으로 HTML 표현하려면 위와 같이 직접 문자열로 태그 지정해야 함
  • 위와 같이 서블릿 자바 코드로 HTML을 표현하는 것은 너무나도 불편한 부분이다
    • 이러한 이유로 JSP > MVC 패턴 출시가 되었음

03. HTTP 응답 데이터 - API JSON

  • CSR(client side rendering)에서 가장 많이 사용되는 방식이다
  • APP 혹은 수 많은 다른 서비스에서 XML, JSON 데이터를 요청할때 사용하는 방식
  • 서버는 TEXT, HTML 페이지를 반환하는 것이 아닌, JSON 형태의 데이터를 반환

03-1. 서블릿으로 직접 JSON 반환하기

package hello.servlet.basic.response;

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 mapper = 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("kim");
        helloData.setAge("20");

        //{"username":"kim", "age":20}
        //convert vo to json string with objectmapper
        String result = mapper.writeValueAsString(helloData);
        response.getWriter().write(result);
    }
}
  • VO 객체를 JSON String으로 변환 하려면 Jackson lib가 제공하는 ObjectMapper를 사용하면 됨
  • HTTP 응답으로 JSON을 반환할 때는 content-type을 application/json으로 지정해야 함

form-data, x-www-form-urlencoded, raw 차이

[개발지식] form-data, x-www-form-urlencoded , raw 차이

“form-data”, “x-www-form-urlencoded”, “raw”는 서버로 HTTP 요청 바디를 인코딩하고 데이터 전송하는 세 방법

  • form-data (content-type: multipart/form-data)
    • 일반적으로 바이너리 형식 데이터(파일 같은)와 텍스트 데이터가 포함된 양식 제출 시 사용
    • 바이너리 데이터는 “Content-Disposition” 헤더로 식별되는 각각의 부분으로 요청 바디에 별도 전송
  • x-www-form-urlencoded (content-type: x-www-form-urlencoded)
    • 가장 널리 사용되며 일반적으로 간단한 텍스트 데이터 제출 시 사용
    • 데이터는 “&” 기호로 구분되는 키-값 쌍으로 인코딩됨
    • 각 키-값 은 “=” 기호로 구분 됨
  • raw
    • 요청 바디에서 데이터를 원시 형식으로 전송함
    • 서버는 해당 데이터 그대로 사용 가능
    • 주로 JSON, XML 데이터 전송 시 사용

블로그의 정보

기록하고, 복기하고

ymkim

활동하기