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
// 위의 버젼을 조금 더 간소화 함. (단, HTTP 상태코드를 변경할 수 없음)@ResponseStatus(HttpStatus.OK) // 이 애노테이션을 통해서 응답결과 상태코드를 변경할 수 있음@ResponseBody@GetMapping("/response-body-json-v2")
publicHelloDataresponseBodyJsonV2() {
HelloDatahelloData = newHelloData();
helloData.setUsername("userA");
helloData.setAge(20);
returnhelloData;
}
ResponseEntity는 HTTP 응답 코드를 설정할 수 있는데, @ResponseBody를 사용하면 이런 것을 설정하기가 까다로움
@ResponseStatus(HttpStatus.OK) 애노테이션을 사용하면 응답 코드도 설정 가능
이 데이터를 서버의 컨트롤러에서 @RequestBody를 사용하면 자바 객체로 받을 수 있음
@PostMapping("/user")
publicResponseEntity<User> createUser(@RequestBodyUseruser) {
// user 객체는 JSON 데이터를 User 클래스로 변환한 객체// 여기서 HttpMessageConverter가 JSON을 User 객체로 변환returnResponseEntity.ok(user);
}
여기서 HttpMessageConverter가 JSON 데이터를 User 객체로 변환
HttpEntity(RequestEntity)
HTTP 요청의 모든 정보를 담을 수 있음
헤더, 바디, 상태 코드 등을 모두 포함할 수 있음
@PostMapping("/user")
publicResponseEntity<User> createUser(RequestEntity<User> requestEntity) {
Useruser = requestEntity.getBody();
// 여기서 HttpMessageConverter가 JSON을 User 객체로 변환returnResponseEntity.ok(user);
}
@RequestBody를 사용하려면 요청의 Content-Type이 application/json이나 application/xml 등과 같은 데이터 형식을 나타내야 함
✅ 만약 HTML 데이터를 처리해야 한다면, @RequestBody 대신 HttpServletRequest를 사용
HTTP 요청 데이터 읽기
HTTP 요청이 오고, 컨트롤러에서 @RequestBody, HttpEntity 파라미터를 사용
메시지 컨버터에서 메시지를 읽을 수 있는지 확인하기 위해 canRead() 호출
대상 클래스 타입을 지원하는가?
예) @RequestBody의 대상 클래스(byte[], String, HelloData)
HTTP 요청의 Content-Type 미디어 타입을 지원하는가?
예) text/plain, application/json, */*
canRead() 조건을 만족하면 read()를 호출해서 객체를 생성하고 반환
HTTP 응답 데이터 생성
컨트롤러에서 @ResponseBody, HttpEntity로 값이 변환
메시지 컨버터가 메세지를 쓸 수 있는지 확인하기 위해 canWrite()를 호출
대상 클래스 타입을 지원하는가?
예) return의 대상 클래스 (byte[], String, HelloData)
HTTP 요청의 Accept 미디어 타입을 지원하는가?
예) text/plain, application/json, */*
canWrite() 조건을 만족하면 write()를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성
요청 매핑 헨들러 어뎁터 구조
HTTP 메시지 컨버터는 스프링 MVC 어디쯤에서 사용되는 것일까?
@RequestMapping을 처리하는 핸들러 어댑터인 RequestMappingHandlerAdapter(요청 매핑 핸들러 어댑터)에 모든 비밀이 있음
RequestMappingHandlerAdapter 동작 방식
ArgumentResolver
애노테이션 기반의 컨트롤러는 매우 다양한 파라미터를 사용할 수 있음
HttpServletRequest, Model, @RequestParam, @ModelAttribute 그리고 @RequestBody, HttpEntity 같은 HTTP 메시지를 처리하는 부분까지 사용 가능
이렇게 파라미터를 유연하게 처리할 수 있는 이유는 바로 ArgumentResolver 때문
애노테이션 기반 컨트롤러를 처리하는 RequestMappingHandlerAdapter는 바로 이 ArgumentResolver를 호출해서 컨트롤러(핸들러)가 필요로 하는 다양한 파라미터의 값(객체)을 생성. 그리고 이렇게 파라미터의 값이 모두 준비되면 컨트롤러를 호출하며 값을 넘겨줌
정확히는 HandlerMethodArgumentResolver 인데 줄여서 ArgumentResolver 라고 부름
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.
6_스프링 MVC - 기본 기능 (3)
응답 - 정적 리소스, 뷰 템플릿
서버에서 응답 데이터를 만드는 방법은 크게 3가지
1️⃣ 정적 리소스
/static,/public,/resources,/META-INF/resourcessrc/main/resources는 리소스를 보관하는 곳이고, 클래스패스의 시작 경로정적 리소스 경로
src/main/resources/staticsrc/main/resources/static/basic/hello-form/html)에 파일이 들어있으면 웹 브라우저에서http://localhost:8080/basic/hello-form.html이렇게 실행하면 해당 파일을 볼 수 있다🔎 클래스패스(classPath)
2️⃣ 뷰 템플릿
src/main/resources/templatesscr/main/resources/templates/response/hello.html: 뷰 템플릿 생성ResponseViewController: 뷰 템플릿을 호출하는 컨트롤러responseViewV1 실행결과
responseViewV2 실행결과
String을 반환하는 경우 - View or HTTP 메시지
@ResponseBody가 없으면response/hello로 뷰 리졸버가 실행되어서 뷰를 찾고, 렌더링 함@ResponseBody가 있으면, 뷰 리졸버를 실행하지 않고, HTTP 바디에 직접response/hello라는 문자가 입력됨response/hello를 반환하면templates/response/hello.html경로의 뷰 템플릿이 렌더링 됨void를 반환하는 경우
@Controller를 사용하고,HttpServletResponse,OutputStream(Writer)같은 HTTP 메시지 바디를 처리하는 파라미터가 없으면 요청 URL을 참고해서 논리 뷰 이름으로 사용/response/hellotemplates/response/hello.html3️⃣ HTTP 메시지
@ResponseBody,HttpEntity를 사용하면 뷰 템플릿을 사용하는 것이 아니라 HTTP 메시지 바디에 직접 응답데이터를 출력할 수 있음Thymeleaf 스프링 부트 설정
build.gragleThymeleafViewResolver와 필요한 스프링 빈들을 등록application.propertiesHTTP 응답 - HTTP API, 메시지 바디에 직접 입력
HTTP API를 제공하는 경우에는 HTML이 아니라 데이터를 전달해야 하므로, HTTP 메시지 바디에 JSON 같은 형식으로 데이터를 실어 보냄
ResponseBodyController전체 코드responseBodyStringV1
ok응답 메시지를 전달response.getWriter().write("ok")responseBodyStringV2
ResponseEntity엔티티는HttpEntity를 상속 받았는데, HttpEntity는 HTTP 메시지의 헤더, 바디 정보를 가지고 있음ResponseEntity는 여기에 더해서 HTTP 응답 코드를 설정할 수 있음responseBodyStringV3
@ResponseBody를 사용하면 view를 사용하지 않고, HTTP 메시지 컨버터를 통해서 HTTP 메시지를 직접 입력할 수 있음@ResponseEntity도 동일한 방식으로 동작responseBodyJsonV1
ResponseEntity를 반환responseBodyJsonV2
ResponseEntity는 HTTP 응답 코드를 설정할 수 있는데,@ResponseBody를 사용하면 이런 것을 설정하기가 까다로움@ResponseStatus(HttpStatus.OK)애노테이션을 사용하면 응답 코드도 설정 가능ResponseEntity를 사용하면 됨@RestController
@Controller대신에@RestController를 사용하면, 해당 컨트롤러에 모두@ResponseBody가 적용되는 효과가 있음@ResponseBody는 클래스 레벨에 두면 전체 메서드에 적용되는데,@RestController애노테이션 안에@ResponseBody가 적용되어 있음HTTP 메시지 컨버터
@responsebody 사용 원리
HTTP 메시지 컨버터를 사용하기 전, 스프링 입문 강의에서 설명했던 내용을 먼저 살펴보자
@ResponseBody를 사용viewResolver대신에HttpMessageConverter가 동작StringHttpMessageConverterMappingJackson2HttpMessageConverter스프링 MVC는 다음의 경우에 HTTP 메시지 컨버터를 적용
@RequestBody: 클라이언트의 JSON 데이터를 자바 객체로 변환할 때 사용HttpEntity(RequesetEntity): 요청의 모든 정보를 포함할 수 있으며, 바디를 자바 객체로 변활할 때 사용@ResponseBody: 자바 객체를 클라이언트로 JSON 형태로 보낼 때 사용HttpEntitu(ResponseEntity): 응답의 모든 정보를 포함할 수 있으며, 자바 객체를 JSON으로 변환할 때 사용🌀 중간 정리
스프링 MVC에서 HTTP 메시지 컨버서는 HTTP 요청과 응답의 본문을 객체로 변환하거나 객체를 HTTP 본문으로 변환하는 역할
HTTP 요청
{ "name": "John", "age": 30 }@RequestBody를 사용하면 자바 객체로 받을 수 있음HttpMessageConverter가 JSON 데이터를 User 객체로 변환HTTP 응답
HttpMessageConverter가 User 객체를 JSON으로 변환HTTP 메시지 컨버터 인터페이스
HTTP 메시지 컨버터는 인터페이스로 되어있음
org.springframework.http.converter.HttpMessageConvertercanRead(),canWrite(): 메시지 컨버터가 해당 클래스, 미디어타입을 지원하는 지 체크read(),write(): 메시지 컨버터를 통해서 메시지를 읽고 쓰는 기능스프링 부트 기본 메시지 컨버터
(일부 생략)
주요 메시지 컨버터
ByteArrayHttpMessageConverter: byte[] 데이터를 처리byte[], 미디어 타입 :*/*(모두 가능)@RequestBody byte[] data@ResponseBody return byte[]쓰기 미디어타입application/octet-streamStringHttpMessageConverter: String 문자로 데이터를 처리String, 미디어 타입 :*/*@RequestBody String data@ResponseBody return "ok"쓰기 미디어타입text/plainMappingJackson2HttpMessageConverter: application/jsonHashMap, 미디어타입application/json관련@RequestBody HelloData data@ResponseBody return helloData쓰기 미디어타입application/json관련@RequestBody를 사용하려면 요청의Content-Type이application/json이나application/xml등과 같은 데이터 형식을 나타내야 함@RequestBody대신HttpServletRequest를 사용HTTP 요청 데이터 읽기
@RequestBody,HttpEntity파라미터를 사용canRead()호출@RequestBody의 대상 클래스(byte[],String,HelloData)text/plain,application/json,*/*canRead()조건을 만족하면read()를 호출해서 객체를 생성하고 반환HTTP 응답 데이터 생성
@ResponseBody,HttpEntity로 값이 변환canWrite()를 호출byte[],String,HelloData)text/plain,application/json,*/*canWrite()조건을 만족하면write()를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성요청 매핑 헨들러 어뎁터 구조
HTTP 메시지 컨버터는 스프링 MVC 어디쯤에서 사용되는 것일까?
@RequestMapping을 처리하는 핸들러 어댑터인RequestMappingHandlerAdapter(요청 매핑 핸들러 어댑터)에 모든 비밀이 있음RequestMappingHandlerAdapter 동작 방식
ArgumentResolver
HttpServletRequest,Model,@RequestParam,@ModelAttribute그리고@RequestBody,HttpEntity같은 HTTP 메시지를 처리하는 부분까지 사용 가능RequestMappingHandlerAdapter는 바로 이ArgumentResolver를 호출해서 컨트롤러(핸들러)가 필요로 하는 다양한 파라미터의 값(객체)을 생성. 그리고 이렇게 파라미터의 값이 모두 준비되면 컨트롤러를 호출하며 값을 넘겨줌HandlerMethodArgumentResolver인데 줄여서ArgumentResolver라고 부름동작 방식
ArgumentResolver의supportsParameter()를 호출해서 해당 파라미터를 지원하는지 체크resolveArgument()를 호출해서 실제 객체 생성ArgumentResolver를 만들 수 있음ReturnValueHandler
HandlerMethodReturnValueHandler를 줄여서ReturnValueHandler라 부름ArgumentResolver와 비슷한데, 이것은 응답 값을 변환하고 처리HTTP 메시지 컨버터
HTTP 메시지 컨버터 위치
HTTP 메시지 컨버터를 사용하는
@RequestBody도 컨트롤러가 필요로 하는 파라미터의 값에 사용됨@ResponseBody의 경우도 컨트롤러 반환 값을 이용요청의 경우
@RequestBody를 처리하는ArgumentResolver가 있고,HttpEntity를 처리하는ArgumentResolver가 있아ArgumentResolver들이 HTTP 메시지 컨버터를 사용해서 필요한 객체를 생성하는 것응답의 경우
@ResponseBody와HttpEntity를 처리하는ReturnValueHandler가 있음스프링 MVC는
@RequestBody나@ResponseBody가 있으면RequestResponseBodyMethodProcessor(ArgumentResolver, ReturnValueHandler 둘다 구현)를 사용HttpEntity가 있으면HttpEntityMethodProcessor(ArgumentResolver, ReturnValueHandler 둘다 구현)를 사용확장
스프링은 다음을 모두 인터페이스로 제공
필요하면 언제든 기능을 확장할 수 있음
HandlerMethodArgumentResolverHandlerMethodReturnValueHandlerHttpMessageConverter스프링이 필요한 대부분의 기능을 제공하고 있어서 실제 기능을 확장할 일이 많지는 않음
WebMvcConfigure를 상속 받아 스프링 빈으로 등록하면 됨WebMvcConfigure 확장
🔗 출처
All reactions