[Section3] Spring MVC - API 계층 2
🧑🏻💻 TIL(Today I Learned)
✔️ DTO(Data Transfer Object)
💡 DTO(Data Transfer Object)란?
➡️ 마틴 파울러가 'Patterns of Enterprise Application Architecture'라는 책에서 처음 소개한 엔터프라이즈 애플리케이션 아키텍처 패턴 중 하나
➡️ 데이터를 전송하기 위한 용도의 객체라고 생각하면 편함
➡️ 클라이언트에서 서버 쪽으로 전송하는 요청 데이터, 서버에서 클라이언트 쪽으로 전송하는 응답 데이터의 형식으로 클라이언트와 서버 간의 데이터 전송이 이루어지고 이 사이에서 DTO를 사용할 수 있음
🔎 DTO 가 필요한 이유?
1. 코드의 간결성
➡️ 이전 수업 시간에서 작성했던 Memeber Controller 코드를 보면 DTO 가 필요한 이유에 대해서 알 수 있음
@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 애너테이션을 사용하고 있음 코드에서는 요청 데이터가 세 개밖에 없지만 실제로 회원 정보에 더 많은 정보들이 포함될 수 있고 그러면 @RequestParam은 계속해서 늘어날 수 밖에 없음
➡️ 하지만 클라이언트 요청 데이터를 하나의 객체로 모두 전달받을 수 있다면? 코드는 매우 간결해짐
➡️ 즉 DTO는 요청 데이터를 하나의 객체로 전달받는 역할을 한다!
➡️ 만약 DTO 클래스를 적용한다면 아래와 같이 나타낼 수 있음
@RestController
@RequestMapping("/v1/members")
public class MemberController {
@PostMapping
public ResponseEntity postMember(MemberDto memberDto) {
return new ResponseEntity<MemberDto>(memberDto, HttpStatus.CREATED);
}
}
2. 데이터 유효성(Validation) 검증의 단순화
➡️ 만약 클라이언트 쪽에서 이메일 주소를 "000@gmail.com"과 같은 바른 형식이 아니라 "000@", "000gmail.com" 이렇게 바르지 않은 형식으로 전송을 할 경우 데이터 유효성 검증이 없다면 올바르지 않은 형식도 핸들러 메서드에서 전달받게 됨
➡️ 즉, 유효성 검증이란 서버 쪽에서 유효한 데이터를 전달받기 위해 데이터를 검증하는 것
if (!email.matches("^[a-zA-Z0-9_!#$%&'\\*+/=?{|}~^.-]+@[a-zA-Z0-9.-]+$")) {
throw new InvalidParameterException();
}
- 유효성 검증을 위해 핸들러 메서드 내에 위와 같은 정규 표현식을 직접 포함하여 사용할 수 있지만 그렇게 된다면 name이나, phone 과 같은 요청 데이터 또한 검증하기 위한 코드들을 다 써줘야 함
→ HTTP 요청을 전달받는 핸들러 메서드는 요청을 전달받는 것이 주목적이기 때문에 최대한 간결하게 작성되어야 함
➡️ 핸들러 메서드 내부에 코드를 작성하지 말고 외부로 빼는 것이 간결함 유지에 더 좋다!
➡️ 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;
}
}
- @Email 애너테이션을 추가하면 클라이언트 요청 데이터에 유효한 이메일 주소가 포함되어 있지 않을 경우 유효성 검증에 실패하기 때문에 클라이언트의 요청은 거부된다!
@RestController
@RequestMapping("/v1/members")
public class MemberController {
@PostMapping
public ResponseEntity postMember(@Valid MemberDto memberDto) {
return new ResponseEntity<MemberDto>(memberDto, HttpStatus.CREATED);
}
}
- @Valid 애너테이션 : MemberDTO 객체에 유효성 검증을 적용하게 해주는 애너테이션
💡 실습
✔️ @RequeatBody 애너테이션
➡️ JSON 형식의 Request Body를 MemberPostDto 클래스의 객체로 변환 시켜주는 역할
➡️ 즉 클라이언트 쪽에서 전송하는 Request Body가 JSON 형식이어야 한다는 것
✔️ @ResponseBody 애너테이션
➡️ JSON 형식의 Response Body를 클라이언트에게 전달하기 위해 DTO 클래스의 객체를 Response Body로 변환하는 역할
Spring MVC에서는 핸들러 메서드에 @ResponseBody 애너테이션이 붙거나 핸들러 메서드의 리턴 값이 ResponseEntity일 경우
내부적으로 HttpMessageConverter가 동작하게 되어 응답 객체(여기서는 DTO 클래스의 객체)를 JSON 형식으로 바꿔줌
✍🏻 JSON 직렬화(Serializaion)와 역직렬화(Deserialization)
➡️ 역직렬화(Serialization)
: 클라이언트 쪽에서 JSON 형식의 데이터를 서버 쪽으로 전송하면 서버 쪽의 웹 애플리케이션은 전달받은 JSON 형식의 데이터를 DTO 같은 Java 객체로 변환하는 것
➡️ 직렬화(Deserialization)
: 서버 쪽에서 클라이언트에게 응답 데이터를 전송하기 위해서 DTO와 같은 Java 객체를 JSON 형식으로 변환하는 것
🔎 DTO 클래스에 유효성 검증 적용하기
- 유효성 검증을 위한 의존 라이브러리 추가
- @NotBlank
- 이메일 정보가 비어있지 않은지 검증
- null 값이나 공백, 스페이스 같은 값들을 허용하지 않음
- 유효성 검증 실패하면 내장된 디폴트 에러 메세지 콘솔에 출력
- @Email
- 유효한 이메일 주소인지 검증
- 유효성 검증에 실패하면 내장된 디폴트 에러 메세지가 콘솔에 출력
- @Pattern
- 휴대폰 정보가 정규표현식에 매치되는 유효한 번호인지 검증
- 유효성 검증에 실패하면 내장된 디폴트 메세지가 콘솔에 출력
- 유효성 검증 로직이 실행되게 하기 위해서는 @Valid 애너테이션을 추가해야함
- 정규표현식 -> 다양한 조건을 선택적으로 검증하고자 할 때 유용한 방법 중 하나
name 멤버 변수에 사용한 “^\\S+(\\s?\\S+)*$” 정규 표현식
: ‘^’은 문자열의 시작을 의미합니다.‘$’는 문자열의 끝을 의미
‘*’는 ‘*’ 앞에 평가할 대상이 0개 또는 1개 이상인지를 평가
‘\s’는 공백 문자열을 의미
‘\S’ 공백 문자열이 아닌 나머지 문자열을 의미
‘?’는 ‘?’ 앞에 평가할 대상이 0개 또는 1개인지를 의미
‘+’는 ‘+’ 앞에 평가할 대상이 1개인지를 의미
- 여기서도 유효성 검증 로직이 실행되게 만들기 위해서는 @Valid 애너테이션 추가
- @Min(2) → 쿼리 파라미터 및 @Pathvariable에 대한 유효성 검증
- 2 이상의 숫자일 경우에만 유효성 검증에 통과하도록 애너테이션 추가
- 또한 이것에 대한 유효성 검증 정상적으로 수행하기 위해서는 클래스 레벨에 @Validated 애너테이션 반드시 추가해야함!
➡️ 그리고 포스트맨 URI Path에 올바르지 않은 값을 입력하면 아래와 같이 나옴
➡️ 콘솔창도 확인해보면 아래와 같이 나옴
🔎 Jakarta Bean Validation?
➡️ 오늘 유효성 검증을 위해 사용한 애너테이션은 Jakarta Bean Validation이라는 유효성 검증을 위한 표준 스펙에서 지원하는 내장 애너테이션
➡️ 일종의 기능 명세라고 할 수 있음
🔎 Custom Validator
➡️ 유효성을 검증을 적용하다보면 목적에 맞는 애너테이션이 존재하지 않을 수도 있음 이런 경우 목적에 맞는 애너테이션을 직접 만들어서 유효성 검증에 적용할 수 있음
'SEB_BE_45 > 공부 정리' 카테고리의 다른 글
[Sectoion3] Spring MVC - 예외 처리 (0) | 2023.06.14 |
---|---|
[Section3] Spring MVC - 서비스 계층 (0) | 2023.06.13 |
[Section3] Spring MVC - API 계층 1 (0) | 2023.06.12 |
[SEB BE] Section 2 회고 / 20230608 (0) | 2023.06.08 |
[Section2] Spring Framework 핵심 - AOP2 (0) | 2023.06.07 |