1. Spring Controller Annotations
1-1. @PathVariable
- 하는 일: @PathVariable annotation은 요청 URL 경로에서 값을 추출하여 메서드 매개변수로 전달합니다.
- 언제 사용: URL 자체에서 특정 값을 (예: ID) 가져와서 메서드의 인자로 사용할 때 @PathVariable을 사용합니다.
public class Star {
String name;
int age;
public Star(String name, int age) {
this.name = name;
this.age = age;
}
}
Java Class (Star)
@Controller
@RequestMapping("/hello/request")
public class RequestController {
@GetMapping("/form/html")
public String helloForm() {
return "hello-request-form";
}
// [Request sample]
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
return String.format("Hello ! <br> name = %s, age = %d", name, age);
}
1-2. @RequestParam
- 역할: @RequestParam annotation은 URL의 쿼리 매개변수에서 값을 추출합니다. 쿼리 매개변수는 URL에서 물음표(?) 뒤에 나오는 key-value 쌍입니다.
- 언제 사용: URL의 쿼리 스트링에 포함된 매개변수를 추출할 때 @RequestParam을 사용합니다.
// [Request sample]
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam (required = false) String name, int age) {
return String.format("Hello ! <br> name = %s, age = %d", name, age);
}
1-3.@ModelAttribute
- 역할: @ModelAttribute annotation은 요청 데이터(폼 데이터나 쿼리 매개변수)를 모델 객체에 바인딩합니다. 주로 여러 필드를 가진 폼 데이터를 객체에 매핑할 때 사용합니다.
- 언제 사용: 복잡한 폼 데이터를 처리하거나 여러 요청 매개변수를 객체에 직접 바인딩하고 싶을 때 @ModelAttribute를 사용합니다.
// [Request sample]
// Header
// Content type: application/x-www-form-urlencoded
// Body
// name=abdcd&age=122
@PostMapping("/form/model")
@ResponseBody
public String helloRequestBodyForm(@ModelAttribute Star star) {
return String.format("Hello ! <br> (name = %s, age = %d) ", star.name, star.age);
}
1-4.@RequestBody
- 하는 일: @RequestBody annotation은 요청 데이터(폼 데이터나 쿼리 매개변수)를 모델 객체에 바인딩합니다. 주로 여러 필드를 가진 폼 데이터를 객체에 매핑할 때 사용합니다.
- 언제 사용: 복잡한 폼 데이터를 처리하거나 여러 요청 매개변수를 객체에 직접 바인딩하고 싶을 때 @ModelAttribute를 사용합니다.
// [Request sample]
// Header
// Content type: application/json
// Body
// {"name":"abcd","age":"123"}
@PostMapping("/form/json")
@ResponseBody
public String helloPostRequestJson(@RequestBody Star star) {
return String.format("Hello, @RequestBody.<br> (name = %s, age = %d) ", star.name, star.age);
}
주요 포인트:
- 데이터는 URL이나 쿼리 매개변수가 아닌, 요청의 본문(body) 에 담겨서 전송됩니다.
- Spring은 메시지 변환기(예: Jackson)를 사용하여 요청 본문을 자바 객체로 변환합니다.
사용 사례:
다음과 같은 상황에서 @RequestBody를 자주 사용합니다:
- RESTful API 작업 시.
- 클라이언트가 JSON 또는 XML 데이터를 서버로 전송할 때.
- 요청 본문에 있는 데이터를 자바 객체에 매핑하여 쉽게 처리하고 싶을 때.
Controller | |
Annotation | 생략 가능 |
@PathVariable | X |
@RequestParam | O |
@ModelAttribute | O |
@RequestBody | X |
2. CRUD (Create - Read - Update - Delete)
DTO (Data Transfer Object)
DTO는 애플리케이션의 다른 부분들 사이에서 데이터를 전송하는 데 사용되는 간단한 객체입니다. 특히, 계층 간 데이터 전송(예: 서비스 계층에서 controller로, 또는 controller에서 client로)에서 자주 사용됩니다.
DTO 사용하는 이유
- 보안: DTO를 사용하면 내부 구조(예: Database entity)를 클라이언트에게 노출시키지 않고, 필요한 데이터만 전달할 수 있습니다.
- 데이터 구조화: Entity의 모든 필드를 반환할 필요가 없는 경우가 많습니다. DTO를 사용하면 전송할 데이터를 제어할 수 있습니다.
- 관심사의 분리: DTO를 사용함으로써 비즈니스 로직과 데이터 전송 및 표시를 분리할 수 있습니다.
- 직렬화 용이성(Easy Serialization): DTO는 단순한 객체이므로 JSON이나 XML로 쉽게 직렬화/역직렬화할 수 있습니다.
Sum up
- DTO는 데이터를 전송하는 목적으로 사용되며, 비즈니스 로직을 포함하지 않습니다.
- 보안, 데이터 제어, 관심사의 분리를 위해 DTO를 사용합니다.
- 특히 RESTful API에서 클라이언트와 서버 간 데이터를 간편하게 전송하기 위해 많이 사용됩니다.
2-1. Create
- 역할: 새 데이터를 데이터베이스나 시스템에 추가합니다.
- 예시: 새로운 사용자, 상품, 글을 시스템에 추가하는 것.
- HTTP 메서드: RESTful API에서는 주로 POST가 사용됩니다
import com.sparta.memo.dto.MemoRequestDto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class Memo {
private Long id;
private String username;
private String contents;
public Memo(MemoRequestDto requestDto) {
this.username = requestDto.getUsername();
this.contents = requestDto.getContents();
}
public void update(MemoRequestDto requestDto) {
this.username = requestDto.getUsername();
this.contents = requestDto.getContents();
}
}
Java Class Memo (Entity)
import com.sparta.memo.dto.MemoRequestDto;
import com.sparta.memo.dto.MemoResponseDto;
import com.sparta.memo.entity.Memo;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class MemoController {
private final Map<Long, Memo> memoList = new HashMap<>();
//CREATE
@PostMapping("/memos")
public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
// RequestDto -> Entity
Memo memo = new Memo(requestDto);
//Memo Max ID check
//Long maxId = memoList.size() > 0 ? Collections.max(memoList.keySet()) + 1 : 1;
Long maxId = !memoList.isEmpty() ? Collections.max(memoList.keySet()) + 1 : 1;
memo.setId(maxId);
//DB 저장
memoList.put(memo.getId(), memo);
//Entity -> ResponseDto
MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
return memoResponseDto;
}
2-2. Read
- 역할: 데이터베이스나 시스템에서 데이터를 조회합니다.
- 예시: 사용자 목록을 조회하거나 특정 상품의 세부 정보를 가져오는 것.
- HTTP 메서드: RESTful API에서는 주로 GET이 사용됩니다.
//READ
@GetMapping("/memos")
public List<MemoResponseDto> getMemos() {
//Map to List
List<MemoResponseDto> responseList = memoList.values().stream()
.map(MemoResponseDto::new).toList();
return responseList;
}
2-3. Update
- 역할: 데이터베이스나 시스템에 있는 기존 데이터를 수정합니다.
- 예시: 사용자의 이메일 주소를 변경하거나 상품의 가격을 수정하는 것.
- HTTP 메서드: PUT 또는 PATCH가 사용됩니다. PUT은 전체 업데이트, PATCH는 부분 업데이트에 주로 사용됩니다.
//UPDATE
@PutMapping("/memos/{id}")
public Long updateMemo(@PathVariable Long id, @RequestBody MemoRequestDto requestDto) {
//해당 memo가 DB에 존재하는지 확인
if (memoList.containsKey(id)) {
//해당 memo 가져오기
Memo memo = memoList.get(id);
//memo 수정
memo.update(requestDto);
return memo.getId();
} else {
throw new IllegalArgumentException("선택한 memo는 존재하지 얺습니다.");
}
}
2-4. Delete
- 역할: 데이터베이스나 시스템에 있는 기존 데이터를 삭제합니다.
- 예시: 특정 사용자를 삭제하거나 상품을 목록에서 제거하는 것.
- HTTP 메서드: RESTful API에서는 주로 DELETE가 사용됩니다.
//DELETE
@DeleteMapping("/memos/{id}")
public Long deleteMemo(@PathVariable Long id) {
//해당 memo가 DB에 존재하는지 확인
if (memoList.containsKey(id)) {
//해당 memo를 삭제하기
memoList.remove(id);
return id;
} else {
throw new IllegalArgumentException("\"선택한 memo는 존재하지 얺습니다.\"");
}
}
}
CRUD 작업 개요
작업 | HTTP method | API 예시 |
Create | POST | @PostMapping("/memos") |
Read | GET | @GetMapping("/memos") |
Update | PUT/PATCH | @PutMapping("/memos/{id}") |
Delete | DELETE | @DeleteMapping("/memos/{id}") |
'Spring Boot' 카테고리의 다른 글
Spring Boot - JPA (Java Persistence API) 기초 (0) | 2024.10.08 |
---|---|
Spring Boot - Inversion of Control (IoC), Dependency Injection (DI) and Bean (0) | 2024.10.07 |
Schedule Management App - Troubleshooting (전체 일정 조회 문제) (0) | 2024.10.04 |
일정 관리 App - API 명세서, Entity 생성 & MySQL Tables 생성 (0) | 2024.10.01 |
Spring Boot - Lombok, MVC Pattern (0) | 2024.09.27 |