250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- equals()
- 서블릿
- 프록시
- 인터페이스
- 참조변수
- 김영한
- 티스토리챌린지
- 코드트리조별과제
- @configuration
- html form
- 스프링컨테이너
- 싱글톤
- 오버라이딩
- 오블완
- 코딩테스트
- 추상클래스
- 스프링
- ocp
- 다형성
- HttpServletResponse
- 백준
- objecterror
- java
- http 메시지 컨버터
- fielderror
- 의존관계
- 테스트코드
- 코드트리
- JSON
- DI
Archives
- Today
- Total
minOS
API 예외 처리 - HandlerExceptionResolver 활용 본문
TIL/김영한의 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술
API 예외 처리 - HandlerExceptionResolver 활용
minOE 2024. 10. 7. 21:12728x90
API 예외 처리 - HandlerExceptionResolver 활용
이 코드에서 예외를 완전히 처리하기
예외가 발생하면 WAS까지 예외가 던져지고, WAS에서 오류 페이지 정보를 찾아서 다시 `/error` 를 호출하는 과정은
생각해보면 너무 복잡하다. `ExceptionResolver` 를 활용하면 예외가 발생했을 때 이런 복잡한 과정 없이 여기에서
문제를 깔끔하게 해결할 수 있다.
사용자 정의 UserException 클래스 생성package hello.exception.exception; public class UserException extends RuntimeException { public UserException() { super(); } public UserException(String message) { super(message); } public UserException(String message, Throwable cause) { super(message, cause); } public UserException(Throwable cause) { super(cause); } protected UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); }
사용자 오류 추가@Slf4j @RestController public class ApiExceptionController { @GetMapping("/api/members/{id}") public MemberDto getMember(@PathVariable("id") String id){ if (id.equals("ex")){ throw new RuntimeException("잘못된 사용자"); //500 html 반환 문제를 해결하려면 오류 페이지 컨트롤러도 JSON응답 할 수 있도록 수정해야한다. } if(id.equals("bad")){ throw new IllegalArgumentException("잘못된 입력 값"); } if(id.equals("user-ex")){ throw new UserException("사용자 오류"); } return new MemberDto(id,"hello "+id);
사용자 정의 예외 처리 클래스package hello.exception.resolver; import com.fasterxml.jackson.databind.ObjectMapper; import hello.exception.exception.UserException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import java.io.IOException; import java.util.HashMap; import java.util.Map; @Slf4j public class UserHandlerExceptionResolver implements HandlerExceptionResolver { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try { if (ex instanceof UserException) { log.info("UserException resolver to 400"); String acceptHeader = request.getHeader("accept"); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); if ("application/json".equals(acceptHeader)) { Map<String, Object> errorResult = new HashMap<>(); errorResult.put("ex", ex.getClass()); errorResult.put("message", ex.getMessage()); String result = objectMapper.writeValueAsString(errorResult); //Json - > String response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); response.getWriter().write(result); return new ModelAndView(); } else { // TEXT/HTML return new ModelAndView("error/500"); } } } catch (IOException e) { log.info("resolver ex", e); } return null; } }
HTTP 요청 해더의 `ACCEPT` 값이 `application/json` 이면 JSON으로 오류를 내려주고, 그 외 경우에는 error/
500에 있는 HTML 오류 페이지를 보여준다.
WebConfig에 UserHandlerExceptionResolver 추가
@Override public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { resolvers.add(new MyHandlerExceptionResolver()); resolvers.add(new UserHandlerExceptionResolver()); }
POSTMAN 결과 : http://localhost:8080/api/members/user-ex
TEXT/HTMl 경우 웹브라우저에서 기본으로 렌더링
정리
`ExceptionResolver` 를 사용하면 컨트롤러에서 예외가 발생해도 `ExceptionResolver` 에서 예외를 처리해버린다.
따라서 예외가 발생해도 서블릿 컨테이너까지 예외가 전달되지 않고, 스프링 MVC에서 예외 처리는 끝이 난다.
결과적으로 WAS 입장에서는 정상 처리가 된 것이다. 이렇게 예외를 이곳에서 모두 처리할 수 있다는 것이 핵심이다.
서블릿 컨테이너까지 예외가 올라가면 복잡하고 지저분하게 추가 프로세스가 실행된다. 반면에`ExceptionResolver` 를 사용하면 예외처리가 상당히 깔끔해진다.
728x90
'TIL > 김영한의 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술' 카테고리의 다른 글
API 예외 처리 - DefaultHandlerExceptionResolver (1) | 2024.10.09 |
---|---|
API 예외 처리 - ResponseStatusExceptionResolver (1) | 2024.10.09 |
API 예외 처리 - HandlerExceptionResolver 시작 (7) | 2024.10.07 |
API 예외처리 - 스프링 부트 기본 오류 처리 (1) | 2024.10.03 |
API 예외 처리 - 시작 (0) | 2024.10.02 |