Spring MVC 흐름
Client가 요청 데이터 전송 → Controller가 요청 데이터 수신 → 비즈니스 로직 처리 → Model 데이터 생성 → Controller에게 Model 데이터 전달 → Controller가 View에게 Model 데이터 전달 → View가 응답 데이터 생성
- @RestController : 해당 클래스가 REST API의 리소스를 처리하기 위한 API 엔드포인트로 동작함을 정의
RequestMapping 애너테이션
클라이언트의 요청과 Controller의 핸들러 메서드를 매핑하기 위해서 사용하는 애너테이션
일반적으로 공통 URI는 클래스 레벨에 정의하고, 핸들러 메서드별로 달라지는 URI는 각각의 핸들러 메서드에 정의
Method | 설명 |
---|
@GetMapping | HTTP Get Method에 해당하는 단축 표현으로 서버의 리소스를 조회할 때 사용 |
@PostMapping | HTTP Post Method에 해당하는 단축 표현으로 서버에 리소스를 등록(저장)할 때 사용 |
@PutMapping | HTTP Put Method에 해당하는 단축 표현으로 서버의 리소스를 수정할 때 사용. 리소스의 모든 정보를 수정할 때 사용 |
@PatchMapping | HTTP Put Method에 해당하는 단축 표현으로 서버의 리소스를 수정할 때 사용. 리소스의 일부 정보만 수정할 때 사용 |
@DeleteMapping | HTTP Delete Method에 해당하는 단축 표현으로 서버의 리소스를 삭제할 때 사용 |
Controller 핸들러 메서드
Method | 설명 |
---|
@RequestParam | 쿼리 파라미터, form-data 등의 Servlet request Parameter를 바인딩 해야 할 경우 사용 |
@RequestHeader | request header를 바인딩해서 header의 key/value에 접근할 수 있음 |
@RequestBody | request body를 읽어서 지정한 Java 객체로 deserialization |
@RequestPart | 'multipart/form-data' 형식의 request 데이터를 part 별로 바인딩할 수 있도록 해줌 |
@PathVariable | @RequestMapping 에 패턴 형식으로 정의된 URL의 변수에 바인딩할 수 있도록 해줌 |
@MatrixVariable | URL 경로 세그먼트 부분에 key/value 쌍으로 된 데이터에 바인딩할 수 있도록 해줌 |
HttpEntity | request header와 body에 접근할 수 있는 컨테이너 객체를 사용할 수 있음 |
@RestController
@RequestMapping("/v1/coffees")
public class CoffeeController {
private final Map<Long, Map<String, Object>> coffees = new HashMap<>();
@PostConstruct
public void init() {
Map<String, Object> coffee1 = new HashMap<>();
long coffeeId = 1L;
coffee1.put("coffeeId", coffeeId);
coffee1.put("korName", "바닐라 라떼");
coffee1.put("engName", "Vanilla Latte");
coffee1.put("price", 4500);
coffees.put(coffeeId, coffee1);
}
// 1. 커피 정보 수정을 위한 핸들러 메서드 구현
@PatchMapping("/{coffee-id}")
public ResponseEntity patchCoffee(@PathVariable("coffee-id") long coffeeId) {
coffees.get(coffeeId).put("korName", "바닐라 빈 라떼");
coffees.get(coffeeId).put("price", 5000);
return new ResponseEntity<>(coffees.get(coffeeId), HttpStatus.OK);
}
// 2. 커피 정보 삭제를 위한 핸들러 서드 구현
@DeleteMapping("/{coffee-id}")
public ResponseEntity deleteCoffee(@PathVariable("coffee-id") long coffeeId) {
coffees.remove(coffeeId);
return new ResponseEntity<>(coffees.get(coffeeId), HttpStatus.NO_CONTENT);
}
}
DTO (Data Transfer Object)
바로 요청 데이터를 하나의 객체로 전달 받는 역할
데이터를 전달하기 위해 사용하는 객체
DTO가 필요한 이유
기존코드
@RestController
@RequestMapping("/v1/members")
public class MemberController {
@PostMapping
public ResponseEntity postMember(@RequestParam("email") String email,
@RequestParam("name") String name,
@RequestParam("phone") String phone) {
Map<String, String> map = new HashMap<>();
map.put("email", email);
map.put("name", name);
map.put("phone", phone);
return new ResponseEntity<Map>(map, HttpStatus.CREATED);
}
...
...
}
회원의 정보를 저장하기 위해 @RequestParam 애너테이션의 개수가 늘어남에 따라 코드가 복잡해짐
▶ 이를 해결하기 위해서 DTO클래스 사용
@RestController
@RequestMapping("/v1/members")
public class MemberController {
@PostMapping
public ResponseEntity postMember(@Valid MemberDto memberDto) {
return new ResponseEntity<MemberDto>(memberDto, HttpStatus.CREATED);
}
...
...
}
DTO 클래스
public class MemberDto {
@Email
private String email;
private String name;
private String phone;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}