这周调用一个下载文件的API遇到一个问题。这个API返回的是CDN的signed URL,客户端需要根据Set-Cookie中指定的cookies值,将cookie设置到下载的GET请求中。项目中使用的是Jersey,而jersey中的Client提供了client.cookie(Cookie c)和client.cookie(String name, String value)等方法来设置cookies。我使用这两种方法都失败了,服务器返回403, 说需要的cookie没有设置。后来干脆"手写cookies"并使用 request.header("Cookie", "blah=haha")的方式代替,调用就成功了。
问题虽然解决了,根本原因还是要去挖一挖滴。猜测是jersey生成的请求有什么妖孽。。。
下面的示例代码使用Jersey的 logging feature。它简单好用,能够将请求和应答的内容都打印出来。
Logger logger = Logger.getLogger(getClass().getName());
Feature loggingFeature = new LoggingFeature(logger, Level.INFO, null, null);
Client restClient = ClientBuilder.newClient().register(loggingFeature);
URI uri = URI.create("https://httpbin.org/get");
List<Cookie> cookies = new ArrayList<>();
NewCookie c1 = new NewCookie("name", "value", "/path", "mysite.greatcompany.com", "nocomment",100000, true);
cookies.add(c1);
Response resp = new MdRequest(restClient, uri)
.cookies(cookies)
.header(HttpHeaders.AUTHORIZATION, "Bearer fake_token")
.get();
得到的请求消息如下:
Aug 11, 2021 11:31:12 AM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 1 * Sending client request on thread main
1 > GET https://httpbin.org/get
1 > Authorization: Bearer fake_token
1 > Cookie: $Version=1;name=value
问题出在Cookie这个头里边的$Version=1。因为不知道服务器端的设置,极大可能是服务器不支持cookie版本1的这个语法。