본문 바로가기
Spring/스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

HttpServletRequest로 HTTP 요청 데이터 조회하기

by hk27 2022. 1. 18.
HTTP 요청 데이터는 어떻게 받아올까요?

 

안녕하세요.

오늘은 HttpServletRequest로 HTTP 요청 데이터를 어떻게 조회하는지 알아보겠습니다.

 

HTTP 요청 데이터

먼저 HTTP 요청 데이터에는 무엇이 있는지 알아봅시다.

클라이언트에서 서버로 요청을 보낼 때, 데이터를 전달하기 위해서 주로 3가지 방법을 사용합니다.

 

1. GET - 쿼리 파라미터

/url?username=hello&age=20처럼 메시지 바디 없이 URL에서 물음표 이하의 쿼리 파라미터에 데이터를 포함해서 전달하는 방식입니다.

검색, 필터, 페이징 등에서 많이 사용하는 방식입니다.

 

2. POST - HTML Form

메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달합니다.

content-type이 application/x-www-form-urlencoded입니다.

회원 가입, 상품 주문, HTML Form 사용 시 주로 사용되는 방식입니다.

웹 브라우저에서 HTML Form을 사용해서 데이터를 전달하면, 메시지 바디에 쿼리 파라미터 형식으로 데이터가 전송됩니다.

 

3. HTTP message body에 직접 데이터를 담아서 요청

HTTP API에서 주로 사용하는 방식으로, JSON, XML, TEXT 등이 전송됩니다. 

보통 JSON 형식으로 데이터를 전송합니다.

POST, PUT, PATCH 메소드와 함께 사용되는 경우가 많습니다. 

 

 

클라이언트에서 3가지 방식으로 데이터를 보내면, 서버에서는 이들을 조회할 수 있어야 합니다.

각각을 어떻게 조회하는지 알아봅시다.

 

1. GET 쿼리 파라미터

메시지 바디 없이, URL로 전송되는 쿼리 파라미터를 조회해봅시다.

쿼리 파라미터는 URL에 다음과 같이 "?"를 시작으로 보낼 수 있습니다. 추가 파라미터는 &로 구분합니다. 

http://localhost:8080/request-param?username=hello&age=20

위의 요청에서는 username, age 데이터가 전달됩니다. 

username=hello
age=20

 

단일 파라미터를 조회할 때는 getParameter 메소드를 사용하고, 복수 파라미터를 조회할 때는 getParameterValues 메소드를 사용합니다.

복수 파라미터는 동일한 이름을 갖는 파라미터가 여러 개 들어왔을 때 조회할 수 있습니다.

String username = request.getParameter("username"); //단일 파라미터 조회
String[] usernames = request.getParameterValues("username"); //복수 파라미터 조회

 

예제 코드를 봅시다.

@WebServlet(name = "requestParamServlet", urlPatterns = "/request-param")
public class RequestParamServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("[단일 파라미터 조회]");
        String username = request.getParameter("username");
        System.out.println("request.getParameter(username) = " + username);

        System.out.println("[단일 파라미터 조회]");
        String age = request.getParameter("age");
        System.out.println("request.getParameter(age) = " + age);

        System.out.println("[이름이 같은 복수 파라미터 조회]");
        String[] usernames = request.getParameterValues("username");
        for (String name : usernames) {
            System.out.println("username = "+ name);
        }
        response.getWriter().write("ok");
    }
}

위의 코드처럼 request.getParameter("username"), request.getParameter("age")로 조회합니다.

이름이 같은 복수 파라미터는 스트링 배열로 리턴되고, request.getParameterValues("username") 로 조회합니다.  

참고로 여러 개의 이름이 같은 파라미터를 넣었는데 getParameter를 이용하면 getParameterValues의 첫 번째 값이 반환됩니다.

 

 

2. POST HTML Form

POST 방식으로 HTML Form으로 데이터를 전송하면 메시디 바디에 쿼리 파라미터 형식으로 데이터를 전달합니다.

content-type은 application/x-www-form-urlencoded이고, 데이터는 앞서 살펴본 쿼리 파라미터 방식과 같이 username=hello&age=20 형태로 전송됩니다. 

 

Get 메소드의 쿼리 파라미터 방식과 Post 메소드의 HTML Form 방식의 데이터는 사실 형식이 같습니다.

쿼리 파라미터는 URL의 뒷부분에 붙여서 오고, HTML Form은 데이터 바디에 담겨서 온다는 것만 다릅니다.

