본문 바로가기

백엔드/스프링

스프링 MVC - 응답데이터와 메시지 컨버터

응답 데이터 생성

스프링 응답 데이터타입 3가지 👉 정적 리소스, 뷰 템플릿, http 메시지 바디

1. 정적 리소스
 스프링 부트에서 제공하는 정적 리소스의 디렉토리    /static /public /resources /META-INF/resources
static이 아닌 public 이라는 이름의 폴더를 만들어서 열어보면

잘 열린다..!!

2. 뷰템플릿
 동적인 html 제공시 뷰 템플릿 사용한다. 뷰 템플릿을 거쳐서 html이 만들어지고 뷰가 응답을 만들어서 전달한다.
스프링 부트에서 뷰 템플릿 기본 경로 : src/main/resources/templates

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

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

위의 두 방식은 templates 경로 밑의 hello.html 파일을 제공해준다. 두 함수는 동일하게 동작하며 이를 통해 Model은 정말 뷰에게 데이터를 전달하는 역할임을 확인할 수 있다. (@ResponseBody가 있으면 단순 문자열이 메시지 바디에 들어간다.)

3.http 메시지
api 제공시에는 html이 아니고 데이터를 전달해야하니 메시지 바디에 json 같은 형식으로 실어보냄

@GetMapping("/repsonse-json-v1")
public ResponseEntity<HelloData> json1() throws IOException {
    //hello 객체 생성 후
    return new ResponseEntity<>(new HelloData(), HttpStatus.OK);
}


@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/repsonse-json-v2")
public HelloData json2() throws IOException {
    //hello 객체 해서 리턴
    return new HelloData();
}

 

메시지 컨버터

http api처럼 직접 body에 넣거나 읽을땐 메시지 컨버터를 사용한다. httpEntity 쓸라면 좀 번거로워서 메시지 컨버터가 많이 쓰인다.

※ 스프링 MVC에서 HTTP 메시지 컨버터를 적용하는 경우

http 요청 - @RequestBody, HttpEntity (RequestEntity)
http 응답 - @ResponseBody, HttpEntity (ResponseEntity)

0 = ByteArrayHttpMessageConverter 클래스: byte[], 미디어 /
1 = StringHttpMessageConverter 클래스: String, 미디어 /
2 = MappingJackson2HttpMessageConverter 클래스: 객체, 미디어 application/json
3,4, ...

대상 클래스 타입과 미디어 타입을 다 고려해서 사용할 메시지 컨버터를 찾는다.

>> http request 데이터 읽을때

  1. 컨트롤러에서 @RequestBody나 httpEntity 파라미터를 쓸 때,
  2. 핸들러 어댑터 찾을때처럼 메시지 컨버터들을 순회하며 canRead 함수를 호출한다.
  3. 대상 클래스 타입을 지원하는지 ( @RequestBody의 대상 클래스 byte[], String 등)
  4. Content-Type을 지원하는지 ( ex. text/plain, application/json, /)
  5. 둘 다 만족시 해당 컨버터의 read 함수가 호출된다.

>> http response 데이터 생성시

  1. 컨트롤러에서 @RequestBody나 httpEntity 파라미터를 쓸 때,
  2. 메시지 컨버터들을 순회하며 canWrite 함수를 호출한다.
  3. 반환 타입을 지원하는지 ( return 타입 byte[], String 등)
  4. http 요청의 accept 미디어 타입을 지원하는지 ( ex. text/plain, application/json, /)
  5. 둘 다 만족시 해당 컨버터의 write 함수가 호출된다.

 

파라미터와 리턴값이 처리되는 과정

애노테이션 기반의 컨트롤러는 엄청 다양한 파라미터를 사용할 수 있었는데 이것은 전부 Argument Resolver 덕분이다. 애노테이션 기반 컨트롤러 @RequestMapping를 처리해주는 핸들러 어댑터 RequestMappingHandlerAdapter가 Ragument Resolver를 사용한다. 파라미터들을 하나하나 Argument Resolver에게 준비해달라 요청하고 결과값을 받아서 컨트롤러를 호출하게 된다.

리턴값도 마찬가지로 String을 반환하든 객체를 반환하든 ModelAndView를 반환하든 다 처리해줬는데 이것은 핸들러 어댑터에서 Return Value Handler들을 호출해서 해당 타입을 처리할 수 있는 핸들러를 사용해서 처리해주기 때문이다.

 

메시지 컨버터의 위치

메시지 컨버터는 바로 이 Argument Resolver와 Return Value Handler에 있다.

Argument Resolver 중에서도 @RequestBody나 HttpEntity를 처리하는 것들이 Http 메시지 컨버터를 호출하며 처리해주는 것이다. Return Value에서도 동일하다.

단순하게 처리할 수 있는건 Argument Resolver가 하고 만약 메시지 바디안에 있는 데이터를 처리해야한다! 하면 메시지 컨버터를 쓰는 것이다.

 

 

 

관련글

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

 

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

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

www.inflearn.com

 

 

 

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

스프링 No serializer found for class 에러 해결  (0) 2021.08.24
PRG (Post Redirect Get)  (0) 2021.08.19
스프링 MVC - 요청 데이터  (0) 2021.08.19
스프링MVC 요청 매핑  (0) 2021.08.18
스프링MVC의 Handler, View Resolver  (0) 2021.08.18