【问题标题】:Configure two cxf jaxrs clients to use the same session (cookies)配置两个 cxf jaxrs 客户端使用相同的会话(cookies)
【发布时间】:2012-10-15 16:37:45
【问题描述】:

我想使用 apache cxf 连接到带有 jaxrs 客户端的 REST 服务器。服务器有一个 url 来进行身份验证,还有一些其他的 url 来做实际的事情。登录后,服务器会创建一个会话并保持连接打开 30 分钟。我的问题是客户端不存储 cookie,我总是在服务器上获得一个新的(未经过身份验证的)会话。

我在我的 spring 应用程序上下文中配置了客户端。

<jaxrs:client id="loginResource" 
    serviceClass="com.mycompany.rest.resources.LoginResource" 
    address="${fsi.application.url}">
</jaxrs:client>
<jaxrs:client id="actionResource" 
    serviceClass="com.mycompany.rest.resources.ActionResource" 
    address="${fsi.application.url}">
</jaxrs:client>

如何将两个客户端配置为使用相同的会话或在客户端之间共享会话cookie?

【问题讨论】:

  • 带有会话的 REST 服务器??怎么可能?
  • 我们实现的是客户端而不是服务器。我们知道 REST 应该是无状态的,不使用会话,但遗憾的是我们无法更改服务器。

标签: session rest cookies cxf jax-rs


【解决方案1】:

我一直在努力解决同样的问题,我终于找到了解决方案。

1) 让客户端保留cookies。

WebClient.getConfig(proxy).getRequestContext().put(
        org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);

也许有一种方法可以通过配置与编程来完成上述操作。

2) 将 cookie 从一个客户端复制到另一个客户端。

public static void copyCookies(Object sourceProxy, Object targetProxy) {
    HTTPConduit sourceConduit = WebClient.getConfig(sourceProxy).getHttpConduit();
    HTTPConduit targetConduit = WebClient.getConfig(targetProxy).getHttpConduit();
    targetConduit.getCookies().putAll(sourceConduit.getCookies());
}

使用代理 A 进行身份验证后,我调用上述方法与代理 B 共享其 cookie,代理 B 完成实际工作。

【讨论】:

    【解决方案2】:

    我使用以下请求/响应过滤器在每个请求中传递会话 ID:

    ClientResponseFilter >> 用于从 session-cookie 中提取 session-id

    ClientRequestFilter >> 将 session-id 作为 cookie 头传递给每个请求


    private class SessionIdRequestFilter implements ClientRequestFilter, ClientResponseFilter {
        /** cookie header key */
        private static final String COOKIE_KEY = "Cookie"; //$NON-NLS-1$
    
        /** name of the session cookie */
        private String cookieName = "JSESSIONID";
    
        /** holds the session id from the cookie */
        private String sessionId;
    
        @Override
        public void filter(ClientRequestContext request) throws IOException {
            // append session cookie to request header
            if (!request.getHeaders().containsKey(COOKIE_KEY) && sessionId != null) {
                request.getHeaders().add(COOKIE_KEY, getCookieName() + "=" + sessionId); //$NON-NLS-1$
            }
        }
    
        @Override
        public void filter(ClientRequestContext request, ClientResponseContext response) throws IOException {
            // find sessionId only if not already set
            if (sessionId == null) {
                Map<String, NewCookie> cookies = response.getCookies();
                if (cookies != null && !cookies.isEmpty()) {
                    NewCookie cookie = cookies.get(getCookieName());
                    if (cookie != null) {
                        sessionId = cookie.getValue();
                    }
                }
            }
        }
    
        private String getCookieName() {
            return cookieName;
        }
    }
    

    要注册过滤器,请使用:

    RestClientBuilder.newBuilder().baseUri(apiUri).register(new SessionIdRequestFilter());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-18
      相关资源
      最近更新 更多