요청 매핑
`@RestController`
: @Controller 는 반환값이 String 이면 뷰 이름으로 인식하여 뷰를 찾고 렌더링
: @RestController 는 반환값으로 뷰를 찾는 것이 아닌, HTTP 메시지를 바디에 바로 입력
: @Controller + @ResponseBody 효과
@RestController
public class MappingController {
@RequestMapping("/mapping-get-v1")
public String mappingGetV1() {
return "ok";
}
}
`@RequestMapping("url")`
: URL 호출이 오면 이 메서드가 실행되도록 매핑
: 다중 설정 가능
: 겹치는 URL 부분을 클래스 단위에 @RequestMapping("중복 url") 을 두면,
: 클래스 레벨 + 메서드 레벨과 조합되어 URL 을 사용할 수 있다.
@RequestMapping("/hello-basic")
@RequestMapping({"/hello-basic", "/hello-go"})
`@Get/Head/Post/Put/Patch/DeleteMapping`
: @RequestMapping 에 method 속성으로 요청 HTTP 메서드를 제한 가능
: 맞지 않으면 405 상태코드 (Method Not Allowed)
// 적용 전
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
// 적용 후
@GetMapping("/mapping-get-v1")
`@PathVariable("파라미터 명")`
: 매핑되는 부분을 편리하게 조회
: @PathVariable 이름과 파라미터 이름이 같으면 생략 가능
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
return "ok";
}
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
return "ok";
}
`params 속성`
: 특정 파라미터가 있거나 없는 조건으로 매핑
/**
* 파라미터로 추가 매핑
* params="mode",
* params="!mode"
* params="mode=debug"
* params="mode!=debug" (! = )
* params = {"mode=debug","data=good"}
*/
@GetMapping(value = "/mapping-param", params = "mode=debug")
`headers 속성`
: 특정 헤더가 있거나 없는 조건으로 매핑
/**
* 특정 헤더로 추가 매핑
* headers="mode",
* headers="!mode"
* headers="mode=debug"
* headers="mode!=debug" (! = )
*/
@GetMapping(value = "/mapping-header", headers = "mode=debug")
`consumes 속성`
: HTTP 요청의 Content-Type 헤더 값(미디어 타입) 조건으로 매핑
: 맞지 않으면 415 상태코드 (Unsupported Media Type)
/**
* Content-Type 헤더 기반 추가 매핑 Media Type
* consumes="application/json"
* consumes="!application/json"
* consumes="application/*"
* consumes="*\/*"
* MediaType.APPLICATION_JSON_VALUE
*/
@PostMapping(value = "/mapping-consume", consumes = "application/json")
`produces 속성`
: HTTP 요청의 Accept 헤더 값(미디어 타입) 조건으로 매핑
: 맞지 않으면 406 상태코드 (Not Acceptable)
/**
* Accept 헤더 기반 Media Type
* produces = "text/html"
* produces = "!text/html"
* produces = "text/*"
* produces = "*\/*"
*/
@PostMapping(value = "/mapping-produce", produces = "text/html")
기본, 헤더 조회
파라미터로 다양한 HTTP 헤더 정보를 조회할 수 있다.
`HttpServletRequest`
`HttpServletResponse`
`HttpMethod`
`Locale`
`@RequestHeader MultiValueMap<String, String> headerMap`
: 모든 HTTP 헤더를 MultiValueMap 형식으로 조회
`@RequestHeader("헤더 명") String 헤더 명`
: 특정 HTTP 헤더를 조회
`@CookieValue(value = "이름", required = false) String cookie`
: 필수 속성 required (기본값 true)
> 참고 <
- MultiValueMap 은 하나의 키에 여러 값 가지는 것이 가능하다.
@RequestMapping("/headers")
public String headers(HttpServletRequest request,
HttpServletResponse response,
HttpMethod httpMethod,
Locale locale,
@RequestHeader MultiValueMap<String, String> headerMap,
@RequestHeader("host") String host,
@CookieValue(value = "myCookie", required = false) String cookie
) {
return "ok";
}
요청 파라미터
`@RequestParam`
: HTTP 요청 파라미터를 조회
: 파라미터 명과 변수 명이 같으면 생략 가능
: 파라미터를 Map 으로 조회
> required 속성 - true (기본값) 없으면 오류, false 없어도 괜찮음
(빈 문자열 `""` 값이 있다고 인정됨)
> defaultValue 속성 - 기본값 설정
(빈 문자열 `""` 기본 값으로 변경됨)
> 참고 <
String, int, Integer 등 단순 타입이면, @RequestParam 도 생략 가능 (하지만 지양함)
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(
@RequestParam String username,
@RequestParam int age
) {
return "ok";
}
// 파라미터를 Map 으로 조회
@ResponseBody
@RequestMapping("/request-param-map")
public String requestParamMap(@RequestParam Map<String, Object> paramMap) {
paramMap.get("age"));
return "ok";
}
`@ModelAttribute`
: 자동으로 해당 객체를 생성하여 요청 파라미터 값을 입력
: 모델(Model)에 @ModelAttribute 로 지정한 객체를 자동으로 넣어줌 (`model.addAttribute()` 생략 가능)
: @ModelAttribute 생략 가능 (하지만 지양함)
: 생략하면 저장 이름을 클래스의 첫글자만 소문자로 변경해서 등록 (`Item` 객체면 `item` 으로 등록)
(해당 객체에 setter 가 있어야 함)
(파라미터 이름이 username 이면, `setUsername()` 을 찾아 호출하여 값을 입력)
: 타입이 맞지 않으면 `BindException` 이 발생
@Data
public class HelloData {
private String username;
private int age;
}
@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {
return "ok";
}
> 참고 <
- 롬복 `@Data` : `@Getter` , `@Setter` , `@ToString` , `@EqualsAndHashCode` , `@RequiredArgsConstructor` 자동 적용
- String / int / Integer 같은 단순 타입일 때 생략되면 @RequestParam 적용
- 나머지가 생략되면 @ModelAttribute 적용
`@ModelAttribute` 의 특별한 사용법
: 해당 컨트롤러를 요청할 때, 자동으로 실행되어 모델에 담긴다.
@ModelAttribute("regions")
public Map<String, String> regions() {
Map<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
return regions;
}
요청/응답 메시지
`HttpEntity` (요청, 응답)
: (요청)
> Http header, body 정보를 편리하게 조회
> 메시지 바디 정보를 직접 조회
: (응답)
> 메시지 바디 정보를 직접 반환
> view 조회 X
// String 요청 메시지
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
String messageBody = httpEntity.getBody();
return new HttpEntity<>("ok");
}
// Json 요청 메시지
@PostMapping("/request-body-json-v3")
public HttpEntity<HelloData> requestBodyJsonV3(HttpEntity<HelloData> httpEntity) {
HelloData data = httpEntity.getBody();
return new HttpEntity<>(data);
}
`RequestEntity` (요청)
: HttpEntity 상속받음
: HttpMethod, url 정보 추가
`ResponseEntity` (응답)
: HttpEntity 상속받음
: Http 상태 코드 설정 가능
@ResponseBody
@PostMapping("/request-body-string-v4")
public ResponseEntity<String> requestBodyStringV4(RequestEntity<String> httpEntity) {
return new ResponseEntity<>("ok", HttpStatus.CREATED);
}
`@RequestBody` (요청)
: Http 메시지 바디 정보 편리하게 조회
( 헤더 정보가 필요하면 HttpEntity or @RequestHeader 사용 )
> 메시지 바디가 Json 인 경우, 자동으로 해당 객체를 생성하여 Json 값을 입력 (생략 불가)
`@ResponseBody` (응답)
: HTTP 메시지를 바디에 바로 입력
: @RestController 와 같은 효과
: view 조회 X
// String 요청 메시지
@ResponseBody
@PostMapping("/request-body-string-v5")
public String requestBodyStringV5(@RequestBody String messageBody) {
return "ok";
}
// Json 요청 메시지
@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
return data;
}
> 참고 <
`@RequsetBody`, `HttpEntity`, `RequestEntity`, `@ResponseBody`, `ResponseEntity` 는
HTTP 메시지 컨버터를 적용하여 변환한다.
출처 | 스프링 MVC 1(김영한) - 인프런
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
[Spring] 메시지 / 국제화 하기 (0) | 2025.03.31 |
---|---|
[Thymeleaf] 타임리프 사용 방법 완전 정복! (0) | 2025.03.20 |
[심화] 로깅은 무엇일까 ?? (0) | 2025.03.19 |
[Spring] SpringMVC 의 세부적인 구조 (핸들러, 핸들러 어댑터, 메시지 컨버터) (1) | 2025.03.19 |
[Spring] 리팩토링하며 점진적으로 Spring MVC 프레임워크 만들기 !! (0) | 2025.03.14 |