728x90
반응형
API 예외 처리
- 백엔드 개발자면 API 예외 처리를 가장 많이 다룰 것이다.
- 보통 JSON 형태로 200, 400, 500 대 상태코드로 응답을 주게 된다.
- 그럼 어떻게 JSON 으로 응답을 주는지 차근 차근 공부해 보면서 알아본다.
API 예외 처리 응답방식
- 스프링 부트는 BasicErrorController 가 제공하는 기본 정보들을 활용하여 API 를 생성해서 준다.
{
"timestamp": "2021-04-28T00:00:00.000+00:00", "status": 500,
"error": "Internal Server Error",
"exception": "java.lang.RuntimeException",
"trace": exception 추적 내용,
"message": "잘못된 사용자",
"path": "/api/members/ex"
HandlerExceptionResolver 예외 처리
- 예외가발생 해서 WAS 까지 가는 순간 상태 코드는 무조건 500 이다.
하지만 예외종류는 많고 400, 404등 다른 상태코드도 전달하고 싶다. - HanlerExceptionResolver 을 통해서 동작 방식을 변경 할 수 있다.
예외 발생 예제
- HandlerExceptionResolver 예외 처리를 적용하지 않으면 어떻게 되는지 보자
- 상태 코드는 500 이다 WAS 까지 도달 하면 500 이기 때문이다.
@GetMapping("/api/exception")
public MemberDto getMember(@PathVariable("id") String id) {
if (id.equals("ex")) {
throw new RuntimeException("잘못된 사용자");
}
}
상태코드
{
"status": 500,
"error": "Internal Server Error",
"exception": "java.lang.IllegalArgumentException",
"path": "/api/members/bad"
}
ExceptionResolver 동작 방식
1. 요청이 들어오면 preHandler 호출
2. Handler Adapter 호출
3. Controller 호출
- 여기서 예외 발생
4. 예외 전달
5. ExceptionResolver가 Exception 을 가로채어 해결시도를 한다.
6. 해결하면 알맞는 View 를 호출하고
7. afterCompletion 을 호출한다.
8. ExceptionResolver 가 예외를 해결 했기 때문에 200 응답으로 나간다.
HandlerExceptionResolver 구현해보기
- 파라미터를 보면 Object handler, Exception 이 있다.
- handler: 컨트롤러 정보
- Exception: 컨트롤러에서 발생한 예외 - 그리고 반환 타입이 중요하다.
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
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();
}
} catch (IOException e) {
log.error("resolver ex", e);
}
return null;
}
반환타입에 따른 처리
- ModelAndView 반환:
- 빈 모델인 경우: 뷰를 렌더링 하지 않고 정상흐름으로 반환
- 안에 정보가 있는경우: 뷰를 렌더링 한다. - NULL: 다음 ExceptionResolver 를 찾아 실행한다.
- 처리가 안되면 기존에 발생한 예외를 서블릿 밖으로 보낸다
ExceptionResolver 등록
- 단순히 구현한다고 동작하는게 아니라 아래와 같이 등록을 해줘야 한다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 익셉션 리솔버 등록
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add(new MyHandlerException());
}
}
ExceptionResolver 예제1
- accept 가 json 인경우는 json 형식으로 보내주고 그렇지 않으면
HTML 화면으로 이동 시킨다 - 여기서 중요한건 response.setStatus 이다
http status 를 지정해 주지 않으면 200 으로 나가기 때문에 여기서 변경을 해줘야 한다.
public class TestHandlerException implements HandlerExceptionResolver {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
if (ex instanceof TestException) {
String acceptHeader = request.getHeader("accept");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
if ("application/json".equals(acceptHeader)) {
Map<String,Object> errorResult = new HashMap<>();
errorResult.put("예외 종류", ex.getClass());
errorResult.put("예외메세지", ex.getMessage());
String result = null;
try {
result = objectMapper.writeValueAsString(errorResult);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().write(result);
return new ModelAndView();
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
new ModelAndView("/500.html");
}
}
return null;
}
}
참고:
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard
스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의
웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있
www.inflearn.com
728x90
반응형
'Spring > spring mvc 2 스터디' 카테고리의 다른 글
[Spring] API 예외 처리(ExceptionHandler) (0) | 2022.07.02 |
---|---|
[Spring] API 예외 처리(ExceptionResolver) (0) | 2022.07.02 |
[Spring] 예외 처리 이론 및 기초 (0) | 2022.06.25 |
[Spring] Filter Vs Interceptor (0) | 2022.06.01 |
[Spring] Interceptor (0) | 2022.06.01 |
댓글