inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발

Version 관리 - URI를 이용한 버전관리

@ExceptionHandler(MethodArgumentNotValidException.class) 예외 response 메서드 파라미터 관련하여 질문있습니다.

898

sumni010405

작성한 질문수 2

0

안녕하세요.
유효성 체크를 위한 Validation API 사용 강의를 듣고 의문이 생겨 질문드립니다.

ResponseEntityExceptionHandler 클래스에 http 예외 response 메서드가 정의되어있다고 하셨고, 이를 오버라이딩하여 사용했을 때는

@Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) {
        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage(ex.getMessage())
                .details(ex.getBindingResult().toString())
                .build();
        
        return ResponseEntity.status(status).body(exceptionResponse);
    }

스크린샷 2022-10-11 오후 2.18.08.png의도한대로 exceptionResponse가 http body에 들어갔습니다.

 

제가 여기서 ResponseEntityExceptionHandler 클래스를 상속받지 않고, @ExceptionHanlder(MethodArgumentNotValidException.class)를 통해 에러를 캐치하고자 하였는데요.

@Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) {
        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage("Validation Failed")
                .details(ex.getBindingResult().toString())
                .build();

        return ResponseEntity.status(status).body(exceptionResponse);
    }

스크린샷 2022-10-11 오후 3.26.10.png이때는 저희가 작성한 exceptionResponse가 http body에 담기지 않는 것을 확인할 수 있었습니다.

그래서 앞서 작성한 메서드(MethodArgumentNotValidException.class만 캐치하는 메서드)를 삭제하였을 때는

@ExceptionHandler(Exception.class)
    public final ResponseEntity<Object>handleAllExceptions(Exception ex, WebRequest request){

        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage(ex.getMessage())
                .build();

        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(exceptionResponse);
    }

전체 에러를 잡는 메서드가 따로 있기 때문에

스크린샷 2022-10-11 오후 2.18.08.png커스텀한 에러 메시지가 응답되었습니다.

 

여기서 제가 내린 결론은

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) {
        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage("Validation Failed")
                .details(ex.getBindingResult().toString())
                .build();

        return ResponseEntity.status(status).body(exceptionResponse);
    }

해당 메서드가 MethodArgumentNotValidException.class 에러를 캐치하지만 로직을 수행하고 있지 못하다. 입니다.

 

그래서 다음과 같이 파라미터를 바꾸어줬더니

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage("Validation Failed")
                .details(ex.getBindingResult().toString())
                .build();

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exceptionResponse);
    }
   

에러를 캐치하고 Custom한 ResponseException을 전달받았습니다.

 

그럼 이러한 에러를 캐치하고 custom한 responseException을 만들 때 메서드의 파라미터는 어떻게 정해야 하는 건가요????

 

또한, 제가 생각한 이 과정이 맞는지 궁금합니다.

rest-api spring-boot

답변 1

1

Dowon Lee

안녕하세요, 이도원입니다.

오류가 발생하신 부분에 대해서 잘 정리해 주셨는데, 아래 내용에서 조금 이상한 점이 있네요.

...

"제가 여기서 ResponseEntityExceptionHandler 클래스를 상속받지 않고, @ExceptionHanlder(MethodArgumentNotValidException.class)를 통해 에러를 캐치하고자 하였는데요."

...

말씀하신 내용처럼 ResponseEntityExceptionHandler 클래스를 상속받지 않으셨다고 하면, @Override를 사용하실 수 없을텐데, 해당 코드에는 @Overriderk 되어 있어서, 질문의 내용을 완전하게 이해하기가 어려웠습니다. 다만, 마지막에 정리하신 내용을 보면

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) {
        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage("Validation Failed")
                .details(ex.getBindingResult().toString())
                .build();

        return ResponseEntity.status(status).body(exceptionResponse);
    }

