Многие службы REST будут использовать куки как часть схемы аутентификации / авторизации. Это проблема, потому что по умолчанию старый клиент Джерси будет использовать singleton CookieHandler.getDefault, который в большинстве случаев будет нулевым, а если нет, то вряд ли будет работать в многопоточной серверной среде. (Это потому, что в фоновом режиме клиент Джерси по умолчанию будет использовать URL.openConnection).
Теперь вы можете обойти это, используя адаптер Apache HTTP Client для Джерси; но это не всегда доступно. Поэтому, если вы хотите использовать клиент Jersey с файлами cookie в серверной среде, вам нужно немного подумать, чтобы убедиться, что вы используете свой собственный файл cookie.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
final CookieHandler ch = new CookieManager(); Client client = new Client(new URLConnectionClientHandler( new HttpURLConnectionFactory() { @Override public HttpURLConnection getHttpURLConnection(URL uRL) throws IOException { HttpURLConnection connect = (HttpURLConnection) uRL.openConnection(); try { Field cookieField = connect.getClass().getDeclaredField("cookieHandler"); cookieField.setAccessible(true); MethodHandle mh = MethodHandles.lookup().unreflectSetter(cookieField); mh.bindTo(connect).invoke(ch); } catch (Throwable e) { e.printStackTrace(); } return connect; } })); |
Это будет работать только в том случае, если ваша среда использует внутреннюю реализацию sun.net.www.protocol.http.HttpURLConnection которая поставляется с JDK. Похоже, это относится к современным версиям WLS.
Для JAX-RS 2.0 вы можете сделать аналогичное изменение, используя класс ClientConfig для Jersey 2.x и HttpUrlConnectorProvider .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
final CookieHandler ch = new CookieManager(); Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new HttpUrlConnectorProvider().connectionFactory(new HttpUrlConnectorProvider.ConnectionFactory() { @Override public HttpURLConnection getConnection(URL uRL) throws IOException { HttpURLConnection connect = (HttpURLConnection) uRL.openConnection(); try { Field cookieField = connect.getClass().getDeclaredField("cookieHandler"); cookieField.setAccessible(true); MethodHandle mh = MethodHandles.lookup().unreflectSetter(cookieField); mh.bindTo(connect).invoke(ch); } catch (Throwable e) { e.printStackTrace(); } return connect; } }))); |
Обновление от 11 февраля 2015: в некоторых случаях, в частности, с использованием https, я видел HttpURLConnection, заключенный в другой класс, чтобы обойти это, просто используйте отражение для доступа к значению поля делегата. Я обновил примеры кода, чтобы отразить эту проблему.
| Ссылка: | Работа с cookie-файлами для каждого клиента с Джерси от нашего партнера JCG |