Jersey Client: Adding Cookies to Request(Jersey 客户端:向请求添加 Cookie)
问题描述
我正在尝试编写一个使用 Jersey 客户端 API 访问 RESTful Web 服务的库.该服务需要一个设置 cookie 的登录请求,然后后续请求必须设置该 cookie 才能成功.登录请求按预期工作,我能够在登录响应中检索 cookie,但似乎无法在后续请求中重新添加 cookie.谁能告诉我可能做错了什么.这是发出请求的代码:
I am trying to write a library that accesses a RESTful web service using the Jersey Client API. The service requires a login request that sets a cookie, then subsequent requests must have that cookie set to succeed. The login request works as expected, and I am able to retrieve the cookie in the response from the login, but cannot seem to add the cookie back in subsequent requests. Can anyone tell what I might be doing wrong. Here is the code that makes the request:
MultivaluedMap<String,String> qs = new MultivaluedMapImpl();
qs.add( "xml", this.toXmlString() );
WebResource wr = client.resource( Constants.ServiceURL );
if ( CookieJar.Cookies != null )
{
for ( NewCookie c : CookieJar.Cookies )
{
logger.debug( "Setting cookie " + c.getName() );
wr.cookie( c );
}
}
ClientResponse response = wr.queryParams( qs ).get( ClientResponse.class );
虽然请求没有失败,但服务会响应应用程序错误No Session".这是请求序列的日志跟踪:
While the request doesn't fail, the service responds with the application error "No Session". Here is the log trace of the request sequence:
Jul 15, 2011 5:20:33 PM com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client out-bound request
1 > GET https://www.company.com/TrackerXMLInterface.asp?xml=%3Cxml%3E%3CTRANTYPE%3ELOGIN%3C/TRANTYPE%3E%3CTRANPARMS%3E%3CLOGINID%3Emylogin%3C/LOGINID%3E%3CPASSPHRASE%3EBa1b2c3%3C/PASSPHRASE%3E%3C/TRANPARMS%3E%3C/xml%3E
Jul 15, 2011 5:20:35 PM com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client in-bound response
1 < 200
1 < Date: Fri, 15 Jul 2011 22:20:35 GMT
1 < Content-Length: 150
1 < Set-Cookie: ASPSESSIONIDSUBSBSRR=GBGOKGJDAAHCNDDHPBFICFIH; secure; path=/
1 < Content-Type: text/html
1 < Server: Microsoft-IIS/7.0
1 < X-Powered-By: ASP.NET
1 < Cache-Control: private
1 <
<XML><TRANRESULTS><TRANRETURNCODE>L00</TRANRETURNCODE><TRANRETURNMSG>Valid Login </TRANRETURNMSG><TRANDETAIL></TRANDETAIL></TRANRESULTS></XML>
[continued below]
我认为以下请求的标头中应该包含 cookie:
I'm thinking the following request should have the cookies in the header:
Jul 15, 2011 5:20:35 PM com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client out-bound request
1 > GET https://www.company.com/TrackerXMLInterface.asp?xml=%3Cxml%3E%3CTRANTYPE%3ESSNLAST%3C/TRANTYPE%3E%3CTRANPARMS%3E%3CSSN%3E123456789%3C/SSN%3E%3CLASTNAME%3ESchmoe%3C/LASTNAME%3E%3C/TRANPARMS%3E%3C/xml%3E
Jul 15, 2011 5:20:35 PM com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client in-bound response
1 < 200
1 < Date: Fri, 15 Jul 2011 22:20:35 GMT
1 < Content-Length: 150
1 < Set-Cookie: ASPSESSIONIDSUBSBSRR=HBGOKGJDIAPBBEIGLOILDJDN; secure; path=/
1 < Content-Type: text/html
1 < Server: Microsoft-IIS/7.0
1 < X-Powered-By: ASP.NET
1 < Cache-Control: private
1 <
<XML><TRANRESULTS><TRANRETURNCODE>R04</TRANRETURNCODE><TRANRETURNMSG>No Session </TRANRETURNMSG><TRANDETAIL></TRANDETAIL></TRANRESULTS></XML>
非常感谢任何有关这方面的指导.
Any guidance on this is much appreciated.
推荐答案
问题是 WebResource 是不可变的 - cookie() 方法返回 WebResource.Builder.因此,执行以下操作只会在您每次调用 cookie 时创建一个新的 WebResource.Builder 实例(并且根本不会修改原始 WebResource).您忽略那些 Builder 实例并仍然在原始 WebResource 上执行请求:
The problem is WebResource is immutable - the cookie() method returns WebResource.Builder. So, doing the following just creates a new instance of WebResource.Builder every time you call cookie (and does not modify the original WebResource at all). You ignore those Builder instances and still perform the request on the original WebResource:
for ( NewCookie c : CookieJar.Cookies ) {
logger.debug( "Setting cookie " + c.getName() );
wr.cookie( c );
}
您应该改为:
WebResource.Builder builder = wr.getRequestBuilder();
for (NewCookie c : CookieJar.Cookies) {
builder = builder.cookie(c);
}
然后您可以通过以下方式提出请求:
Then you can make the request by:
ClientResponse response = builder.queryParams(qs).get(ClientResponse.class);
此外,为避免在所有资源方法中重复此代码,您可能需要考虑编写一个客户端过滤器,它会为您处理所有请求.例如.以下代码将确保为每个响应设置从服务器发送的 cookie:
Also, to avoid duplicating this code in all your resource methods, you may want to consider writing a client filter, which will do it for you for all your requests. E.g. the following code would ensure cookies sent from the server get set for each response:
client.addFilter(new ClientFilter() {
private ArrayList<Object> cookies;
@Override
public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
if (cookies != null) {
request.getHeaders().put("Cookie", cookies);
}
ClientResponse response = getNext().handle(request);
if (response.getCookies() != null) {
if (cookies == null) {
cookies = new ArrayList<Object>();
}
// simple addAll just for illustration (should probably check for duplicates and expired cookies)
cookies.addAll(response.getCookies());
}
return response;
}
});
注意:这仅在您不与多个线程共享客户端实例时才有效!
NOTE: This will only work if you don't share client instances with multiple threads!
这篇关于Jersey 客户端:向请求添加 Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Jersey 客户端:向请求添加 Cookie


- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01