위 코드는 실행이 되지 않았고,

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
        ExceptionResponse exceptionResponse=ExceptionResponse.builder()
                .timestamp(new Date())
                .messsage("Validation Failed")
                .details(ex.getBindingResult().toString())
                .build();

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exceptionResponse);
    }
   

위 코드는 실행이 되었다는 것으로 이해했습니다. (맞나요??)

위와같은 상황이라면, @ExceptionHandler를 사용하실 때, 메소드의 Argument에는 정해져 있는 내용들만 선언될 수 있습니다. (대신 순서는 상관없는 것으로 압니다)

따라서, MethodArgumentNotValidationException과 WebRequset는 선언 시 문제가 되지 않지만, 이회의 HttpHeaders, HttpStatus를 같이 선언하여 사용하실 때에는 오류가 발생하고, 실제 콘솔 로그를 보시면 아래와 같은 오류를 확인해 보실 수 있습니다.

java.lang.IllegalStateException: Could not resolve parameter [1] in public org.springframework.http.ResponseEntity<java.lang.Object> com.example.myrestfulservices.exception.CustomizedResponseEntityExceptionHandler.handleMethodArgumentNotValid(org.springframework.web.bind.MethodArgumentNotValidException,org.springframework.http.HttpHeaders,org.springframework.http.HttpStatus,org.springframework.web.context.request.WebRequest): No suitable resolver

따라서, @ExceptionHandler를 사용하실 때, MethodArgumentNotValidationException만 선언해서 실행하였을 때 정상작동되었었습니다.

정리하면, @ExceptionHandler를 사용하실 때, 기존의 @Override 메소드에서 정의된 아래와 같은 인자값들을 모두 선언하여 사용하시면 No suitable resolver 오류가 발생하기 때문에, 사용하시는 인자값을 구분하여 실행하셔야 할 것 같습니다.

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) { ...

사용 가능한 인자값으로는,

Exception 객체, Request나 Response 객체, Session 객체, WebRequest 객체, Locale 객체, InputStream이나 OutputStream 객첵, Model 객체가 있습니다.

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html

질문에 대한 답변이 되었으면 좋겠네요.

감사합니다.

JPA

0

62

1

jpa dependency를 추가하고 SecurityConfig클래스에서 오류가 납니다.

0

71

1

웹 브라우저 400 bad request

0

73

1

@Size는 되는데 @Past는 안 됩니다.

0

64

1

pdf 자료는 없나요?

0

76

2

locale 정보가 null 이면 무조건 messages_ko.properties이 호출 되는 문제

0

91

2

Swagger 강의, Unable to infer base url 이거 뜨시는 분들 도움되시라고

0

120

1

강의에서나온 화면 피피티

0

161

1

HelloWorldBean 관련 에러

0

189

2

Swagger API 3.x 오류..

0

223

1

java: variable message not initialized in the default constructor 에러는 어찌하면 좋을까요?

1

283

1

현재 GIT에 올리신 소스를 실행해봤습니다.

0

190

2

고양이 소리가 귀엽네요 !!

0

140

2

git에서 소스받고 실습중인데

0

120

1

post가 안되요

0

107

1

한국어 같은 경우 언어코드인 messages_ko.properties 로 생성하는게 더 좋지 않나요?

0

169

2

리턴타입으로서 EntityModel<User> 와 ResponseEntity질문

0

107

1

예외처리쪽 관련 질문있습니다.

0

161

2

엔티티가 바로 응답으로 나가도 되나요??

0

230

2

안녕하세여 Cannot invoke "co.kr.joneconsulting.resfulservice.repository.PostRepository.save(Object)" because "this.postRepository" is null

0

142

2

사용자 등록하고 나서 H2 에서 보면 신규 사용자의 password, ssn 이 null 로 되어 있습니다.

0

144

2

ApplictionContext 질문

0

196

2

롬북이 안먹히는것같아요

0

159

1

인텔리제이에서스프링부트 파일 실행하면

0

242

1