Spring

[Spring]HTTP 응답을 보내는 방법과 HttpMessageConverter 자세하게 파악해보기

마닐라 2022. 6. 6. 13:43

서버에서 응답 데이터를 만드는 방법은 크게 정적 리소스, 뷰 템플릿, HTTP 메시지 사용 3가지 이다.

스프링 부트는 클래스패스의 다음 디렉토리에 있는 정적 리소스를 제공한다.

/static, /public, /resources, /META-INF/resources

 

HTTP 응답 - 뷰 템플릿

1. ModelAndView 사용

@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
    ModelAndView mav = new ModelAndView("response/hello")
            .addObject("data", "hello!");
    return mav;
}

 

2.String을 반환

HTTP 메세지 응답 관련 @Responsebody 어노테이션이 없으면 viewResolver가 실행되어 뷰를 찾고 렌더링한다.

@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
    model.addAttribute("data", "hello!");
    return "response/hello";
}

 

3.Void를 반환

요청 URL을 참고하여 논리 뷰 이름으로 사용한다.

이 방식은 명시성이 너무 떨어지고 이렇게 맞는 경우도 거의 없어서 권장되지 않는다.

@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
    model.addAttribute("data", "hello!");
}

 

HTTP 응답 메세지 - 단순 텍스트

1.HttpServletResponse가 제공하는 getWriter().write("xx") 사용

@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException {
    response.getWriter().write("ok");
}

 

2.ResponseEntity<T> 사용하여 String 반환

@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
    return new ResponseEntity<>("ok", HttpStatus.OK);
}

 

3.@Responsebody를 사용하여 String 반환

@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
    return "ok";
}

 

HTTP 응답 메세지 - JSON

1.ResonseEntity<T> 사용하여 객체 반환

@GetMapping("/response-body-json-v1")
public ResponseEntity<HelloData> responseBodyJsonV1() {
    HelloData helloData = new HelloData();
    helloData.setUsername("userA");
    helloData.setAge(20);
    return new ResponseEntity<>(helloData, HttpStatus.OK);
}

 

2.@Responsebody를 사용하여 객체 반환

@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
    HelloData helloData = new HelloData();
    helloData.setUsername("userA");
    helloData.setAge(20);
    return helloData;
}

 

HTTPMessageConverter

뷰 템플릿으로 HTML을 생성해서 응답하는 것이 아니라 HTTP API처럼 JSON 데이터를 HTTP 메세지 바디에서 직접 읽거나 쓰는 경우 HTTPMessageConverter를 사용하면 편리하다. 

쿼리 파라미터가 아닌 메세지 바디 요청에서도 물론 사용한다.

쿼리 파라미터 방식은 ConversionService가 해준다.

해당 기능은 스프링에 모두 구현되어있고 그로 인해 우리가 편리하게 사용할 수 있는 것이다.

 

기본 문자처리는 StringHttpMessageConverter 구현체가 동작한다.

기본 객체처리는 MappingJackson2HttpMessageConverter 구현체가 동작한다.

외에도 byte 처리 등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있다.

 

스프링 MVC는 다음의 경우에 HTTPMessageConverter를 적용한다

요청 - @RequestBody, HttpEntity(RequestEntity)

응답 - @ResponseBody, HttpEntity(ResponseEntity)

 

HTTPMessageConverter는 요청의 경우 RequestMappingHandlerAdapter 구현체에서 동작한다.

해당 구현체가 ArgumentResolver를 호출하고 컨트롤러가 필요로하는 다양한 파라미터의 값을 생성한다.

그리고 이렇게 파라미터의 값이 모두 준비되면 컨트롤러를 호출하면서 값을 넘겨준다.

ArgumentResolver가 HTTP Message Converter를 호출하는 것이다.

 

응답의 경우 ReturnValueHandler가 있고 클라이언트의 HTTP Accept 헤더와 서버의 컨트롤러 반환 타입 정보 둘을 조합해서 HttpMessageConverter가 선택된다.

 

출처

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