Java/Spring Boot

Spring boot @RestController 유효성 검사

요술공주밍키 2024. 9. 22. 15:26

발단

평상시 서버사이드로 프로젝트를 진행하다 보니 API로 로직을 구현하는 부분에 있어서 부족했던 것 같다.

이번에 API 프로젝트를 만들면서 유효성 검증을 하려고 보니 기존에 하던 방식과는 다른 부분이 있는 것

같아서 정리하려고 한다.


DTO 생성

우선 Controller에서 전달 받을 DTO와 반환할 DTO를 구현한다.

 

🟨 GetFolderListDTO

@Data
@Schema(description = "컨텐츠함 목록 요청 정보", requiredProperties = {"PARENT_FOLDER_ID"})
public class GetFolderListDTO {

    @JsonProperty("PARENT_FOLDER_ID")
    @Schema(description = "부모 컨텐츠함 아이디", example = "SW")
    @NotBlank(message = "해당 값은 필수 입력값입니다.")
    private String PARENT_FOLDER_ID;
}

 

@Schema나 @JsonProperty는 Swagger-ui를 위해 작성한 것이니 유효성 검사에는 영향이 없다.

 

🟨Response

@Data
@Builder
@Schema(description = "공통 Response 데이터")
public class Response<T> {

    @Schema(description = "Http status 값")
    private int status;

    @Schema(description = "Message")
    private String message;

    @Schema(description = "추가 데이터")
    private T data;
}

 

Response는 별도의 Object를 전달받아 반환할 수 있도록 구현했다.


✅ Controller

Controller에서는 @RequestBody 뒤에 @Valid만 붙여주면 된다.

@PostMapping("/folderList")
    public Response<?> getFolderList(@RequestBody @Valid GetFolderListDTO parameter) {
        // Controller logic...
    }

✅ @ControllerAdvice

이제는 모든 컨트롤러에서 DTO의 유효성 검사를 통과하지 못하면 에러를 반환할 수 있도록 예외처리를 진행한다.

@ControllerAdvice
public class ExceptionController {

    @ResponseBody
    @ExceptionHandler(BindException.class)
    public Response<?> handleBindException(BindException ex) {
        List<FieldError> errors = ex.getBindingResult().getFieldErrors();
        List errorList = new ArrayList<>();

        for (FieldError fieldError : errors) {
            Map err = new HashMap();
            err.put("fieldName", fieldError.getField());
            err.put("message", fieldError.getDefaultMessage());
            errorList.add(err);
        }

        return Response.builder()
                .status(HttpStatus.BAD_REQUEST.value())
                .message("Validation Error")
                .data(errorList)
                .build();
    }
}

 

@Valid를 통과하지 못하고 BindingError가 나타났을 때 위 로직을 통해 ResponseDTO를 반환하도록 처리하였다.


✅ 테스트

Request 정보를 아무것도 담지 않았다.

 

위 사진처럼 Request 정보에 아무것도 담지 않고 전송했을 때 아래와 같이 출력된다.

 

정상적으로 데이터 반환