[40일차] DTO(Data Transfer Object) 유효성(Validation)

유태형·2022년 6월 24일
0

코드스테이츠

목록 보기
40/77

오늘의 목표

  1. DTO
  2. 유효성



내용

DTO(Data Transfer Object)

클라이언트에서 제공하는 JSON데이터를 서버에서 쉽게 처리하기 위해서 json을 객체로 만든 객체를 DTO라고 합니다.

DTO필드, getter, setter로 구성됩니다.

class Dtoclass{
	private String name;
    private lon id;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public long getId() {
        return id;
    }

    public void setId(int id) {
        this.name = name;
    }
}
	@PostMapping
    public ResponseEntity postMember(@RequestParam("email") String email,
                                     @RequestParam("name") String name,
                                     @RequestParam("phone") String phone) {
		
    }

클라이언트에서 서버로 전송되는 파라미터들을 @RequestParam("파라미터") 매개변수로 파라미터별로 매개변수로 받아야 했습니다. 3개가 아닌 만약 30개, 100개, 그이상일 경우 모두 매개변수로 받는건 굉장히 오버헤드가 큽니다.

	@PostMapping
    public ResponseEntity postMember(Dtoclass dtoclass) {
		
    }

DTO 객체 사용시 클라이언트에서 전달하는 파라미터 DTO객체의 필드에 스프링이 자동으로 대입하여 줍니다. 헨들러 메서드에서 해당 객체를 사용하면 간략하고 편리하게 이용할 수 있습니다.

	@PostMapping
    public ResponseEntity postMember(@RequestBody Dtoclass dtoclass) {
		
    }

클라이언트에서 서버로 HTML내의 파라미터가 아닌 JSON형태로 데이터를 전송시 @RequestBody 에너테이션을 사용하면 DTO객체로 받을 수 있습니다.




유효성(Validation)

스프링 프레임워크에서 제공하는 유효성 라이브러리를 사용하기위해서는 gradle의 dependecy에 추가해야만 합니다.

dependencies{
	implementation 'org.springframework.boot:spring-boot-starter-validation'
}

유효성 검사는 핸들러 메서드가 아닌 DTO 클래스에서 수행하게 됩니다.

class Dtoclass{
	@Email
    private String email;
    
    @NotBlank(message = "공백이 아니어야 합니다")
    private String name;
    
    @Pattern(regexp = "^([a-zA-Z])(?: [a-zA-Z])*$")
    private String product;
    
    ....getter & setter
}
유효성 검사설명
@Email이메일 형식으로 되어있는지 확인합니다.
@NotNullNull값이 아닌지 확인 합니다.
@NotEmptyNULL값이 아니고 ""빈 값이 아닌지 확인합니다.
@NotBlankNull값이 아니고 ""빈 값도 아니고 " "공백도 아닌지 확인합니다.
@Pattern(regexp = "정규포현식",message="메시지")정규표현식을 만족하는지 확인합니다. 만족하지 않을시 메시지를 출력하고 에러를 출력합니다.

핸들러 메서드의 매개변수에서 해당 DTO 객체로 받아 들일때 유효성 검사를 시행하기 위해서는 @Valid애너테이션을 추가해야 합니다.

	@PostMapping
    public ResponseEntity 핸들러메서드(@Valid @RequestBody Dtoclass dtoclass){
    	
    }

대표적인 정규포현식으로

  • ^010-\\d{3,4}=\\d{4}$ : 전화번호 형식의 정규표현식입니다.
  • ^[0-9a-zA-Z]([-_₩.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_₩.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$ : 이메일 형식의 정규 표현식입니다.
  • %(?=\\s*\\S).*$ : 공백이 아닌 문자열을 나타내는 정규 표현식입니다.

@PathVariable@RequestParam등의 애너테이션이 붙은 매개변수의 유효성을 검사하기 위해선 컨트롤러에 @Validated에너테이션이 필요합니다.

@RestController
@RequestMapping("/v1")
@Validated
public class 컨트롤러{
	@PatchMapping("/{id}")
    public ReponseEntity 핸들러메서드(@PathVariable("id") @Min(1) long id){
    	...
    }
}

@Min(값)은 해당 값 이상의 값이 매개변수로 전달되는지 유효성을 확인합니다.



Custom Validator

내장된 애너테이션 만으로는 목적에 맞는 에너테이션이 존재하지 않을 수 있습니다.
이 경우 유효성 검증을 직접 만들어서 적용할 수도 있습니다.

Custom Validator를 구현하기위한 3단계

  1. Custom Validator를 사용하기 위한 Custom Annotaion 정의
  2. Custom Annotation에 바인딩 되는 Custom Validator 구현
  3. DTO 클래스의 멤버 변수에 Custom Annotation 추가
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {NotSpaceValidator.class})
public @interface NotSpace{
	String message() default "공백이 아니어야 합니다.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
public class NotSpaceValidator implements ConstraintValidator<NotSpace, String>{
	public void initailize(NotSpace constraintAnnotation){
    	ConstraintValidator.super.initailize(constraintAnnotation);
    }
    
    public boolean isValid(String value, ConstraintValidatorContext context){
    return value == null || StringUtils.hasText(value));
    }
}
class Dtoclass{
    private String email;
    
    @NotSpace(message = "공백이 아니어야 합니다")
    private String name;
    
    @NotSpace(message = "공백이 아니어야 합니다")
    @Pattern(regexp = "^([a-zA-Z])(?: [a-zA-Z])*$")
    private String product;
    
    ....getter & setter
}



후기

DTO객체는 JSON데이터를 전달받아 비즈니스 로직을 편리하게 처리하기 위해 필요한 요소이고, 유효성 검사를 통해 잘못된 값을 전달받았을때 걸러줄 수 있는 중요한 기능을 학습하였습니다.




GitHub

https://github.com/ds02168/CodeStates_Spring/tree/main/section3-week1

profile
오늘도 내일도 화이팅!

0개의 댓글