@RestController
- @Controller는 반환 값이 String 이면 뷰 이름으로 인식됨 → 뷰를 찾고 뷰가 랜더링 됨
- @RestController는 반환 값으로 뷰를 찾는 것이 아니라, HTTP 메시지 바디에 바로 입력함
- 해당 컨트롤러에 모두 @ResponseBody가 적용 - Rest API(HTTP API)를 만들 때 사용하는 컨트롤러
@RequestMapping("/xx")
- /xx URL 호출이 오면 이 메서드가 실행되도록 매핑
- 대부분의 속성을 배열로 제공하므로 다중 설정 가능
PathVariable(경로 변수) 사용
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {}
// 다중
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId)
특정 헤더 조건 매핑
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {}
미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume
- HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑
- 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)을 반환
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {}
미디어 타입 조건 매핑 - HTTP 요청 Accept, produce
- HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑
- 맞지 않으면 HTTP 406 상태코드(Not Acceptable)을 반환
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {}
클라이언트에서 서버로 요청 데이터를 전달하는 3가지 방법
- GET - 쿼리 파라미터
- /url?username=hello&age=20
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 예) 검색, 필터, 페이징등에서 많이 사용하는 방식
- POST - HTML Form
- content-type: application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파리미터 형식으로 전달 username=hello&age=20
- 예) 회원 가입, 상품 주문 등에서 사용
- HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH
요청 파라미터 조회 - 쿼리 파라미터, HTML Form
@RequestParam
@ResponseBody // View 조회를 무시하고, HTTP message body에 직접 해당 내용 입력
@RequestMapping("/request-param-v2")
public String requestParamV2(
@RequestParam("username") String memberName,
@RequestParam("age") int memberAge) {}
- HTTP 파라미터 이름이 변수 이름과 같으면 @RequestParam(name="xx") 생략 가능
- @RequestParam String username, @RequestParam int age
- 파라미터 필수 여부 - requestParamRequired
- @RequestParam(required = true) String username, @RequestParam(required = false) Integer age
- /request-param?username= → 파라미터 이름만 있고 값이 없는 경우 빈문자로 통과
- @RequestParam(required = false) int age → null 을 int 에 입력하는 것은 불가능 → Integer로 변경 or defaultValue 사용
- 기본 값 적용 - requestParamDefault
- @RequestParam(required = true, defaultValue = "guest") String username
- @RequestParam(required = false, defaultValue = "-1") int age
- 파라미터를 Map으로 조회
- public String requestParamMap(@RequestParam Map<String, Object> paramMap)
- paramMap.get("username")
@ModelAttribute
@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {}
- 스프링 MVC는 @ModelAttribute 가 있으면 다음을 실행
- 요청 파라미터 처리
- HelloData 객체를 생성
- 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티를 찾음
- 해당 프로퍼티의 setter를 호출해서 파라미터의 값을 입력(바인딩)함
- Model 추가
- 모델(Model)에 @ModelAttribute로 지정한 객체를 자동으로 넣어줌
- -name(value) 속성을 모델 이름으로 사용
- 생략 가능
- String , int , Integer 같은 단순 타입 = @RequestParam
- 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 외)
요청 파라미터 vs HTTP 메시지 바디
- 요청 파라미터를 조회하는 기능: @RequestParam , @ModelAttribute
- HTTP 메시지 바디를 직접 조회하는 기능: @RequestBody
HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH
HTTP 요청 메시지 - 단순 텍스트
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
log.info("messageBody={}", messageBody);
return "ok";
}
@RequestBody
- HTTP 메시지 바디 정보를 편리하게 조회
- 헤더 정보가 필요하다면 HttpEntity 를 사용하거나 @RequestHeader 를 사용
@ResponseBody
- 응답 결과를 HTTP 메시지 바디에 직접 담아서 전달
- view를 조회하지 않음
HTTP 요청 메시지 - JSON
@RequestBody 문자 변환
@ResponseBody
@PostMapping("/request-body-json-v2")
public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException
- 문자로 된 JSON 데이터인 messageBody를 objectMapper를 통해서 자바 객체로 변환
@RequestBody 객체 변환
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData data)
- @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
- @RequestBody 에 직접 만든 객체를 지정할 수 있음
- @ResponseBody를 사용하면 해당 객체를 HTTP 메세지 바디에 직접 넣어줄 수 있어 반환형 지정 가능
@RequestBody 요청
- JSON 요청 → HTTP 메시지 → 컨버터 객체
@ResponseBody 응답
- 객체 → HTTP 메시지 컨버터 → JSON 응답
HTTP 응답 - 뷰 템플릿
- HTML을 동적으로 생성하는 용도로 사용
- 뷰 템플릿 경로 src/main/resources/templates
뷰 템플릿을 호출하는 컨트롤러
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
model.addAttribute("data", "hello!");
return "response/hello";
}
- String을 반환하는 경우 - View or HTTP 메시지
- @ResponseBody가 없으면 response/hello로 뷰 리졸버가 실행되어서 뷰를 찾고, 렌더링
- @ResponseBody가 있으면 뷰 리졸버를 실행하지 않고, HTTP 메시지 바디에 직접 response/hello라는 문자 입력
HTTP 응답 - HTTP API, 메시지 바디에 직접 입력
- @ResponseBody를 사용하면 view를 사용하지 않고, HTTP 메시지 컨버터를 통해서 HTTP 메시지를 직접 입력 가능
@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "ok";
}
- @ResponseStatus(HttpStatus.OK) 애노테이션을 사용한 응답 코드 설정
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
HTTP 메시지 컨버터
HTTP 요청 데이터 읽기
- HTTP 요청이 오고, 컨트롤러에서 @RequestBody, HttpEntity 파라미터를 사용
- 메시지 컨버터가 메시지를 읽을 수 있는지 확인하기 위해 canRead() 를 호출
- 대상 클래스 타입을 지원하는가
- ex) @RequestBody 의 대상 클래스 ( byte[] , String , HelloData )
- HTTP 요청의 Content-Type 미디어 타입을 지원하는가
- ex) text/plain , application/json , */*
- 대상 클래스 타입을 지원하는가
- canRead() 조건을 만족하면 read() 를 호출해서 객체 생성하고, 반환
HTTP 응답 데이터 생성
- 컨트롤러에서 @ResponseBody, HttpEntity로 값이 반환
- 메시지 컨버터가 메시지를 쓸 수 있는지 확인하기 위해 canWrite()를 호출
- 대상 클래스 타입을 지원하는가
- ex) return의 대상 클래스 ( byte[] , String , HelloData )
- HTTP 요청의 Accept 미디어 타입을 지원하는가 (더 정확히는 @RequestMapping의 produces )
- ex) text/plain , application/json , */*
- 대상 클래스 타입을 지원하는가
- canWrite() 조건을 만족하면 write()를 호출해서 HTTP 응답 메시지 바디에 데이터를 생성
요청 매핑 헨들러 어댑경혁장터 구조
RequestMappingHandlerAdapter 동작 방식
- 애노테이션 기반 컨트롤러를 처리하는 RequestMappingHandlerAdapter는 ArgumentResolver를 호출해서 컨트롤러(핸들러)가 필요로 하는 다양한 파라미터의 값(객체)을 생성
- ArgumentResolver의 supportsParameter()를 호출해서 해당 파라미터를 지원하는지 체크하고, 지원하면 resolveArgument() 를 호출해서 실제 객체를 생성 → 생성된 객체가 컨트롤러 호출시 넘어감
- ReturnValueHandler는 ArgumentResolver 와 비슷한 역할로 응답 값을 변환하고 처리
HTTP 메시지 컨버터 위치
- 요청의 경우 ArgumentResolver가 HTTP 메시지 컨버터를 사용해서 필요한 객체를 생성
- 응답의 경우 ReturnValueHandler가 HTTP 메시지 컨버터를 호출해서 응답 결과를 만듦
참고 강의:
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의
웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -
www.inflearn.com
'Spring Boot' 카테고리의 다른 글
Thymeleaf 기본 기능 (0) | 2023.07.02 |
---|---|
Thymeleaf (0) | 2023.06.30 |
Spring Boot - MVC 구조 (0) | 2023.06.25 |
스프링 핵심 원리 (0) | 2023.06.23 |
Spring Boot, 웹 MVC, DB 접근 기술 (1) | 2023.05.13 |