본문 바로가기
Back-end/Spring MVC 개념

4. Servlet - 요청/응답 처리방법

by devraphy 2022. 2. 25.

0. 개요

- Servlet 사용법을 자세히 배우기 전에, 우선 기본적인 HTTP 지식에 대해 알아보자.

- 그다음에 Servlet이 HTTP request와 response를 어떻게 처리하는지에 대해 알아보자. 


1. 웹 서비스의 HTTP 요청과 응답 

a) GET 방식

- 데이터를 url 파라미터(= 쿼리 파라미터)로 전달하는 방식

- 검색, 필터, 페이징 등에서 자주 사용하는 방식이다. 

https://devraphy.tistory.com?category=Back-end&id=123

- 위의 예시를 보면, 물음표를 기점으로 쿼리 파라미터를 작성한 부분이라는 것을 알 수 있다.

- category라는 이름의 파라미터에는 Back-end라는 값이 매핑된다.

- id라는 이름의 파라미터에는 123이라는 값이 매핑된다.

- 쿼리 파라미터로 전달되는 값은 모두 String 자료형이다. 

b) POST 방식 - <Form> 태그 사용

- HTTP 메시지 바디에 쿼리 파라미터를 저장하여 전달하는 방식으로, 

- server에게 전달하는 데이터가 url에 노출되면 안 되는 경우 사용하는 방식이다. 

 

- 일반적으로 HTML의 <Form> 태그를 사용하여 데이터를 전달할 때, 이 방식으로 전달된다. 

- 이 경우, HTTP 헤더에 content-type의 값이 application/x-www-form-urlencoded로 되어있다.

- 즉, <Form> 태그로부터 데이터가 전달되었다고 판단할 수 있다. 

c) HTTP message body

- HTTP 메시지 바디에 데이터를 담아서 전달하는 방식

- 주로 HTTP API 또는 RESTful API에서 사용하는 방식이다.

- JSON, XML, Text 데이터 형식을 사용할 수 있으나, 주로 JSON 형식을 사용한다.

- POST, PUT, PATCH와 같은 HTTP 메서드를 사용한다. 

 

- 여기까지 웹 서비스에서 사용되는 HTTP 요청과 응답 형태에 대해서 알아보았다.

- 이제부터는 위에서 설명한 3가지 방식을 Servlet이 어떻게 처리하는지 알아보자.


2. Servlet의 요청 데이터 조회

- Servlet은 HttpServletRequest를 사용하여 client의 Request 메시지를 객체로 만든다.

- 그렇다면 Service() 메서드 내부에서 request 객체가 가진 값을 어떻게 조회하는지 알아보자. 

a) HttpServletRequest.getParameter() - 쿼리 파라미터 조회

@WebServlet(name = "helloServlet", urlPatterns = "매핑할 url주소")
public class HelloServlet extends HttpServlet{

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 단일 파라미터의 값 조회 ex) www.tistory.com?username=devraphy
        String param = request.getParameter("username"); // "devraphy" 반환
        
        // 2. 동일 파라미터의 복수 값 조회 ex) www.tistory.com?nickname=raphy&nickname=rapha
        String[] params = request.getParameterValues("nickname"); // ["raphy", "rapha"] 반환
        
        // 3. 전체 파라미터의 값 조회 ex) www.tistory.com?username=devraphy&nickname=raphy
        // 모든 쿼리 파라미터의 값을 Enum 자료형으로 반환한다. 그러므로 iterator를 사용한다.
        request.getParameterNames().asIterator()
                        .forEachRemaining(paramName -> System.out.println(paramName + ": "
                                + request.getParameter(paramName))); 
        
    }
}

- GET 방식 또는 <Form> 태그로 전달된 request의 데이터를 조회하는 방법으로 getParameter()를 사용한다.

 

- <Form> 태그는 POST 메서드로 전달된 request 다.

- 그러므로 왜 다른 형식으로 보내진 reuqest 데이터를 동일한 메서드로 조회할 수 있는지 의문이 들 것이다.

 

- <Form> 태그를 사용하면 HTTP 메시지 바디에 쿼리 파라미터가 저장된다.

- 쿼리 파라미터라는 데이터의 형식이 GET 방식과 동일하기 때문에 같은 메서드를 사용하여 조회할 수 있다.

- 즉, getParameter()는 GET 방식과 <Form> 태그로 부터 넘어온 request만 조회할 수 있다.

