Spring WebFilter переопределяет заголовок ExceptionHandler - PullRequest
0 голосов
/ 20 декабря 2018

Я использую как WebFilter, так и WebExceptionHandler.WebFilter должен добавлять новый заголовок, только если ExceptionHandler не установил его.Однако WebFilter добавляется в ServerWebExchange до того, как WebHttpHandler выполняет ExceptionHandler, поэтому он не может определить, был ли запущен ExceptionHandler.

@Component
@Order(-2)
class MyErrorWebExceptionHandler(g: MyErrorAttributes, applicationContext: ApplicationContext, serverCodecConfigurer: ServerCodecConfigurer)
    : AbstractErrorWebExceptionHandler(g, ResourceProperties(), applicationContext) {

    init {
        super.setMessageWriters(serverCodecConfigurer.writers)
        super.setMessageReaders(serverCodecConfigurer.readers)
    }

    @Override
    override fun getRoutingFunction(errorAttributes: ErrorAttributes): RouterFunction<ServerResponse> {
        return RouterFunctions.route(RequestPredicates.all(), HandlerFunction<ServerResponse> { renderErrorResponse(it) })
    }

    private fun renderErrorResponse(request: ServerRequest): Mono<ServerResponse> {

        val errorPropertiesMap = getErrorAttributes(request, false)

        return ServerResponse.status(HttpStatus.OK)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .headers { x ->
                        x.set(c_ApplicationStatus, errorPropertiesMap[c_ApplicationStatus].toString())
                      }.build()
}

@Component
class ServerResponseHeaderWebFilter : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        exchange.response.headers.set(c_ApplicationStatus, HttpStatus.OK.value().toString())
        return chain.filter(exchange)

    }
}

Ответы [ 2 ]

0 голосов
/ 17 января 2019

в конце концов я обнаружил, что заголовок, установленный в фильтре, можно увидеть в объекте request.exchange ().это должно быть удалено там для нового набора заголовка, чтобы заменить это.

private fun renderErrorResponse(request: ServerRequest): Mono<ServerResponse> {

        val errorPropertiesMap = getErrorAttributes(request, false)

        request.exchange().response.headers.remove(c_ApplicationStatus)
        return ServerResponse.status(HttpStatus.OK)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .headers { x -> x.set(c_ApplicationStatus, value) }
                .build()
}
0 голосов
/ 21 декабря 2018

В этом случае мы можем быстро смоделировать порядок выполнения с помощью чего-то вроде:

WebFilter
|- setting the application status header to OK
|- calling chain.filter
   |- finding the handler and calling it
   |- in case of an error, the exception handler is called
|- after chain.filter

Как только цепочка фильтров будет завершена с обменом, ответ будет зафиксирован и обработан, поэтому нет способаизмените заголовки ответа в этой точке.В этом примере кода обработчик исключений, если он будет выполнен, переопределит любой заголовок, установленный веб-фильтром.

Таким образом, технически ответ на ваш вопрос заключается в том, что нет способа изменить ответ, если цепочка обработчиков имеетпозаботился об этом.Это ожидаемое поведение Spring WebFlux по своему замыслу.

Но, похоже, нам нужно сделать шаг назад и поговорить о том, чего вы пытаетесь достичь.

Вы пытаетесь проверить, вызывается ли вообще ваш обработчик исключений при разработкеособенность?Вы пытаетесь адаптировать механизм обработки ошибок в Spring Boot таким образом, который сейчас невозможен?

Если вы хотите поговорить о том, чего вы пытаетесь достичь, задайте другой вопрос, чтобы SOпользователи могут извлечь пользу из этого вопроса.

...