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
- 백준
- http
- db
- Spring Boot
- Proxy
- Servlet
- java
- Android
- springdatajpa
- 자바
- 알고리즘
- jpa
- 스프링 핵심 기능
- Thymeleaf
- JPQL
- kotlin
- 그리디
- transaction
- QueryDSL
- Greedy
- spring
- 스프링
- 김영한
- JDBC
- 스프링 핵심 원리
- pointcut
- 인프런
- Exception
- AOP
- SpringBoot
Archives
- Today
- Total
개발자되기 프로젝트
[API예외] HandlerExceptionResolver 활용 본문
1.예외를 ExceptionResolver에서 마무리하기
- 예외가 발생하면 WAS까지 예외가 던져지고, WAS에서 오류 페이지 정보를 찾아서
- 다시 /error 를 호출하는 과정은 생각해보면 너무 복잡하다.
- ExceptionResolver 를 활용하면 예외가 발생했을 때 이런 복잡한 과정 없이
- ExceptionResolver에서 문제를 깔끔하게 해결- > BasicErrorController호출하는 등의 절차가 없음.
2. UserException
- 임의의 예외를 만듦
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);
}
}
3. ExceptionResolver
- ExceptionResolver에서 Exception처리를 해버리자.
- response객체세 상태 코드, contentType, Encoding, messageBody에 넣을 내용을 세팅해준다.
- 이 때 Map타입의 에러 내용을 String으로 변환하기 위해 ObjectMapper 사용
- 모든 세팅을 마친 후 빈 ModelAndView를 반환하여 WAS에 정상 응답을 내려주자.
- WAS입장에서는 Exception이 아닌 ModelAndView가 반환되었기 때문에 정상 응답으로 처리 할 것.
@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);
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", ex);
}
return null;
}
}
4. ExceptionResolver 등록
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add(new MyHandlerExceptionResolver());
resolvers.add(new UserHandlerExceptionResolver());
}
}
5. 실행.
- Accept : application/json
6. 정리
- ExceptionResolver 를 사용하면
- 컨트롤러에서 예외가 발생해도 ExceptionResolver 에서 예외를 처리해버린다.
- 즉 예외가 발생해도 서블릿 컨테이너까지 예외가 전달되지 않고, \
- 스프링 MVC에서 예외 처리가 끝남!
- 결과적으로 WAS 입장에서는 정상 처리가 된 것이다.
- 이렇게 예외를 이곳에서 모두 처리할 수 있다는 것이 핵심이다.
- 서블릿 컨테이너까지 예외가 올라가면 복잡하고 지저분하게 추가 프로세스가 실행된다.
- /error가 호출되어 BasicErrorController호출되고 accept에 맞는 method호출되고 등등
- 반면에 ExceptionResolver 를 사용하면 예외처리가 상당히 깔끔
- ExceptionResolver에서 예외처리가 끝나고 이전 처럼 다시 BasicController를 호출하지 않음.
- ExceptionResolver에서 응답할 data를 넣어두지 않는 경우, BasicErrorHandler에서 대응해야.
- ExceptionResolver에서 응답할 data를 세팅하는 경우, BasicErrorHandler가 호출될 필요가 없음.
- 그런데 직접 ExceptionResolver 를 구현하려고 하니 상당히 복잡하다.
7. GitHub : 210928 HandlerExceptionResolver활용
'인프런 > [인프런] 스프링 MVC 2' 카테고리의 다른 글
[API예외] Spring제공 ExceptionResolver2 (0) | 2021.10.01 |
---|---|
[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 |
Comments