b) HTTP message body 조회 

@WebServlet(name = "helloServlet", urlPatterns = "url 매핑 주소")
public class HelloServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. request의 body 내용을 바이트코드로 얻어옴
        ServletInputStream inputStream = request.getInputStream();

        // 2. 받아온 바이트코드를 문자열로 변환, 엔코딩 형식 기입해야함
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

    }
}

- 우선 HTTP message body의 데이터를 읽기 위해서는 inputStream을 사용해야 한다.

- HTTP message body의 내용은 바이트 코드로 작성되어 있기 때문이다.

 

- 받아온 바이트 코드를 문자열로 변환하는데, 이때 StreamUtils의 copyToString() 메서드를 사용한다.

- copyToString() 메서드에는 문자열로 변환할 대상과 변환 형식(= 엔코딩)을 매개변수로 받는다.

- 엔코딩 형식은 상수로 제공된다.


3. Servlet의 응답 반환 

- Servlet에서 어떻게 response를 처리하는지에 대해서 알아보자.

a) Response - 일반 text를 반환

@WebServlet(name = "helloServlet", urlPatterns = "url 매핑 주소")
public class HelloServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 1 header의 content-type 및 인코딩 형식 설정
        resp.setHeader("Content-Type", "text/plain;charset=utf-8");
        
        // 2. response 객체를 이용한 Text를 반환할 객체를 생성 
        PrintWriter writer = resp.getWriter();
        
        // 3. client에게 text를 반환
        writer.println("HTTP response 테스트");
    }
}

 - response message의 헤더를 text 형식으로 설정한다.

- 그다음 response객체를 이용하여 writer 객체를 생성한다.

- writer 객체를 이용하여 client에게 전달하고 싶은 text를 반환한다.

- client는 해당 text를 response로 전달받고, 브라우저에 출력한다. 

b) Response - HTML 반환 

@WebServlet(name = "helloServlet", urlPatterns = "매핑 url")
public class HelloServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        // 1. response 헤더 설정 
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        
        // 2. response 객체를 이용한 writer 객체 생성 
        PrintWriter writer = response.getWriter();
        
        // 3. HTML 반환
        writer.println("<html>");
        writer.println("<body>");
        writer.println("<div> 안녕 </div>");
        writer.println("</body>");
        writer.println("</html>");

    }
}

- HTML을 응답하는 것은 text를 응답하는 방법과 차이가 없다.

- 다만, HTML을 위의 예시처럼 일일이 작성하여 전달해야 한다는 불편함이 있다.

- 이처럼 view를 처리해야 한다는 것이 Servlet을 사용하는 데에 있어서 가장 불편한 점이다.

c) Response - JSON 반환

@Getter @Setter
public class HelloData  { // JSON 반환에 사용할 데이터 형식

    private String username;
    private int age;

}
@WebServlet(name = "helloServlet", urlPatterns = "url 매핑 주소")
public class HelloServlet extends HttpServlet {

	// 1. 반환 데이터를 JSON 형식으로 바꿔주는 역할
    private ObjectMapper objectMapper = new ObjectMapper();


    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        // 2. Response 헤더 설정 
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        
        // 3. 반환 데이터 설정 
        HelloData helloData = new HelloData();
        helloData.setUsername("Raphael");
        helloData.setAge(20);

        // 4. json형식으로 parsing
        String result = objectMapper.writeValueAsString(helloData);
        
        // 5. response 객체에 담아 client에게 전달
        response.getWriter().write(result);

    }
}

- 위의 예시 코드와 같이, JSON 반환 시 사용할 데이터 형식을 따로 클래스로 만들어 사용할 수 있다.

 

- 여기서 핵심이 되는 부분은 ObjectMapper이다.

- resposne body에 담기는 데이터는 String 형식이므로 이를 JSON 형식으로 바꿔줘야 한다.

- 이때 ObjectMapper의 writeValueAsString() 메서드를 사용하여 변환할 수 있다.

 

- JSON을 전달받은 client는 이를 브라우저에 다음과 같이 출력한다.

 

'Back-end > Spring MVC 개념' 카테고리의 다른 글

6. MVC 1의 등장  (0) 2022.03.01
5. JSP의 등장  (0) 2022.02.28
3. Servlet - 기본 사용 방법  (0) 2022.02.24
2. Servlet의 등장  (0) 2022.02.23
1. Java 웹 기술의 역사  (0) 2022.02.22

댓글