SPRING/Spring MVC

HTTP 요청 데이터와 응답 데이터 입력

요청 메시지 데이터(HttpServletRequest)

이제 본격적으로 데이터를 입력해 봅시다.

 

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

  • 쿼리 파라미터(GET)
  • HTML Form (POST)
  • API 메시지 바디(POST, PUT,...)

 

쿼리 파라미터를 통해 전달

인터넷에 아무 검색이나 해봅시다. 그런 뒤 URI을 보면

https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=쿼리파라미터

물음표(?) 뒤 'name=value' 형태로 되어 있는 것을 알 수 있습니다. 이를 쿼리 파라미터라고 하는데 해당 요소들을 통해 요청 메시지에 데이터를 담을 수 있습니다.

  • 물음표(?)로 시작한다.
  • 앰퍼샌드(&)를 통해 여러 파라미터를 입력할 수 있다. itemname=book&stock=200

 

해당 요청 메시지의 쿼리 파라미터를 얻기 위해서는. getParameter("파라미터 명")이라는 메서드를 사용해야 합니다.

 

@WebServlet(name = "requestParamServlet", urlPatterns = "/helloParameter")
public class RequestParamServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("===전체 파라미터 조회===");
        req.getParameterNames().asIterator()
                .forEachRemaining(paramName -> System.out.println(paramName + "=" + req.getParameter(paramName)));

        System.out.println();

        System.out.println("===이름이 같은 복수 파라미터 조회===");
        String[] items = req.getParameterValues("item");
        for (String item : items) {
            System.out.println("item = " + item);
        }
    }
}
  • getParameterNames( ) : 파라미터 전체를 조회하는 메서드입니다.
  • getParamterValues( ) : 같은 파라미터 명에서 여러 값을 가질 수 있습니다. 이 경우에 사용하는 메서드입니다.
    • ex : item=book&item=pen => book, pen 리턴.

 

 

HTML Form을 통해 전달

본격적으로 메시지 바디를 활용할 차례입니다. 따로 자바 코드를 사용하는 것이 아닌 HTML을 사용하는 HTML Form

방식은 메시지 바디에 쿼리 파라미터 형식으로 전달하는 방식입니다!

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/helloParameter" method="post">
    itemname: <input type="text" name="itemname" />
    stock: <input type="text" name="stock" />
    <button type="submit">전송</button>
</form>
</body>
</html>
  • 위치만 다를 뿐이지 쿼리 파라미터 형식으로 전달되는 것은 똑같기 때문에 쿼리 파라미터의 URL로 설정합시다.
  • 단 메시지 바디로 전송은 GET은 절대 안 됩니다. POST 메서드를 사용합시다.
  • Content-Type : 'application/x-www-form-urlencoded'입니다.

 

 

API를 사용해 메시지 바디 전송

HTTP API를 통해 단순 텍스트부터, XML, JSON까지 전송을 가능케 할 수 있습니다.

이 기능의 최대 장점은 객체를 매핑할 수 있다는 것입니다!

 

1) 단순 텍스트

단순 텍스트를 전송하고 그 요청 메시지를 받아봅시다.

@WebServlet(name = "requestApiStringServlet", urlPatterns = "/api-string")
public class RequestApiStringServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
        ServletInputStream inputStream = req.getInputStream(); // 바이트 코드 얻기
      
        // 얻은 바이트코드를 문자열로 변환
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
    
        System.out.println("messageBody = " + messageBody);
    }
}
  • content-type : 'text/plain'

 

2) JSON 형식 전송

JSON은 name:value 형식의 집합입니다. (XML 형식을 더 간소화한 버전이라고 생각하시면 됩니다.)

이 형식의 가장 중요한 점은

JSON 형식을 객체로 매핑할 수 있어야 하고, 객체를 JSON 형식으로 매핑 역시 할 수 있어야 합니다.

 

이번 케이스에서는 JSON 형식으로 받은 메시지 바디를 객체로 매핑해 봅시다.

 

먼저 바로 객체로 매핑하면 의존관계가 형성되기 때문에 DAO와 같은 역할을 하는 ItemData를 만듭시다.

@Getter @Setter
public class ItemData {
    private String name;
    private int stock;
}

 

객체를 매핑하기 위해서는 Jackson, Gson과 같은 라이브러리가 필요합니다.

스프링 부트의 MVC에서는 Jackson을 기본 라이브러리로 제공합니다.

