Httpclient 4, ошибка 302. Как перенаправить?
Я хочу получить доступ к одному сайту, для которого сначала требуется аутентификация (tomcat server), а затем войти в систему с запросом POST и оставить этого пользователя для просмотра страниц сайта. Я использую Httpclient 4.0.1
Первая проверка подлинности работает отлично, но не вход в систему, который всегда жалуется на эту ошибку: "302 перемещено временно"
Я храню файлы cookie, и я сохраняю контекст, и все же ничего. На самом деле кажется, что вход в систему работает, потому что, если я пишу неверные параметры или пароль пользователя, я вижу страницу входа. Поэтому я думаю, что не работает автоматическое перенаправление.
Следуя моему коду, который всегда выдает исключение IOException, 302:
DefaultHttpClient httpclient = new DefaultHttpClient();
CookieStore cookieStore = new BasicCookieStore();
httpclient.getParams().setParameter(
ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
HttpContext context = new BasicHttpContext();
context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
//ResponseHandler<String> responseHandler = new BasicResponseHandler();
Credentials testsystemCreds = new UsernamePasswordCredentials(TESTSYSTEM_USER, TESTSYSTEM_PASS);
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
testsystemCreds);
HttpPost postRequest = new HttpPost(cms + "/login");
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("pUserId", user));
formparams.add(new BasicNameValuePair("pPassword", pass));
postRequest.setEntity(new UrlEncodedFormEntity(formparams, "UTF-8"));
HttpResponse response = httpclient.execute(postRequest, context);
System.out.println(response);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
throw new IOException(response.getStatusLine().toString());
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(
ExecutionContext.HTTP_REQUEST);
HttpHost currentHost = (HttpHost) context.getAttribute(
ExecutionContext.HTTP_TARGET_HOST);
String currentUrl = currentHost.toURI() + currentReq.getURI();
System.out.println(currentUrl);
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048) {
System.out.println(EntityUtils.toString(entity));
} else {
// Stream content out
}
}
Ответы
Ответ 1
Для версии 4.1:
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return isRedirect;
}
});
Ответ 2
В более поздних версиях HttpCLient (4.1+) вы можете просто сделать это:
DefaultHttpClient client = new DefaultHttpClient()
client.setRedirectStrategy(new LaxRedirectStrategy())
LaxRedirectStrategy автоматически перенаправляет запросы HEAD, GET и POST. Для более строгой реализации используйте DefaultRedirectStrategy.
Ответ 3
Для HttpClient 4.3.x:
HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
Ответ 4
Вам нужно реализовать специальный обработчик перенаправления, который укажет, что ответ на POST является перенаправлением. Это можно сделать путем переопределения метода isRedirectRequested(), как показано ниже.
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectHandler(new DefaultRedirectHandler() {
@Override
public boolean isRedirectRequested(HttpResponse response, HttpContext context) {
boolean isRedirect = super.isRedirectRequested(response, context);
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return isRedirect;
}
});
В более поздней версии HttpClient имя класса - DefaultRedirectStrategy, но подобное решение можно использовать там.
Ответ 5
httpclient.setRedirectHandler(new DefaultRedirectHandler());
См. HttpClient Javadoc
Ответ 6
Перенаправления не обрабатываются автоматически HttpClient 4.1 для других методов, кроме GET и PUT.
Ответ 7
Extend the DefaultRedirectStrategy class and override the methods.
@Override
protected URI createLocationURI(String arg0) throws ProtocolException {
// TODO Auto-generated method stub
return super.createLocationURI(arg0);
}
@Override
protected boolean isRedirectable(String arg0) {
// TODO Auto-generated method stub
return true;
}
@Override
public URI getLocationURI(HttpRequest arg0, HttpResponse arg1,
HttpContext arg2) throws ProtocolException {
// TODO Auto-generated method stub
return super.getLocationURI(arg0, arg1, arg2);
}
@Override
public HttpUriRequest getRedirect(HttpRequest request,
HttpResponse response, HttpContext context)
throws ProtocolException {
URI uri = getLocationURI(request, response, context);
String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else {
return new HttpPost(uri);
}
}
@Override
public boolean isRedirected(HttpRequest request, HttpResponse response,
HttpContext context) throws ProtocolException {
// TODO Auto-generated method stub
return super.isRedirected(request, response, context);
}
in this case isRedirectable method will always return true and getRedirect method will return post request in place of get request.