본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


SPRING BOOT

Spring boot 공부 4 - Error 데이터 커스터마이징해서 응답

반응형

@ExceptionHandler를 통해 예외를 잡아 응답하는 방식을 알아봤었다. 

 

다른 처리를 하지 않는다면 , 기본적인 정보들만 응답이 되기 때문에 

 

해당에러에 대한 정보를 ExceptionHandler 메소드의 파라미터를 통해 뽑아내 json 형식 데이터로 내려 주는 방법을 알아보자. 

 

MethodArgumentNotValidException 을 예외처리한다 가정해 봤다 . 

 

 

ExceptionHandler 메소드의 코드는 아래와 같다

 

 @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity MethodArgumentNotValidException(MethodArgumentNotValidException e,HttpServletRequest request){
        //error 담을 리스트
        List<Error>  errors = new ArrayList<>();

        //에러에서 BindingResult를 가져와
        BindingResult bindingResult = e.getBindingResult();
        //해당 BindingResult에서 발생한 에러를 모두 가져와 forEach을 통해 작업한다
        bindingResult.getAllErrors().forEach(error ->{
            
            //각각의 error 객체가 들어와 FieldError 타입으로 형변환 되고
            FieldError field = (FieldError) error;
            //해당 필드에서 이름, 에러 메세지 , 들어온 값을 뽑아낸다.  
            String fieldName = field.getField();
            String message = field.getDefaultMessage();
            String invalidValue = field.getRejectedValue().toString();

            // Error에 위에 뽑아놓은 에러정보를 담고
            Error errorMessage = new Error();
            errorMessage.setMessage(message);
            errorMessage.setField(fieldName);
            errorMessage.setInvalidValue(invalidValue);

            //에러리스트에 에러를 담았다.
            errors.add(errorMessage);
        });
        
        //실제 응답바디에 담길 errorResponse를 만들어 에러에 대한 기본정보를 담고
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage("");
        errorResponse.setRequestUrl(request.getRequestURI());
        errorResponse.setStatusCode(HttpStatus.BAD_REQUEST.toString());
        errorResponse.setResultCode("FAIL");
        //발생한 에러리스트를 담아준다. 
        errorResponse.setErrorList(errors);
		
        //응답 바디에  errorResponse를 담아 리턴한다. 
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
        
        
    }

 

아직은 익숙하지 않지만 API 스펙을 머리 속으로 그려보고 뭘 집어넣어야 할지 생각 해보면  클래스를 어떻게 만들지가 더 잘 그려지는 것 같다. 

 

응답 body에 내려보낼 api 스펙을 먼저 그려보자 

 

 

{
   "statusCode":"",
   "requestUrl":"",
   "code":,
   "message":"",
   "resultCode":"",
   "errorList":[
      {
         "field":"",
         "message":"",
         "invalidValue":""
      },
      {
         "field":"",
         "message":"",
         "invalidValue":""
      },
      {
         "field":"",
         "message":"",
         "invalidValue":""
      }
   ]
}

 

 

위의 자바 코드를 보면 알수 있듯이 

 

ErrorResponse 에 해당 응답에 대한 기본적인 정보들이 들어있으며 HttpServletRequest를 통해 해당 요청에 대한 정보를 가져올 수 있다 , errorList에는 실제 일어난 Error가 배열 형태로 들어가 있다.

 

MethodArgumentNotValidException는 요청 데이터가 넘어와 validation annotation을 통해 검증을 하던 중에 검증에 실패하게 되면 생기는 예외이다.  

 

Error는 MethodArgumentNotValidException에서 뽑아낸 해당 Error가 일어난 field 명, error 가 일어난 이유(message) , 잘못 들어온 값이 들어 있다.  

 

User 클래스는 아래와 같이  validation 되어있다.  

public class User {

    @NotEmpty
    @Size(min = 1,max = 10)
    private String name;

    @Min(value = 1)
    @NotNull
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 

 

요청을 해보자 검증에 실패해 예외를 확인하기 위해 잘못된 값을 넘겨 봤다 .

 

 

 

 

 

요청 결과 

 

errorResponse 데이터가 잘 담겨서 전달 됬다. 

 

 

반응형