Spring Boot – @Valid

By | 2023년 2월 18일
Table of Contents

Spring Boot – @Valid

@Valid 사용방법 및 MethodArgumentNotValidException 처리 방법을 정리해봅니다.

의존성 추가

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

DTO

@Getter
@Setter
@NoArgsConstructor
public class LoginRequestDto {
    @NotEmpty(message = "로그인 아이디를 입력하세요")
    private String userLoginId;
    @NotEmpty(message = "로그인 비밀번호를 입력하세요")
    private String userLoginPassword;
}

Controller

@RestController
@RequiredArgsConstructor
@RequestMapping("/v1/login")
public class LoginController {
    @PostMapping("/")
    public ResponseEntity<?> login(@Valid @RequestBody LoginRequestDto dto) {
        return service.login(dto);
    }
}

RestControllerAdvice

@RestControllerAdvice("kr.pe.skyer9.warehouse.account.web")
public class AccountRestExceptionHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        return ResponseEntity.status(460) // 460 = custom error code
                .body(
                        new ApiResponseMessage(
                                ResponseCode.ERROR_FIELD_REQUIRED,
                                e.getBindingResult().getAllErrors().get(0).getDefaultMessage())
                );
    }
}

Feign error handling

수신부가 Feign 인 경우 아래처럼 @ControllerAdvice 를 이용해 처리할 수 있습니다.

public class FeignErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        switch (response.status()) {
            case 460: // 460 = custom error code
                ApiResponseMessage message;
                try (InputStream bodyIs = response.body().asInputStream()) {
                    ObjectMapper mapper = new ObjectMapper();
                    message = mapper.readValue(bodyIs, ApiResponseMessage.class);
                } catch (IOException e) {
                    return new Exception(e.getMessage());
                }
                return new ApiServerException(message.getMessage());
            default:
                return new Exception(response.reason());
        }
        return null;
    }
}
public class ApiServerException extends RuntimeException {
    public ApiServerException(String message) {
        super(message);
    }
}
@ControllerAdvice
public class ApiServerExceptionHandler {
    @ExceptionHandler({ApiServerException.class})
    public ResponseEntity<?> handleApiServerException(HttpServletResponse response, ApiServerException ex) throws IOException {
        ScriptUtil.alertAndBackPage(response, ex.getMessage());
        return null;
    }
}

답글 남기기