인프런 커뮤니티 질문&답변

박성환님의 프로필 이미지
박성환

작성한 질문수

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

@ExceptionHandler

ExceptionHandler와 BasicErrorController에 대한 궁금증

해결된 질문

작성

·

355

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 

[질문 내용]
안녕하세요. 강의를 듣던 도중 궁금한 점이 생겨 질문을 남겨 봅니다.
API 예외를 처리할 때는 ExceptionHandler를 사용하여 처리하고,
HTML 화면을 제공할 때 예외 처리는 BasicErrorController를 사용하는게 편하다고 강의에서 말씀해주셨는데요

@Controller
@Slf4j
public class TestErrorController {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public ErrorResult IllegalArgumentException(IllegalArgumentException e) {
        log.info("IllegalArgumentException ", e);

        return new ErrorResult("BAD Argument", e.getMessage());
    }

    @GetMapping("/test/error/{id}")
    public String testException(@PathVariable String id) {
        if (id.equals("bad")) {
            throw new IllegalArgumentException("bad argument");
        }
        return "home";
    }

    @GetMapping("/test/error2/{id}")
    @ResponseBody
    public String testException2(@PathVariable String id) {
        if (id.equals("bad")) {
            throw new IllegalArgumentException("bad argument");
        }
        return "OK";
    }

}

위와 같이 RestController가 아닌 Controller에서
View를 반환해주는 메서드가 있고, HTTP 메시지바디에 문자열을 반환해주는 메서드가 있는 상태에서
API 예외를 처리하는 @ExceptionHandler를 작성 하였고 테스트를 위해

/test/error/bad, /test/error2/bad를 호출해보면 둘 다 @ExceptionHandler가 예외를 처리하여 JSON 문자열이 반환되어 지더라구요..

여기서 궁금점이 생기게 되었는데요

  1. 위와 같이 하나의 컨트롤러에서 View를 반환해주었을 때 IllegalArgumentException이 발생했다면 BasicErrorController처럼 오류페이지를 반환하고,
    API 의 경우 IllegalArgumentException이 발생하면 @ExceptionHandler에서 처리를 할 수 있는 방법은 없는 걸까요??

  2. 만약 위의 질문에 대한 답이 없다 라고 한다면 실무에서 개발 설계를 할 때, API 컨트롤러와 View를 반환해주는 컨트롤러를 분리하여 설계를 하나요?

답변 1

1

안녕하세요. 박성환님, 공식 서포터즈 y2gcoder입니다.

 

@ExceptionHandler는 해당 애노테이션이 위치한 컨트롤러에서 대상 예외가 발생했을 때 처리하게 됩니다. 그래서 아마도 위에서 말씀하신대로 모두 API 예외 응답으로 처리된 것 같습니다. API 예외 처리 - @ExceptionHandler 챕터부터 강의 자료와 함께 차근차근 수강하시면 아마 이해하실 것 같습니다 :)

그리고 보통 실무에서는 API 컨트롤러와 View를 반환하는 컨트롤러를 분리하여 개발하는 것이 일반적입니다. 두 컨트롤러는 보통 요청과 응답을 제공하는 것에 있고 그 방식이 다르기 때문에 서로 분리해서 개발하는 것이 유지보수나, 책임 분리에 좋다고 생각합니다.

만약 위의 구조에서 API 컨트롤러와 뷰 컨트롤러에 따라 응답을 처리하고 싶다면 방법은 있습니다. @ExceptionHandler가 붙은 메서드에서 HttpServletRequest를 파라미터로 받고, getHeader()를 이용해서 Accept 헤더를 조회하여 Accept 헤더 타입에 따라 json 응답과 View 응답을 분기처리 해주시면 됩니다. 다만 이 부분은 컨트롤러 분리보다 훨씬 더 비효율적인 처리라 생각하기 때문에 추천하지는 않습니다 :)

감사합니다.

박성환님의 프로필 이미지
박성환
질문자

말씀하신 @ExceptionHandler에서 분기를 처리하는 것은 좋은 방법 같지는 않아
API 컨트롤러와 View를 반환하는 컨트롤러를 분리하여 개발하는 방법을 활용하는게 좋을꺼 같네요!

답변 덕분에 궁금증이 해결 되었습니다!! 감사합니다!

파이팅입니다!

박성환님의 프로필 이미지
박성환

작성한 질문수

질문하기