본문 바로가기

백엔드/스프링

Http Request 데이터 형식 정리

웹상에서는 거의 모든 메시지들이 http 프로토콜을 따라 http 메시지로 전달된다. httpServletRequest 객체와 http ServletResponse 객체는 개발자들이 이러한 http 메시지들을 편하게 이용할 수 있도록 도와준다.

 

Http Request

http 에서 요청데이터 형식은 3가지중 하나이다.

1. GET - 쿼리 파라미터

Url에 다음과 같이 파라미터가 포함되는 방식이다. 물음표 뒤에 붙는건 전부 파라미터들이고 &로 구분한다.

http://www.tistory.com?name=abc&age=100

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   req.getParameterNames().asIterator().forEachRemaining(s -> System.out.println(s + ": "+ req.getParameter(s)));
}

쿼리 파라미터는 위와같이 조회할 수 있다. 


2. html form에서 POST 방식

데이터가 http messasge body에 쿼리 파라미터 형식으로 들어가며 html form 을 통해 전달되는 방식이다. 데이터의 타입은 x-www-form-urlencoded이다. 하지만 이 역시 쿼리 파라미터의 형식으로 서버에서는 처리하는 방법이 똑같다. GET은 name=abc?age=100 같은 것이 url 뒤에 붙는다면 POST는 body에 들어간다는 것이다.

간단한 html form을 만들어서 전송해보자. 처리는 GET에서 본 예시코드가 처리해줄 것이다.

개발자 탭을 열고 네트워크를 확인해보면 데이터 형식이 정말 쿼리 파라미터와 똑같은 것을 볼 수 있다.

처리도 GET과 동일하게 하는데도 문제없이 이뤄진다. 정리해보자면 HttpServletRequest 객체의 getParameter은 GET의 URL 쿼리 파라미터 형식과 POST의 HTML Form 형식도 지원한다. GET의 URL 쿼리 파라미터는 Http Message Body를 이용하지 않아서 content-type이 따로 없고 Post는 x-www-form-urlencoded 이다.

👉 바디에 데이터가 들어가면 어떤 형식인지 명시해줘야한다.


3. http message body 방식

메시지 바디에 직접 담아서 보내는 주로 보내는 방식이며 주로 Json 형식을 사용한다. Json 형식이 아닌 그냥 문자들을 메시지 바디에 담아서 보낼 경우 서버에서는 다음과 같이 읽을 수 있다.

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletInputStream input = req.getInputStream();
    String messagebody = StreamUtils.copyToString(input, StandardCharsets.UTF_8);
    System.out.println("messagebody = " + messagebody);
    resp.getWriter().write("ok");
}

이처럼 문자로 주고 받는 경우는 거의 없다. 참고로 위처럼 StreamUtils를 써서 읽는 것은 Post 방식으로 넘어온 데이터도 가능하다. Post 방식도 메시지 바디에다가 넘겨주는 것이니. 근데 편한 getParameter 냅두고 굳이 이렇게 읽을 이유는 없다.

message body에 데이터가 담길 때는 Json 형식이 대부분이다. 우선 request를 보낼때에 서버에서 정한 json 형식에 맞게 데이터를 보내줘야한다. 이름과 나이를 보내줘야한다고 가정했을때

이렇게 메세지를 보낸다고 하면 서버 측에서는 해당 json형식을 객체로 만들기 위해 DTO를 만들어둬야한다. 전달받은 데이터를 객체로 변환하는 것은 잭슨 라이브러리를 사용한다.

@WebServlet(name="json", urlPatterns ="/json")
public class ReqJson extends HttpServlet {

    private ObjectMapper objMapper = new ObjectMapper();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletInputStream input = req.getInputStream();
        String messagebody = StreamUtils.copyToString(input, StandardCharsets.UTF_8);

        Data data = objMapper.readValue(messagebody, Data.class);

        System.out.println("====== 객체로 변환 =====");
        System.out.println(data.getAge());
        System.out.println(data.getName());
    }
}

 

Http Response

@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("my-header", "hi header");
        cookie(resp);
        resp.getWriter().write("h");
}

헤더는 이와같이 설정 가능하다. 마음대로 헤더를 만들수도 있다. 

my-header라는 헤더가 추가된 것을 볼 수 있다!!
물론 쿠키도 설정할 수 있다.setHeader() 로 쿠키를 설정할 수도 있지만 쿠키라는 자바에서는 쿠키 객체를 통해 좀 더 편하게 설정할 수 있도록 해준다.

    private void cookie(HttpServletResponse resp) {
        Cookie c = new Cookie("myCookie", "good");
        c.setMaxAge(500);
        resp.addCookie(c);
    }

이렇게 응답 헤더나 상태코드 등을 설정할 수 있고 이제 응답 데이터에 대해서 알아보자

1. 단순 텍스트 응답

response.getWriter.println("ok");

말그대로 단순히 텍스트만 보내는 것이다. 이렇게 보내면 응답을 받은 사용자의 브라우저에는 ok 글자만 보일 것이다.

응답 화면 예시

2. HTML 응답

응답값이 HTML인 것이다.

딱봐도 실무에선 절대 이렇게 안할 것 같은 느낌이 든다 ㅋㅋㅋㅋ 어쨋든 1번과 2번을 봤을때 응답 데이터에 들어간 내용이 그대로 브라우저에 나온다는 것으로 예상할 수 있겠다.

 

3. HTTP API 응답

마지막으로 http response body에 json 데이터를 담아 보내는 방식이다. 

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setStatus(HttpServletResponse.SC_OK);
    resp.setContentType("application/json");
    resp.setCharacterEncoding("utf-8"); //이건 안넣어도 됨

    Data data = new Data();
    data.setAge(23);
    data.setName("이름");

    //json 평문 형식  {"username":"이름", "age":23}
    String result = objM.writeValueAsString(data);
    resp.getWriter().write(result);
}

Json을 반환해줄 것이므로 setContentType은 application/json 으로 설정한다. json형식의 request를 받을때와 마찬가지로 DTO 객체를 사용한다. 잭슨 라이브러리를 사용해서 보낸다. 해당 클래스의 ObjectMapper 멤버변수를 미리 선언해놓았다.                                   
                                           private ObjectMapper objM = new ObjectMapper();

 

관련글

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1 

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com

 

 

 

 

 

'백엔드 > 스프링' 카테고리의 다른 글

스프링MVC의 Handler, View Resolver  (0) 2021.08.18
프론트 컨트롤러 패턴  (0) 2021.08.17
스프링 빈 스코프  (0) 2021.08.13
스프링 빈 등록 총정리  (0) 2021.08.13
스프링 설정 - Xml 형식  (0) 2021.08.12