2011-07-15 34 views
15

Tôi đang cố gắng viết thư viện truy cập dịch vụ web RESTful bằng API ứng dụng khách của Jersey. Dịch vụ yêu cầu một yêu cầu đăng nhập để đặt cookie, sau đó các yêu cầu tiếp theo phải có cookie được đặt thành công. Yêu cầu đăng nhập hoạt động như mong đợi và tôi có thể truy xuất cookie trong phản hồi từ thông tin đăng nhập, nhưng dường như không thể thêm cookie vào các yêu cầu tiếp theo. Bất cứ ai có thể nói những gì tôi có thể làm sai. Đây là mã tạo yêu cầu:Khách hàng Jersey: Thêm cookie vào yêu cầu

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); 

Trong khi yêu cầu không thành công, dịch vụ sẽ trả lời lỗi ứng dụng "Không có phiên". Dưới đây là những dấu vết log của chuỗi yêu cầu:

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] 

Tôi đang nghĩ đến các yêu cầu sau đây cần có cookie trong tiêu đề:

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> 

Bất kỳ hướng dẫn về vấn đề này được nhiều đánh giá cao.

Trả lời

24

Vấn đề là WebResource là không thay đổi - phương thức cookie() trả về WebResource.Builder. Vì vậy, làm như sau chỉ cần tạo một cá thể mới của WebResource.Builder mỗi khi bạn gọi cookie (và không sửa đổi WebResource ban đầu chút nào). Bạn bỏ qua những trường hợp Builder và vẫn thực hiện các yêu cầu trên WebResource gốc:

for (NewCookie c : CookieJar.Cookies) { 
    logger.debug("Setting cookie " + c.getName()); 
    wr.cookie(c); 
} 

bạn nên làm như sau thay vì:

WebResource.Builder builder = wr.getRequestBuilder(); 
for (NewCookie c : CookieJar.Cookies) { 
    builder = builder.cookie(c); 
} 

Sau đó, bạn có thể thực hiện yêu cầu bởi:

ClientResponse response = builder.queryParams(qs).get(ClientResponse.class); 

Ngoài ra, để tránh sao chép mã này trong tất cả các phương pháp tài nguyên của bạn, bạn có thể muốn xem xét viết một bộ lọc ứng dụng khách, mà sẽ làm điều đó cho bạn cho tất cả các yêu cầu của bạn. Ví dụ. mã sau sẽ đảm bảo các cookie được gửi từ máy chủ được đặt cho mỗi phản hồi:

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; 
    } 
}); 

LƯU Ý: Điều này sẽ chỉ hoạt động nếu bạn không chia sẻ các cá thể khách với nhiều chủ đề!

+1

lưu các thử nghiệm của tôi, nhờ –

+0

không hoạt động cho tôi ngay cả sau khi sửa chữa –

3

Có lẽ bạn cần phải phù hợp với cookie trong cuộc gọi WebResource đã hoạt động trước đó mà không có chúng. Sau đó, bạn có thể thấy mình phá vỡ dòng mã của bạn mà bạn có thể làm việc với phần xây dựng một cách thông qua. Để bao gồm các tập tin cookie, mã của bạn có thể đi từ:

clientResponse = webResource.queryParams(parameters).type(httpContentType).accept(httpAcceptType).post(ClientResponse.class, requestBody); 

tới:

builder = webResource.queryParams(parameters).type(httpContentType); 
if (cookieJar != null) 
{ 
    for (Cookie c : cookieJar) 
     builder = builder.cookie(c); 
} 
clientResponse = builder.accept(httpAcceptType).post(ClientResponse.class, requestBody); 
6

Tôi đã tìm thấy rằng một cách đơn giản hơn để đảm bảo các tập tin cookie được gửi trở lại là để sử dụng tích hợp client Apache HTTP của jersey- khách hàng. Nó được tìm thấy trong gói maven jersey-apache-client:

<dependency> 
    <groupId>com.sun.jersey.contribs</groupId> 
    <artifactId>jersey-apache-client</artifactId> 
    <version>1.13</version> 
    <type>jar</type> 
</dependency> 

Sau đó bạn có thể làm:

ApacheHttpClientConfig config = new DefaultApacheHttpClientConfig(); 
config.getProperties().put(ApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES, true); 
ApacheHttpClient client = ApacheHttpClient.create(config); 

Từ đó trở đi, chỉ cần tiếp tục sử dụng cùng một khách hàng trên yêu cầu và các tập tin cookie sẽ được thu thập và gửi lại máy chủ như mong đợi.

+0

có vẻ như cách tiếp cận này chỉ tương thích với Jersey v1 – harschware

Các vấn đề liên quan