
요청 파라미터의 경우
@RequestParam@ModelAttribute두개를 활용해 요청 파라미터를 가져올 수 있지만
HTTP 메시지 바디에 직접 데이터가 넘어오는 경우에는 사용 할 수 없다.
HTML FORM 형식인 경우에는 요청파라미터로 인식된다.
InputStream을 이용해 읽을 수 있다.
내보낼때에는 response Writer을 활용해야 한다.
@PostMapping("/request-body-string-v1")
public void requestBodyString(HttpServletRequest request, HttpServletResponse response)throws Exception{
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody = {}",messageBody);
response.getWriter().write("ok");
}
InputStreamd() 을 추출해낸다.StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);HttpServletRequest.getInputStream()⇒ HttpEntity<String> httpEntity
⇒ @RequestBody String messageBody
Request에서 하나하나 추출하지 않고
return new RequestEntity<String>( 메세지 ,상 태코드 );HttpStatus.CREATED :: 201@RequestBody String messageBody 으로 가장 편하게 처리할 수 있디.
반환의 경우 메서드에 @ResponseBody 를 추가해 입출력을 모두 편하게 구현 할 수 있다.
@RequestHeader 를 받아 처리하면 된다.@RequestParam , @ModelAttribute 와는 상관 없다.요청 파라미터를 조회하는 기능
@RequestParam , @ModelAttributeHTTP 메시지 바디를 직접 조회하는 기능
@RequestBody@ResponseBody@PostMapping("/request-body-json-v1")
public void requestBodyJsonV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
log.info("username:{} , age :{} ",helloData.getUsername(),helloData.getAge());
response.getWriter().write("ok");
}
request 객체에서 Input Stream을 읽어 문자열을 ObjectMapper으로 객체 자료형에 맞게 재 구성한다.
objectMapper가 있어야 객체를 매핑할 수 있다.
객체를 HTTP 메시지 바디에 직접 넣어줄 수도 있다.
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData helloData) throws IOException {
log.info("username:{} , age :{} ", helloData.getUsername(), helloData.getAge());
return helloData;
}
@RequestBody 를 명시하며 객체 자료형을 선언해도 자동으로 매팽해준다.
@RequestBody 를 생략할 경우에는 @ModelAttribute으로 인식해 매핑되지 않는다.@ResponseBody응답 데이터의 3 종류
스프링 부트는 ClassPath에서 아래 디렉토리들에 있는 정적 리소스를 제공한다.
src/main/resources/ 하위의 경로들
/static/public/resources/META-INF/resourceslocalhost:8080/basic/hello.html
src/main/resources/ 하위의 경로 중
/templates는 뷰탬플릿의 경로로 제공된다
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model){
model.addAttribute("data","hello");
return "response/hello";
}
src/main/resources/templates/response/hell.htmldependencies 추가implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'HTML이나 뷰 탬플릿을 사용해도 HTTP 응답 메시지 바디에 HTML 데이터가 전달된다
그러한 방식이 아니라 HTML파일, 뷰탬플릿을 거치지 않고 직접 HTTP 응답 메시지를 전달하는 경우
@GetMapping("response-body-string-v1")
public ResponseEntity<String> responseBody(){
return new ResponseEntity<>("ok", HttpStatus.OK);
}
@ResponseBody
@GetMapping("response-body-string-v3")
public String responseBodyV3(){
return "ok";
}
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("response-body-json-v1")
public HelloData responseBodyJsonV1(){
return new HelloData("KHG",50);
}
@ResponseStatus(상태코드)를 사용한다ResponseEntity<T>을 사용한다HTTP API 처럼 JSON 데이터를 HTTP 메시지 바디에 직접 읽거나 쓰는 경우 HTTP 메시지 컨버터를 사용하면 편하다.
@ResponseBody ( @RestController )
HttpMessageConverter 가 동작한다.StringHttpMessageConverter 가 동작MappingJackson2HttpMessageConverter 가 동작응답의 경우 HTTP Accept Header 와 서버 컨트롤러의 반환 정보를 조합해 컨버터가 선택된다.
모든 자료형의 컨버터는 <Inteface> HttpMessageConverter 를 상속받는다.
CanRead() , CanWrite()read() , write()스프링 부트는 기본적으로 메시지 컨버터를 컨테이너에 올려둔다
application/octet-streamtext/plainApplication/JSON 일 경우 동작application/JSONHttp요청 ⇒ 컨트롤러에 @RequestBody,HttpEntity가 있을 경우
⇒ 메시지 컨버터가 동작
⇒ 클래스 타입을 지원하는가
⇒ 요청의 Content-Type 미디어 타입을 지원하는가
⇒ canRead()를 통과 시 read()를 호출
컨트롤러에서 @ResponseBody , HttpEntity 값 반환
⇒ 메시지 컨버터가 메시지를 처리할 수 있는지 canWriter를 호출
⇒ 클래스 타입을 지원하는가
⇒ 요청의 Accept 미디어 타입 제한을 지원하는가 ( @RequestMapping의 produces )
⇒canWrite() 통과 시 write() 호출
Content-type : text/plane
@RequestBody HelloData data
⇒ 불가능
RequestMapping
모든 기능은 RequestMappingHandller에 담겨있다.
ArgumentResolver어노테이션 기반의 컨트롤러를 처리하는 RequestMappingHandlerAdaptor는
ArgumentResolver를 호출 후 컨트롤러가 필요로 하는 모든 파라미터 값(객체)를 생성한다.
이러한 준비가 모두 끈나면 컨트롤러를 호출해 값을 넘겨준다.
ReturnValueResolverModelAndView, @ResponseBody , String등 여러 종류가 있다.
ArgumentResolver , ReturnValueResolverWebMvcConfigurer 등을 활용해 기능 확장을 구현 할 수 있다.
출처