Spring - 如果服务返回409 HTTP代码,则重试请求

Dav*_*ave 10 java spring cxf-client

我有一个Spring + CXF应用程序,它使用传输API:在另一台服务器上运行的传输RPC.

根据Transmission文档,您需要发送在第一个请求时生成的令牌.然后,服务器使用409 http代码以及包含令牌的标头进行响应.此令牌应在所有后续调用中发送:

2.3.1.CSRF保护大多数传输RPC服务器都需要与请求一起发送X-Transmission-Session-Id标头,以防止CSRF攻击.当您的请求具有错误的ID时 - 例如当您发送第一个请求时,或者当服务器使CSRF令牌过期时 - 传输RPC服务器将返回HTTP 409错误,其中包含正确的X-Transmission-Session-Id自己的标题.因此,处理409响应的正确方法是更新X-Transmission-Session-Id并重新发送先前的请求.

我正在寻找使用CXF过滤器或拦截器的解决方案,它基本上将处理409响应并重试添加令牌头的初始请求.我认为客户端可以保留此令牌并在将来的呼叫中发送它.

我对cxf不太熟悉,所以我想知道这是否可以实现以及如何实现.任何提示都会有所帮助.

谢谢!

Bon*_*ond 2

这里可以使用spring-retry,它现在是一个独立的项目,不再是 spring-batch 的一部分。

如此处所述,重试回调将有助于使用令牌标头更新另一个调用。

在这种情况下,伪代码/逻辑如下所示

RetryTemplate template = new RetryTemplate();
Foo foo = template.execute(new RetryCallback<Foo>() {
    public Foo doWithRetry(RetryContext context) {
        /* 
         * 1. Check if RetryContext contains the token via hasAttribute. If available set the header else proceed
         * 2. Call the transmission API 
         * 3.a. If API responds with 409, read the token 
         *    3.a.1. Store the token in RetryContext via setAttribute method
         *    3.a.2. Throw a custom exception so that retry kicks in
         * 3.b. If API response is non 409 handle according to business logic
         * 4. Return result
         */
    }
});
Run Code Online (Sandbox Code Playgroud)

确保配置RetryTemplate合理的重试和退避策略,以避免任何资源争用/意外。

如有任何疑问/障碍,请在评论中告知。

注意RetryContext的实现RetryContextSupport具有从 Spring 核心继承的hasAttribute&方法setAttributeAttributeAccessor