기록하기

ExceptionHandlerFilter 적용(3) 본문

Server/Spring Boot

ExceptionHandlerFilter 적용(3)

jjungdev 2022. 7. 10. 15:40

이전 글에 이어서 마지막 flow 를 기록해보려고 한다.

 

1. Security Configuration 적용 및 flow 설계

2. Spring Security + JWT + Redis 설정 및 진행 과정

3. ExceptionHandlerFilter 설계

 

ExceptionHandlerFilter 설계

이번 글에서는 설계한 ExceptionHandlerFilter 코드를 공유하고, 어떻게 처리를 했는지 간단하게 설명하도록 하겠다.


ExceptionHandlerFilter

@Slf4j
@Component
@RequiredArgsConstructor
public class ExceptionHandlerFilter extends OncePerRequestFilter {

    private final ObjectMapper objectMapper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            filterChain.doFilter(request, response);
        } catch (JwtException e) {
            log.error("exception exception handler filter");
            log.error(e.getMessage());
            setErrorResponse(response, e);
        } catch (IllegalArgumentException e) {
            log.error("illegal argument exception handler filter");
            setErrorResponse(response, e);
        } catch (RuntimeException e) {
            log.error("runtime exception handler filter");
            setErrorResponse(response, e);
        }
    }

    public void setErrorResponse(HttpServletResponse response, Throwable ex) throws IOException {
        response.setStatus(ErrorCode.UNAUTHORIZED.getCode());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        objectMapper.writeValue(response.getWriter(), ResponseData.fail(ex.getMessage()));
    }
}

앞서 Exception 이 발생했을 경우 이 필터에서 처리가 된다.

이 곳에서 중요하게 생각한 부분은 오류 메세지가 화면단에도 전달이 되어야 한다는 부분이다.

따라서 ObjectMapper 를 사용하여 Response 를 전달한 것이고, ObjectMapper 의 경우에는 WebConfig 파일에서 Bean 으로 등록을 해주었기에 의존성 주입을 받을 수 있는 것이다. (물론 세부적으로 메세지를 나누려고 했으나 기획단계에서 추가적으로 논의가 되어야 하는 부분도 있어서 공통적으로 401 에러로 처리를 했다.)

따라서 인증 처리 및 로그인 필터 처리 과정 중에 Exception이 발생하게 되면 이 필터에서 처리가 되며 각 예외상황별 처리 방법은 각 프로젝트의 상황에 따라 설계하면 될 것이다.

(추가적으로 WebConfig 파일은 대략적으로 아래와 같이 설계가 되어있다.)
WebConfig

@Slf4j
@Configuration
public class WebConfig implements WebMvcConfigurer {

    ...

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return objectMapper;
    }
    
    ...
    
}