@WebServlet(name = "requestApiJsonServlet", urlPatterns = "/api-json")
public class RequestApiJsonServlet extends HttpServlet {
    // JSON 데이터를 객체로 변환해줄 오브젝트 매퍼
    private ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
        ServletInputStream inputStream = req.getInputStream();
        String messageBody = StreamUtils.copyToString(intputStream, StandardCharsets.UTF_8);
        
        // Json 파일 데이터와 객체 필드명을 비교해서 매핑
        ItemData itemData = objectMapper.readValue(messageBody, ItemData.class);
        
        String name = itemData.getName();
        int stock = itemData.getStock()
    }
}

 

 

응답 메시지 데이터(HttpServletResponse)

요청 메시지의 정보를 가져왔다면 이번에는 응답 메시지를 만들어 봅시다.

 

1. 시작 줄, 헤더

응답 메시지의 메시지 바디를 입력하기 전에, 시작 줄과 헤더를 채워야 합니다!

=============== 응답 메시지 ====================
  <버전> <401> <상태코드>    ==> 시작줄(상태줄)
  <헤더>                    ==> 헤더
  <메시지 바디>             ==> 본문
@WebServlet(name = "responseHeaderServlet", urlPatterns = "/header")
public class ResponseHeaderServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
    	// 상태코드
    	resp.setStatus(HttpServletResponse.SC_OK);
        
        // 헤더 설정
        resp.setHeader("Content-Type", "text/plain;charset=utf-8");
        resp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        resp.setHeader("Pragma", "no-cache")
        resp.setHeader("custom-header","hello")	// 커스텀한 헤더를 작성할 수 있습니다.
	}
}

Plus. 편의 메서드

일일이 헤더를 입력하는 것 말고 더욱 쉽게 정보들을 입력하는 메서드들이 있습니다.

기존 메서드 펀의 메서드
resp.setHeader("Content-Type", "text/plain;charset=utf-8") resp.setContentType("text.palin");
resp.setCharacterEncoding("utf-8");
쿠키 설정
response.setHeader("Set-Cookie",

"cookieName=value;Max-Age=600")
Cookie cookie = new Cookie("cookieName", "value");
cookie.setMaxAge(600);
response.addCookie(cookie)
리다이렉트 응답코드 302
response.setStatus(HttpServletResponse.SC_FOUND);
response.sendRedirect("/basic/hello-form.html")
리다이렉트 위치 설정
response.setHeader("Location", "/index")

 

 

2. 메시지 바디 생성

본격적으로 메시지 바디를 만들어 봅시다! 방법은 크게 3가지입니다.

  • 단순 텍스트
  • HTML
  • API 메시지 바디

 

단순 텍스트

writer.println("") 방식으로 입력하면 됩니다.

HTML과 같이 살펴보겠습니다.

 

HTML

HTML 방식은 자바 코드에 HTML을 직접 입력하는 것입니다. (여기서 JSP와 차이점이 나뉘게 됩니다.)

// 응답 메시지는 메시지 바디가 있기 때문에 Content-Type 설정을 해 주어야 한다.
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");

// HTML을 자바코드에 입력!
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println(" <div>Hello Servlet!</div>");
writer.println("</body>");
writer.println("</html>");

일일히 html을 입력해야 한다니.. 딱 봐도 엄청 귀찮아 보입니다. 

그리고 컴파일러가 실수를 잡아내주지도 못합니다. 이를 개선한 것이 바로 HTML에 java코드를 입력하는 JSP 입니다.

JSP는 나중에 다시 한번 언급하겠습니다.

 

API 메시지 바디

요청 메시지에서 했던 대로 ObjectMapper가 필요합니다.

response.setHeader("content-type", "application/json");
response.setCharacterEncoding("utf-8");
        
// 객체 정보를 가져와서
ItemData data = new ItemData();
itemData.setName("book");
itemData.setStock(200);
        
// JSON 형식으로 변환!
String result = objectMapper.writeValueAsString(data);   //{"name":"book","stock":200}
response.getWriter().write(result);
  • Content-Type : application/json
  • JSON 형식을 객체로 변경하는 readValue( ) 메서드와 다르게 writeValue( ) 메서드를 통해 JSON 형식으로 변환.

'SPRING > Spring MVC' 카테고리의 다른 글

서블릿, JSP, MVC  (0) 2021.11.02
MVC 사용 전 서블릿  (0) 2021.11.01