본문 바로가기
백엔드/스프링 핵심 개념

Validation, Data binding

by 임지혁코딩 2023. 12. 26.

Validation -> 유효성 검증 

사용자, 혹은 서버의 요청을 받는 서버에 관련하여 . 잘못된 내용이 있는지 확인한다. 

 

데이터 검증 . 데이터 하나하나를 확인. 

필수 데이터의 존재 유무, 문자열 길이, 값의 범위 , email , 신용카드같은 형식에 따른 데이터 

 

비지니스 검증 . 결재 잔액은 충분한가? db의 데이터까지 조회, 검증 . 

-> 반드시 분리되는 개념이진 않음 . 

 

Spring 의 Validation 

Java Bean Validation 

-> javabean은 데이터를 쉽게 넣었다 뺴는 단순 구조의 class. 개별 데이터를 검증하기 . 

 name , age , email등의 변수가 있는 user class . 

 

public class MemberCreationReqeust  {

    @NotBlank(message ="이름 입력")
    @Size(max=64,message("이름제약 64자"))
    private String name;
    @Min(0,"나이는 0이상이지")
    private int age ;
    @Email("이메일형식이아님")
    private int email ;
}

 

어노테이션이, 검증의 역할을 해준다.  이것은 이것입니다. 봐주세요. 와 같은 의미 

pulbic MemberCreateResponse createMember; {
    @Valid
    @RequestBody
    final MemberCreationReqeust memberCreationReqeust {

    }
}
//제목에 writecopy가 아닌, MemberCreation 

 

@Valid -> 자바 빈 validation 이후 ,문제 없을시 처리.

문제가 발생하면 MethodArgumentNotValidException 발생

 

방법 2 

Person class의 private String name ; private int age; 와 같이 두개가 있을때. 

 

public class PersonValidatior implements Validator
{
    public void validate(Object.obj, Errors e)
    {
        ValdiatorUtils.rejectIfEmpty(e,"name","name.empty")
        Person p = (Person)obj;
        if (p.getAge() < 0)
        {
            e.rejectValue("age","negativevalue") ;
        }
        else if (p.getAge() > 10 )
        {
            e.rejectValue("age","too.old") ;
        }

    }
}

 

Validator 인터페이스를 상속받아, 내부 내용을 추가하는 식으로 구현할수 있다. 

(내가 원하는 방식으로 좀더 복잡한 validate가 가능하다. ) -> 하지만 어디서 부터 발생시킬지가 어렵다. 

중복 검증 확률도 증가한다. 

 

주의 사항 -> 반복적이고 중복적인 validation을 지 양 한다. 

validation 정책 자체는 동일 해야한다. 즉, 초기 수행, 실패시 바로 expection으로 끝내버리는 것이 유용한 사용이다.

 

Dto에서 bean을 활용해서 1차로 기본적인 데이터의 검증을 진행.  

그 이후 비지니스를 검증하고. 그때 excpetion을 발생시켜서 handler로 예외 처리, 에러 응답 형성

 

Data Binding

validation 이후, 사용자나 외부의 요청 데이터를 객체에 저장해서 request에 담아 주는 것. 

 

Converter Interface - > 2개의 type을 지닌다.  

public interface Converter <S,T>
{
    T convert(S source);
}

 

 

json이라는 data(결국 string)를 java bean인 class XAuthUser의 정보에 맞춰 넣고 싶다. 

XAuthUserConverter implements Converter<String,XAuthUser> {

 source는 string이며, target객체는 XAuthUser 로 특정 class에 넣어줄 수 있다. 

}

이와 같이 string문자열(json)을, 객체에 넣어주는 역할을 간단하게 해낼 수 있다.

 

동작 원리? String-> XAuthUser로 Converter 구현, 그 converter를 @Component로 java container에 결합. 

스프링 내의 ConversionService에서 우리 가만든 Converter를 Converterlist에 등록. 

.. RequestBody ? 결국엔 json 형식 data or key,value값의 데이터의 문자열 .

그것을 받아서 특정 객체로 변경해주는 converter가 들옥되어있는 것이다. 

 

X-auth-user : {"id" :123, "name" :"지혁"} ;

public class XAuthUser {
    private int id;
    private String name;
} //여기에 넣고 싶다.

@GetMapping("/user-info")
public UserInfoResponse getUserInfo(@RequestHeader("x-auth-user") XAuthUser xauthuser)
{
    //내가하고싶은일

}

@Component
public class XAuthUserConverter implements Converter<String, XAuthUser>
{
    @Override
    public XAuthUser convert(String source)
    {
        return objectMapper.readValue(source,XAuthUser.class)
    }
}

 

혹은,

@Requestbody 한줄 만으로, 객체에 담을 수 있게 되는 것이다. -> converter가 필요없다. 

 

Formatter -> 동일하게 @Component로 등록하여 활용할 수 있다. 

객체 <> string간의 변경 

Response시도 활용된다.  Date라는 객체를 문자열로 변경하여 보내주는 것. 

혹은 문자열로 받은 Date를 Date에 담아주고 싶을때. 

public final class DateFormatter implements Formatter<Date>
{
    public String print(Date date, locale locale)
    {
        return getDateFormat(locale).format(date) ;
    }

}

get dateformat같은 내용은 없지만, formatter와 Converter를 통해 객체와 request, response 상호간 변경이 이루어 짐을 깨달았다. 

 

이는 후에 request, response시에 객체를 담는 방법이 될 것이다(@REQUESTBODY를 많이 쓰겠지만서도)

 

주로 사용되는 requestbody의 실제 예시

 

 

@RestController
@RequestMapping("/api")
public class MyController {

    @PostMapping("/create")
    public ResponseEntity<MyResponse> create(@RequestBody MyRequest request) {
        // request 객체에 담긴 데이터를 처리하고, MyResponse 객체를 생성하여 반환
    }
}

'백엔드 > 스프링 핵심 개념' 카테고리의 다른 글

SpEL  (0) 2023.12.27
Resource  (0) 2023.12.26
AOP  (0) 2023.12.25
JAVA- spring, spring boot/ BEAN  (0) 2023.12.25
API  (1) 2023.12.20