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
- pointcut
- java
- db
- spring
- JPQL
- Exception
- Thymeleaf
- 김영한
- 자바
- transaction
- springdatajpa
- Spring Boot
- kotlin
- 그리디
- Servlet
- 스프링
- Greedy
- jpa
- 백준
- Android
- SpringBoot
- 인프런
- http
- 알고리즘
- JDBC
- QueryDSL
- Proxy
- 스프링 핵심 원리
- 스프링 핵심 기능
- AOP
Archives
- Today
- Total
개발자되기 프로젝트
[API예외] HandlerExceptionResolver 본문
- 예외가 발생해서 서블릿을 넘어 WAS까지 예외가 전달되면
- HTTP 상태코드가 500으로 처리된다.
- 발생하는 예외에 따라서 400, 404 등등 다른 상태코드로 처리하고 싶은데?
- 오류 메시지, 형식등을 API마다 다르게 처리하고 싶다.??
- 예를들어 IllegalArgumentException이 controller 밖으로 넘어가면???400으로 처리하고 싶음!
- 400 : Client가 범인임!
1. ApiExceptionController
- "/api/members/bad"로 넘어오면 IllegalArgumentException을 던지자.
@GetMapping("/api/members/{id}")
public MemberDto getMember(@PathVariable("id") String id){
if(id.equals("ex")){
throw new RuntimeException("잘못된 사용자");
}
if(id.equals("bad")){
throw new IllegalArgumentException("잘못된 입력값");
}
return new MemberDto(id, "hello"+id);
}
- 하지만 WAS 입장에서는 Server에서 예외가 발생해서 WAS까지 왔으니 500이다.
2. HandlerExceptionResolver
- 스프링 MVC는 컨트롤러(핸들러) 밖으로 예외가 던져진 경우
- 예외를 해결하고, 동작을 새로 정의할 수 있는 방법을 제공.
- 컨트롤러 밖으로 던져진 예외를 해결하고, 동작 방식을 변경하고 싶으면
HandlerExceptionResolver 를 사용하면 된다. 줄여서 ExceptionResolver
2.1 ExceptionResolver 적용 전
2.2 ExceptionResolver 적용 후
- 마찬가지로 예외터지면 postHAndle은 호출 안함.
- 대신에 ExceptionResolver가 있으면 호출함.
- 여기서 예외 처리가 되면 정상응답으로 나감.
- WAS 가 500으로 던지지 않고, 개발자가 정의한 로직으로 처리 가능?
3. HandlerExceptionResolver 인터페이스
- handler : 핸들러(컨트롤러) 정보
- Exception ex : 핸들러(컨트롤러)에서 발생한 발생한 예외
- 해당 인터페이스를 구현하면 예외 발생 시 원하는 로직으로 처리 가능.
public interface HandlerExceptionResolver {
ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}
4. MyHandlerExceptionResolver
- HandlerExceptionResolver를 구현해보자.
- IllegalArgumentException이 넘어온 경우 HttpServletReponse에 상태코드를 400(Bad Request)로 지정!
- ModelAndView를 새로 만들어서 return 한다.
- ModelAndView 를 반환하는 이유는 마치 try, catch를 하듯이,
- Exception 을 처리해서 정상 흐름 처럼 변경하는 것이 목적!!!
- 발생한 예외를 먹어버리고, 정상적인 것 처럼 ModelAndView를 반환.
- Servlet은 빈 model, View를 받는다. 뿌릴 view가 없다 ㅋㅋ
- WAS는 response를 보고 senError가 호출되었는지 확인.
- 이 때 400이구나!!! 이에 맞는 로직으로 처리함.
- 기존처럼 예외발생 시 500으로 처리하지 않음.
@Slf4j
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
try {
if (ex instanceof IllegalArgumentException) {
log.info("IllegalArgumentException resolver to 400");
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
return new ModelAndView();
//예외를 먹어버리고, 빈 ModelAndView를 반환하면 정상처리 가능.
//return return -> Servlet까지 올라감.
//WAS는 sendError 호출했는지 봤는데 400이네? 이에 해당하는 로직 처리함.
}
}catch (IOException e){
log.error("resolver ex", e);
}
//null을 return 하면 터진 예외가 쭈욱 올라감.
return null;
}
}
5. HandlerExceptionResolver 등록
- extendHandlerExceptionResolvers() 사용
- configureHandlerExceptionResolvers(..) 를 사용하면 스프링이 기본으로 등록하는
ExceptionResolver 가 제거되므로 주의, extendHandlerExceptionResolvers 를 사용하자.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add(new MyHandlerExceptionResolver());
}
}
6. 반환 값에 따른 동작 방식
- HandlerExceptionResolver 의 반환 값에 따른 DispatcherServlet 의 동작 방식이 달라진다.
- 빈 ModelAndView: new ModelAndView() 처럼 빈 ModelAndView 를 반환하면
- 뷰를 렌더링 하지않고, 정상 흐름으로 서블릿이 리턴된다.
- ModelAndView 지정: ModelAndView 에 View , Model 등의 정보를 지정해서 반환하면 뷰를 렌더링
- null: null 을 반환하면, 다음 ExceptionResolver 를 찾아서 실행한다. Exception이 그대로 넘어감.
- 만약 처리할 수 있는ExceptionResolver 가 없으면 예외 처리가 안되고,
- 기존에 발생한 예외를 서블릿 밖으로 던진다. -> WAS는 500으로 처리함.
7. ExceptionResolver 활용
- 예외 상태 코드 변환
- 예외를 response.sendError(xxx) 호출로 변경해서
- 서블릿에서 상태 코드에 따른 오류를 처리하도록 위임
- 이후 WAS는 서블릿 오류 페이지를 찾아서 내부 호출,
- 예를 들어서 스프링 부트가 기본으로 설정한 /error 가 호출됨
- 뷰 템플릿 처리
- ModelAndView 에 값을 채워서 예외에 따른 새로운 오류 화면 뷰 렌더링
- API 응답 처리
- response.getWriter().println("hello"); 처럼
- HTTP 응답 바디에 직접 데이터를 넣어주는 것도 가능하다.
- 여기에 JSON 으로 응답하면 API 응답 처리를 할 수 있다.
8. GitHub : 210928 HandlerExceptionResolver
'인프런 > [인프런] 스프링 MVC 2' 카테고리의 다른 글
[API예외] Spring제공 ExceptionResolver (0) | 2021.09.29 |
---|---|
[API예외] HandlerExceptionResolver 활용 (0) | 2021.09.28 |
[API예외] SpringBoot 기본 오류 처리 (0) | 2021.09.28 |
[API예외] API 예외처리 (0) | 2021.09.28 |
[예외] SpringBoot - BasicErrorController (0) | 2021.09.27 |
Comments