CommonException 으로 @Valid 어노테이션 BindingException, MethodArgumentNotValidException 처리하기

반응형
728x90
반응형

설정

1) build.gradle 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

2) @Valid 어노테이션 추가

/**
* 회원 등록
* @param memberDto
* @return
*/
@PostMapping("")
public ResponseEntity<?> addMember(@ModelAttribute @Valid MemberDto memberDto) {
  /* 패스워드 암호화 */
  memberDto.setMemberPwd(passwordEncoding.encode(memberDto.getMemberPwd()));

  Member member = memberService.addMember(memberDto);

  ...
}

 

3) MemberDto.java 어노테이션 추가

@Data
public class MemberDto {
    @ApiParam(hidden = true)
    private Long idx;

    @ApiParam(defaultValue = "test123")
    @NotNull
    @NotBlank
    private String memberId;

    @ApiParam(defaultValue = "abc123")
    @NotNull
    @NotBlank
    private String memberPwd;

    @ApiParam(defaultValue = "F")
    @NotNull
    @NotBlank
    private String memberGender;

    @ApiParam(defaultValue = "01012341234")
    @NotNull
    @NotBlank
    private String memberPhone;
}

 

 

고의 에러 발생

Field error in object 'memberDto' on field 'memberId': 
rejected value [null]; codes [NotNull.memberDto.memberId,NotNull.memberId,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [memberDto.memberId,memberId]; arguments []; default message [memberId]]; 
default message [널이어서는 안됩니다]
Field error in object 'memberDto' on field 'memberId': rejected value [null]; codes [NotBlank.memberDto.memberId,NotBlank.memberId,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [memberDto.memberId,memberId]; arguments []; default message [memberId]]; 
default message [공백일 수 없습니다]]

 

이렇게 에러가 발생한 경우, 스프링부트의 에러 메시지가 결과로 내려간다.

{
  "timestamp": "2021-02-18T10:27:15.828+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "",
  "path": "/member"
}

 

 

공통 에러 처리

이전 포스팅 바로가기 : devfunny.tistory.com/318

 

스프링부트 공통 Exception 처리하기

사용된 어노테이션 SpringBoot 프레임워크에서 Exception 처리를 공통처리를 해보자. 그전에, 알아야할 어노테이션을 정리해보자. 어노테이션 설명 @RestController @Controller + @ResponseBody 이다. Json, Xml..

devfunny.tistory.com

 

우선 간단히 @ExceptionHandler 을 추가하여 디버깅 모드로 확인해보자. @Valid 에러는 아래 코드로 잡을 수 있다.

/**
* validation 에러
* @param exception
* @return
*/
@ExceptionHandler({BindException.class})
public ResponseEntity<?> errorValid(BindException exception) {
	BindingResult bindingResult = exception.getBindingResult();
	
	...
}

 

디버깅 모드로 BindingResult 객체를 들여다보면 아래 이미지와 같이 필드, 필드명, 값, 메시지 등이 들어있다.

 

 

getFieldErrors()를 하여 필드와 메시지를 통해 우리는 Validation Error Message를 아래와 같이 결과로 내려줄 수 있다.

/**
* validation 에러
* @param exception
* @return
*/
@ExceptionHandler({BindException.class})
public ResponseEntity<?> errorValid2(BindException exception) {
  BindingResult bindingResult = exception.getBindingResult();

  StringBuilder stringBuilder = new StringBuilder();

  for (FieldError fieldError : bindingResult.getFieldErrors()) {
    stringBuilder.append(fieldError.getField()).append(":");
    stringBuilder.append(fieldError.getDefaultMessage());
    stringBuilder.append(", ");
  }

  return CommonResponse.send(HttpStatus.BAD_REQUEST, stringBuilder.toString(), null);
}

 

결과

{
  "message": "memberId:널이어서는 안됩니다, memberId:공백일 수 없습니다, ",
  "items": null,
  "status": 400
}

 

 

BindException vs MethodArgumentNotValidException

/**
* validation 에러 (@ModelAttribute)
* @param exception
* @return
*/
@ExceptionHandler({BindException.class})
public ResponseEntity<?> errorValid(BindException exception) {
  BindingResult bindingResult = exception.getBindingResult();

  StringBuilder stringBuilder = new StringBuilder();

  for (FieldError fieldError : bindingResult.getFieldErrors()) {
    stringBuilder.append(fieldError.getField()).append(":");
    stringBuilder.append(fieldError.getDefaultMessage());
    stringBuilder.append(", ");
  }

  return CommonResponse.send(HttpStatus.BAD_REQUEST, stringBuilder.toString(), null);
}

/**
* validation 에러  (@RequestBody)
* @param exception
* @return
*/
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<?> errorArgumentValid(MethodArgumentNotValidException exception) {
  BindingResult bindingResult = exception.getBindingResult();

  StringBuilder stringBuilder = new StringBuilder();

  for (FieldError fieldError : bindingResult.getFieldErrors()) {
    stringBuilder.append(fieldError.getField()).append(":");
    stringBuilder.append(fieldError.getDefaultMessage());
    stringBuilder.append(", ");
  }

  return CommonResponse.send(HttpStatus.BAD_REQUEST, stringBuilder.toString(), null);
}

 

@Valid 로 인한 에러 발생을 잡아낼 수 있는 여러 에러들이 있다.

 

1) BindException.class

 

@ModelAttribute 어노테이션으로 받은 파라미터

 

 

2) MethodArgumentNotValidException

 

@RequestBody 어노테이션으로 받은 파라미터

 

 

 

반응형

Designed by JB FACTORY