Exception Handler 를 이용해서
컨트롤러가 아닌 외부에서 Exception을 처리하는 경우
response 데이터를 보낼 수 없이 자동으로 오류데이터가 전송되었다!
내가 원하는 response 값을 커스터마이징해서 보내고 싶은 경우
한참을 고안해보았고 검색도 많이 해봤는데 내가 원하는 결과는 나오지 않았다.
우선, 방법은 @RestControllerAdvice를 사용하거나 아래 방법을 사용!
컨트롤러에 error response를 처리해줄 메소드 선언
HttpServletResponse 를 이용해 json 형태로 보내는 로직
public void error(ApiDTO apiDTO) throws IOException {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
ObjectMapper mapper = new ObjectMapper();
response.getWriter().write(mapper.writeValueAsString(apiDTO));
}
Exception을 처리하는 곳의 메소드 return 값이 void인지 확인하기!!
void가 아닌 경우 다시 해당 메소드로 돌아와 repsonse값이 초기화되는 것 같다
정상적으로 작동하길 원하는 경우 해당 메소드의 return값을 void로 변환해줘야 한다
@ExceptionHandler({NullPointerException.class})
public void nullEx(HttpServletRequest request) throws IOException {
...
controller.error(apiDTO);
}
호출된 HTTP API 메소드에 Exception을 처리하는 catch문이 있는지 확인하기!
상세한 Exception의 경우 Exception Handler에 정의하지 않았던 Exception만 정의해야하며,
아예 통으로 Exception을 잡아놓은 경우 해당 catch문으로 이동할 수 있으니 지우기!
// 변경 전
@PostMapping("/read")
@ResponseBody
@AccessRole(role = RoleFinal.USER)
public ApiDTO read(@RequestBody ReadRequest request){
...
catch (Exception e){
...
}
}
//변경 후
@PostMapping("/read")
@ResponseBody
@AccessRole(role = RoleFinal.USER)
public ApiDTO read(@RequestBody ReadRequest request){
...
}