Клиентская библиотека Google HTTP для Java выдает HttpResponseException: 301 перемещено навсегда
У меня проблема с клиентской библиотекой Google HTTP для Java (1.22.0). Это мой код
String url = "http://gazetapraca.pl/ogl/2502758";
GenericUrl genericUrl = new GenericUrl(url);
ApacheHttpTransport apacheHttpTransport = new ApacheHttpTransport();
HttpRequest httpRequest = apacheHttpTransport.createRequestFactory().buildGetRequest(genericUrl);
httpRequest.setFollowRedirects(true);
HttpResponse httpResponse = httpRequest.execute();
и httpRequest.execute() выбрасывает
com.google.api.client.http.HttpResponseException: 301 Moved Permanently
Ниже следует из Wireshark
GET /ogl/2502758 HTTP/1.1
Accept-Encoding: gzip
User-Agent: Google-HTTP-Java-Client/1.22.0 (gzip)
Host: gazetapraca.pl
Connection: Keep-Alive
HTTP/1.1 301 Moved Permanently
Date: Sat, 26 Nov 2016 22:15:52 GMT
Server: Apache
Location: /ogl/2502758/pakowacz+-+mile+widziane+panie
Content-Length: 0
Set-Cookie: JSESSIONID_JOBS=2f1TffY6JYcb6zvBSrQ72fds7rfdsSnHM3sefw6D31Lfr434bnkDmdLQJLvLFZ6zkYBF!-12116034235597; path=/; HttpOnly
Content-Language: pl
P3P: CP="NOI DSP COR NID PSAo OUR IND"
Vary: User-Agent
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
GET /ogl/2502758/pakowacz%20-%20mile%20widziane%20panie HTTP/1.1
Accept-Encoding: gzip
User-Agent: Google-HTTP-Java-Client/1.22.0 (gzip)
Host: gazetapraca.pl
Connection: Keep-Alive
Cookie: JSESSIONID_JOBS=2f1TffY6JYcb6zvBSrQ72fds7rfdsSnHM3sefw6D31Lfr434bnkDmdLQJLvLFZ6zkYBF!-12116034235597
HTTP/1.1 301 Moved Permanently
Date: Sat, 26 Nov 2016 22:15:52 GMT
Server: Apache
Location: /ogl/2502758/pakowacz+-+mile+widziane+panie
Content-Length: 0
Content-Language: pl
P3P: CP="NOI DSP COR NID PSAo OUR IND"
Vary: User-Agent
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
и повторить несколько раз. Может быть, проблема с URL, потому что location
является /ogl/2502758/pakowacz+-+mile+widziane+panie
и следующий метод запроса get is /ogl/2502758/pakowacz%20-%20mile%20widziane%20panie
, В других программах и библиотеках все работает (браузер Google Chrome, почтальон - дополнение к Chrome, JSOUP - библиотека Java).
У кого-нибудь есть идеи, как решить проблему?
1 ответ
Это не вина вашей библиотеки.
Чтобы понять, почему возникает эта проблема, мы должны сначала понять сообщение об ошибке, связанное с вашей проблемой:
com.google.api.client.http.HttpResponseException: 301 Moved Permanently
Итак, что это значит? Ну, а последняя часть сообщения об ошибке в описании гласит "301 перемещен навсегда". То, на что это ссылается, является кодом статуса HTTP. Код состояния HTTP указывает, каков результат конкретного запроса. В этом случае код состояния был 301, что в соответствии с протоколом RFC означает:
Запрошенному ресурсу был назначен новый постоянный URI, и любые будущие ссылки на этот ресурс ДОЛЖНЫ использовать один из возвращенных URI.
Таким образом, это означает, что используемый вами URL больше не действителен, и что вы должны использовать новый URL, предоставленный вам Location
заголовок ответа. Теперь кажется, что используемая вами библиотека достаточно умна, чтобы обнаружить это, и инициализирует новый запрос к новому URL. Это прекрасно, и все, но ваша библиотека, которую вы используете, неправильно экранирует URL, предоставленный Location
заголовок, и использовать его для нового запроса (поворот /ogl/2502758/pakowacz+-+mile+widziane+panie
в /ogl/2502758/pakowacz%20-%20mile%20widziane%20panie
), и сервер, получающий этот запрос, распознает, что эти пути не совпадают (даже если они должны быть. Таким образом, сервер отправляет другой ответ 301, сообщая клиенту (в данном случае, библиотеке) об использовании неэкранированного URL-адреса вместо сбежавшего, хотя они должны быть одинаковыми.
Теперь, почему ваша библиотека делает это? Оказывается, что согласно спецификации RFC символ "+" зарезервирован для URI. Это означает, что этот символ вместе с другими символами предназначен только для использования в URI по назначению. Следовательно, не является стандартным включение символа "+" в URI, если только он не используется для очень конкретной цели, что, по-видимому, не соответствует действительности.
Таким образом, все это означает, что вы не можете винить библиотеку за эту ошибку, вы можете обвинять только людей, которые разработали этот сайт.
Причина, по которой это работает в вашем браузере и других местах, заключается в том, что эти клиенты, похоже, не экранируют запрошенный для вас URL-адрес перед отправкой его на сервер.