Back End/Spring Boot

[Spring] Filter 단에서 발생하는 예외처리하기

DevPing9_ 2023. 5. 8. 17:34

AccessDeniedHandler, AuthenticationEntryPoint 등 뭔가 제한적인 예외처리가 아닌 전역적인 예외처리를 하고 싶었다.

 

프레임워크에서 제공해주는 예외처리법이 있지 않을까 싶어 최대한 예외처리 필터를 끼워넣는 일은 지양하고 싶었지만 시간에 쫒겨 타협을 해버렸다.

 

근데 막상 작성해보니까 괜찮은 것 같다. 

 

존재하는지는 모르겠지만 러닝커브가 있는 프레임워크가 제공해주는 예외처리법을 학습하지 않아도 필터 동작에 대한 개념만 있다면

누구든 아래의 코드를 이해할 수 있을테니까 말이다. 

 

더불어 하나의 필터에서 스프링 컨텍스트 외부의 예외를 처리할테니 유지보수 비용도 크지 않아보인다.

 

예외처리 필터

CommonException 을 상속 받은 모든 Exception 은 모두 예쁘게 예외처리 된다. (행복)

class ExceptionHandlingFilter(
    private val objectMapper: ObjectMapper
) : Filter {

    @Throws(IOException::class, ServletException::class)
    override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
        val res = response as HttpServletResponse
        val req = request as HttpServletRequest

        try {
            chain.doFilter(req, res)
        } catch (e: CommonException) {
            res.contentType = MediaType.APPLICATION_JSON_VALUE
            res.status = e.code
            res.characterEncoding = Charsets.UTF_8.toString()

            val writer = res.writer
            writer.println(objectMapper.writeValueAsString(CommonResponse<CommonException>(e)))
            writer.flush()
            writer.close()
        }

    }
}

 

Common Exception

open class CommonException(
    open val code: Int = HttpStatus.INTERNAL_SERVER_ERROR.value(),
    override val message: String = HttpStatus.INTERNAL_SERVER_ERROR.reasonPhrase,
    override val cause: Throwable? = null
) : Exception(message, cause)

 

Common Response

data class CommonResponse<T>(
    val code: Int = HttpStatus.OK.value(),
    val message: String = HttpStatus.OK.reasonPhrase,
    val data: T? = null
) {
    constructor(exception: CommonException) : this(exception.code, exception.message)
    constructor(exception: CommonException, data: T?) : this(exception.code, exception.message, data)
}

 

728x90