서버 입장에서는 둘의 형식을 동일하게 생각하면 되고, 쿼리 파라미터 조회 메소드를 그대로 사용하면 됩니다.

따라서 HTML Form 데이터도 request.getParameter()로 편리하게 조회할 수 있습니다. 

 

HTML Form 데이터를 테스트하려면 2가지 방식이 있습니다.

첫 번째는 HTML 파일을 만드는 것이고, 두 번째는 Postman으로 테스트하는 것입니다.

 

HTML 파일은 아래와 같이 만들면 됩니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/request-param" method="post">
username: <input type="text" name="username" />
age: <input type="text" name="age" />
<button type="submit">전송</button>
</form>
</body>
</html>

 

Postman으로 테스트하려면 Body를 x-www-form-urlencoded으로 선택해서 데이터를 전송하면 됩니다.

헤더의 content-type은 포스트맨에서 application/x-www-form-urlencoded 로 지정해줍니다.

아래 사진처럼 설정하면 됩니다. 

 

3. API 메시지 바디 - 단순 텍스트

다음으로 HTTP 메시지 바디에 데이터를 직접 담아서 요청할 때, 데이터를 어떻게 조회하는지 알아봅시다.

주로 데이터의 형식으로 JSON을 사용하지만, 먼저 가장 단순한 텍스트 메시지를 HTTP 메시지 바디에 전송하고 읽어봅시다.

HTTP 메시지 바디의 데이터는 InputStream으로 들어옵니다. 

따라서 StreamUtils를 이용해서 copyToString메소드를 불러 String으로 만들어서 메시지 바디를 사용합니다.

아래 코드를 참고해주세요. 

@WebServlet(name = "requestBodyStringServlet", urlPatterns = "/request-body-string")
public class RequestBodyStringServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

        System.out.println("messageBody = " + messageBody);
        response.getWriter().write("ok");

    }
}

 

포스트맨으로 테스트할 수 있고, content type은 단순 텍스트이므로 text/plain으로 지정됩니다.

 

 

4. API 메시지 바디 - JSON

마지막으로 HTTP API에서 주로 사용하는 JSON형식으로 데이터를 전달해봅시다.

위에서 메시지 바디의 내용은 InputStream으로 받아서 String으로 변환한다고 소개해드렸는데요.

그러면 JSON은 String을 다 파싱해서 이용해야 할까요?

다행히도 아닙니다!

ObjectMapper를 사용하면 JSON을 객체로, 객체를 JSON으로 변환할 수 있습니다.

ObjectMapper의 readValue() 메소드를 사용하면 JSON -> 객체 변환이 가능합니다. 

{"username": "hello", "age": 20} 와 같은 JSON 형태의 String을 객체로 바꿔서 받을 수 있습니다.

객체는 필드로 username과 age를 갖고, 필드 값으로 hello, 20을 주입받습니다. 

반대로 객체 -> JSON 변환은 writeValueAsString() 메소드를 사용합니다. 

 

 

먼저 username, age를 필드로 갖는 HelloData 객체를 만듭니다.

@Getter @Setter
public class HelloData {
	private String username;
	private int age;
}

 

JSON 데이터를 받아서 객체를 생성하는 서블릿 코드입니다.

objectMapper.readValue() 메소드를 사용하였습니다. 

@WebServlet(name = "requestBodyJsonServlet", urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        System.out.println("messageBody = " + messageBody);
        
        HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
        System.out.println("helloData.getUsername() = " + helloData.getUsername());
        System.out.println("helloData.getAge() = " + helloData.getAge());
        response.getWriter().write("ok");
    }
}

 

테스트

 

결과

messageBody = {"username": "hello", "age": 20}
helloData.getUsername() = hello
helloData.getAge() = 20

 

JSON 형태의 메시지가 객체에 잘 저장된 것을 확인할 수 있습니다. 

 

 

이번 게시글에서는 요청 데이터를 조회하는 방법을 알아보았습니다.

다음 게시글에서는 응답 데이터를 전송하는 방법을 알아보겠습니다. 

 

 

인프런  '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의를 듣고 공부하며 정리한 자료입니다. 

잘못된 부분은 피드백 주시면 감사하겠습니다. 

글 읽어주셔서 감사합니다 :-)

 

참고자료

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술, 섹션 2. 서블릿 https://www.inflearn.com/course/스프링-mvc-1

댓글