You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@responsebody 가 없으면 response/hello 로 뷰 리졸버가 실행되어서 뷰를 찾고, 렌더링 한다.
@responsebody 가 있으면 뷰 리졸버를 실행하지 않고, HTTP 메시지 바디에 직접 response/hello 라는 문자가 입력된다
void를 반환하는 경우
@controller 를 사용하고, HttpServletResponse , OutputStream(Writer) 같은 HTTP 메시지 바디를 처리하는 파라미터가 없으면 요청 URL을 참고해서 논리 뷰 이름으로 사용
요청 URL: /response/hello
실행: templates/response/hello.html
참고.
void 방식은 명시성이 떨어지고 이렇게 딱 맞는 경우도 많이 없어서 권장하지 않는다.
HTTP 메시지
@responsebody , HttpEntity 를 사용하면, 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 응답 데이터를 출력할 수 있다.
✅Thymelead 스프링 부트 설정
생략
1️⃣ 2️⃣ HTTP 응답 - HTTP API, 메시지 바디에 직접 입력
HTTP API를 제공하는 경우에는 HTML이 아니라 데이터를 전달해야 하므로, HTTP 메시지 바디에 JSON 같은 형식으로 데이터를 실어 보낸다.
HTTP 요청에서 응답까지 대부분 다루었으므로 이번시간에는 정리를 해보자.
참고
HTML이나 뷰 템플릿을 사용해도 HTTP 응답 메시지 바디에 HTML 데이터가 담겨서 전달된다. 여기서 설명하 는 내용은 정적 리소스나 뷰 템플릿을 거치지 않고, 직접 HTTP 응답 메시지를 전달하는 경우를 말한다.
ResponseBodyController
packagehello.springmvc.basic.response;
importhello.springmvc.basic.HelloData;
importjakarta.servlet.http.HttpServletResponse;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.http.HttpStatus;
importorg.springframework.http.ResponseEntity;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.ResponseBody;
importorg.springframework.web.bind.annotation.ResponseStatus;
importjava.io.IOException;
@Slf4j@ControllerpublicclassResponseBodyController {
/** * 서블릿 직접 다룰 때처럼 * HttpServletResponse 객체를 통해서 HTTP 메시지 바디에 직접 `ok` 응답 메시지를 전달한다. * response.getWriter().write("ok") * @param response * @throws IOException */@GetMapping("/response-body-string-v1")
publicvoidresponseBodyStringV1(HttpServletResponseresponse) throwsIOException {
response.getWriter().write("ok");
}
/** * HttpEntity, ResponseEntity(Http Status 추가) * ResponseEntity 엔티티는 HttpEntity 를 상속 받았는데, HttpEntity는 HTTP 메시지의 헤더, 바디 정보를 가지고 있다. * ResponseEntity 는 여기에 더해서 HTTP 응답 코드를 설정할 수 있다. * HttpStatus.CREATED 로 변경하면 201 응답이 나가는 것을 확인할 수 있다. * @return */@GetMapping("/response-body-string-v2")
publicResponseEntity<String> responseBodyV2() {
returnnewResponseEntity<>("ok", HttpStatus.OK);
}
/** * @ResponseBody 를 사용하면 view를 사용하지 않고, HTTP 메시지 컨버터를 통해서 HTTP 메시지를 직접 입력할 수 있다. * ResponseEntity 도 동일한 방식으로 동작한다. * @return */@ResponseBody@GetMapping("/response-body-string-v3")
publicStringresponseBodyV3() {
return"ok";
}
/** * ResponseEntity 를 반환한다. HTTP 메시지 컨버터를 통해서 JSON 형식으로 변환되어서 반환된다. * @return */@GetMapping("/response-body-json-v1")
publicResponseEntity<HelloData> responseBodyJsonV1() {
HelloDatahelloData = newHelloData();
helloData.setUsername("userA");
helloData.setAge(20);
returnnewResponseEntity<>(helloData, HttpStatus.OK);
}
/** * ResponseEntity 는 HTTP 응답 코드를 설정할 수 있는데, @ResponseBody 를 사용하면 이런 것을 설정하기 까다롭다. * @ResponseStatus(HttpStatus.OK) 애노테이션을 사용하면 응답 코드도 설정할 수 있다. * 물론 애노테이션이기 때문에 응답 코드를 동적으로 변경할 수는 없다. * 프로그램 조건에 따라서 동적으로 변경하려면 ResponseEntity 를 사용하면 된다. * @return */@ResponseStatus(HttpStatus.OK)
@ResponseBody@GetMapping("/response-body-json-v2")
publicHelloDataresponeBodyJsonV2() {
HelloDatahelloData = newHelloData();
helloData.setUsername("userA");
helloData.setAge(20);
returnhelloData;
}
}
@RequestBody를 처리하는 ArgumentResolver가 있고, HttpEntity를 처리하는 ArgumentResolver가 있다.
이 ArgumentResolver 들이 HTTP 메시지 컨버터를 사용해서 필요한 객체를 생성하는 것이다.( 모임에서 만나서 코드 살펴보기)
응답의 경우
@responsebody와 HttpEntity를 처리하는 ReturnValueHandler가 있다. 그리고 여기에서 HTTP 메시지 컨버터를 호출해서 응답 결과를 만든다.
스프링 MVC는 @RequestBody@ResponseBody 가 있으면 RequestResponseBodyMethodProcessor(ArgumentResolver, ReturnValueHandler 둘다 구현)HttpEntity 가 있으면 HttpEntityMethodProcessor(ArgumentResolver, ReturnValueHandler 둘다 구현) 를사용한다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
1️⃣ 1️⃣ 응답 - 정적 리소스, 뷰 템플릿
✅정적 리소스
스프링 부트는 클래스패스의 다음 디렉토리에 있는 정적 리소스를 제공한다.
scr/main/resources는 리소스를 보관하는 곳이고, 또 클래스패스의 시작 경로이다.→ 따라서 다음 디렉토리에 리소스를 넣어두면 스프링 부트가 정적 리소스로 서비스를 제공한다.
✅ 뷰 템플릿
뷰 템플릿을 거쳐서 HTML이 생성되고, 뷰가 응답을 만들어서 전달한다.
일반적으로 HTML을 동적으로 생성하는 용도로 사용하지만, 다른 것들도 가능하다. 뷰 템플릿이 만들 수 있는 것이라면 뭐든 가능하다.
스프링 부트는 기본 뷰 템플릿 경로를 제공한다.
➡️뷰 템플릿 경로
scr/main/resources/templates➡️ 뷰 템플릿 생성
➡️ ResponseViewController - 뷰 템플릿을 호출하는 컨트롤러
String을 반환하는 경우 - View or HTTP 메시지
void를 반환하는 경우
✅Thymelead 스프링 부트 설정
1️⃣ 2️⃣ HTTP 응답 - HTTP API, 메시지 바디에 직접 입력
✅**@RestController**
1️⃣ 3️⃣ HTTP 메시지 컨버터
HTTP API 처럼 JSON 데이터를 HTTP 메세지 바디에서 직접 읽거나 쓰는 경우 HTTP 메세지 컨버터를 사용하면 편리하다.
@responsebody 사용 원리
스프링 MVC가 적용하는 HTTP MessageConverter
HTTP 메시지 컨버터 인터페이스
canRead(),canWrite(): 메시지 컨버터가 해당 클래스, 미디어타입을 지원하는지 체크read(),write(): 메시지 컨버터를 통해서 메시지를 읽고 쓰는 기능✅스프링 부트 기본 메시지 컨버터
대상 클래스 타입과미디어 타입둘을 체크해서 사용여부를 결정한다. 만약 만족하지 않으면 다음 메시지 컨버터로 우선순위가 넘어간다.주요한 컨버터 몇가지
ByteArrayHttpMessageConverter
byte[]*/*application/octet-streamStringHttpMessageConverter
String*/*MappingJackson2HttpMessageConverter
에외 케이스
✅HTTP 요청 데이터 읽기
canRead()를 호출한다.text/plain,application/json,*/*✅HTTP 응답 데이터 생성
text/plain,application/json,*/*1️⃣ 4️⃣ 요청 매핑 헨들러 어뎁터 구조
✅ArgumentResolver
애노테이션 기반의 컨트롤러는 매우 다양한 파라미터를 사용할 수 있었다.
HttpServletRequest,Model,@RequestParam,@ModelAttribute같은 애노테이션 그리고@RequestBody,HttpEntity같은 HTTP 메시지를 처리 가능하다.→ 이렇게 파라미터를 유연하게 처리할 수 있는 이유가
ArgumentResolver의 역할이다.HandlerMethodArgumentResolver인데 줄여서ArgumentResolver라고 부른다.✅동작 방식
ArgumentResolver의supportsParameter()를 호출해서 해당 파라미터를 지원하는지 체크하고 지원하면resolverArgument()를 호출해서 실제 객체를 생성한다. 그리고 이렇게 생성된 객체가 컨트롤러 호출시 넘어가는 것이다.추가로 이 인터페이스를 확장해서 원하는
ArgumentResolver를 만들 수 있다.✅ReturnValueHandler
HandlerMethodReturnValueHandler를 줄여서ReturnValueHandler라고 부른다.ArgumentResolver와 비슷한데, 이것은 응답 값을 변환하고 처리한다.컨트롤러에서 String으로 뷰 이름을 반환해도 동작하는 이유가
ReturnValueHandler에 역할 때문이다.스프링은 10여개가 넘는
ReturnValueHandler를 지원한다.코드 확인
✅메시지 컨버터
요청의 경우
@RequestBody를 처리하는ArgumentResolver가 있고,HttpEntity를 처리하는ArgumentResolver가 있다.ArgumentResolver들이 HTTP 메시지 컨버터를 사용해서 필요한 객체를 생성하는 것이다.( 모임에서 만나서 코드 살펴보기)응답의 경우
스프링 MVC는
@RequestBody@ResponseBody가 있으면RequestResponseBodyMethodProcessor(ArgumentResolver, ReturnValueHandler 둘다 구현)HttpEntity가 있으면HttpEntityMethodProcessor(ArgumentResolver, ReturnValueHandler 둘다 구현)를사용한다.✅확장
HandlerMethodArgumentResolverHandlerMethodReturnValueHandlerHttpMessageConverter기능 확장은
WebMvcConfigurer를 상속 받아서 스프링 빈으로 등록하면 된다.WebMvcConfigurer 확장
All reactions