Java Httpclient 4, error 302. 如何重定向?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3658721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Httpclient 4, error 302. How to redirect?
提问by juanmirocks
I want to access one site that first requires an (tomcat server) authentication and then log in with a POST request and keep that user to see the site's pages. I use Httpclient 4.0.1
我想访问一个首先需要(tomcat 服务器)身份验证的站点,然后使用 POST 请求登录并让该用户查看该站点的页面。我使用 Httpclient 4.0.1
The first authentication works fine but not the logon that always complains about this error: "302 Moved Temporarily"
第一次身份验证工作正常,但登录时总是抱怨此错误:“302 临时移动”
I keep cookies & I keep a context and yet nothing. Actually, it seems that the logon works, because if I write incorrect parameters or user||password, I see the login page. So I guess what doesn't work is the automatic redirection.
我保留 cookie 并保留上下文,但什么也没有。实际上,登录似乎是有效的,因为如果我写了错误的参数或用户||密码,我会看到登录页面。所以我想不起作用的是自动重定向。
Following my code, which always throws the IOException, 302:
按照我的代码,它总是抛出 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
}
}
采纳答案by fvisticot
For 4.1 version:
对于 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;
}
});
回答by Vivien Barousse
回答by Shashikant Kore
You have to implement custom redirection handler that will indicate that response to POST is a redirection. This can be done by overriding isRedirectRequested() method as shown below.
您必须实现自定义重定向处理程序,以指示对 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;
}
});
In later version of HttpClient, the class name is DefaultRedirectStrategy, but similar solution can be used there.
在 HttpClient 的更高版本中,类名是 DefaultRedirectStrategy,但可以使用类似的解决方案。
回答by Alin
Redirects are not handled automatically by HttpClient 4.1 for other methods than GET and PUT.
对于 GET 和 PUT 以外的其他方法,HttpClient 4.1 不会自动处理重定向。
回答by paradoxbomb
In later versions of HttpCLient (4.1+), you can just do this:
在更高版本的 HttpCLient (4.1+) 中,您可以这样做:
DefaultHttpClient client = new DefaultHttpClient()
client.setRedirectStrategy(new LaxRedirectStrategy())
LaxRedirectStrategy will automatically redirect HEAD, GET, and POST requests. For a stricter implementation, use DefaultRedirectStrategy.
LaxRedirectStrategy 将自动重定向 HEAD、GET 和 POST 请求。对于更严格的实现,请使用 DefaultRedirectStrategy。
回答by nat
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.
回答by Alix Lourme
For HttpClient 4.3.x :
对于 HttpClient 4.3.x :
HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();