Httpclient 4,错误 302。如何重定向?
Posted
技术标签:
【中文标题】Httpclient 4,错误 302。如何重定向?【英文标题】:Httpclient 4, error 302. How to redirect? 【发布时间】:2011-04-09 04:38:05 【问题描述】:我想访问一个首先需要(tomcat 服务器)身份验证的站点,然后使用 POST 请求登录并让该用户查看该站点的页面。我使用 Httpclient 4.0.1
第一次身份验证工作正常,但登录时总是抱怨此错误:“302 Moved Temporarily”
我保留 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
【问题讨论】:
“第一次验证工作正常,但登录时总是抱怨这个错误”。 302 重定向不是服务器的投诉;这表明用户代理现在必须进入响应中指示的新页面。 我是这么想的,但是怎么样?然后我尝试了一个 GET 请求,但无济于事。 【参考方案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;
);
【讨论】:
我不认为这应该返回 false,我认为它应该返回 isRedirect。当我进行此更改时,此代码有效。谢谢! 它可以工作,但在大多数情况下,HTTP 服务器将 POST 请求更改为 GET 请求。如果目标(例如 servlet)只接受 POST 请求,则自动重定向失败,状态码为 405(不允许使用方法)。有什么建议吗? 嘿,我试过这个,虽然这在一个 java 项目中运行良好,但我在 android 中尝试过,我得到了类似于这里描述的东西 ***.com/questions/9255150/… 你有什么建议?我已经导入了 httpclient 4.2 库【参考方案2】:对于 HttpClient 4.3.x :
HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
【讨论】:
【参考方案3】:在更高版本的 HttpCLient (4.1+) 中,您可以这样做:
DefaultHttpClient client = new DefaultHttpClient()
client.setRedirectStrategy(new LaxRedirectStrategy())
LaxRedirectStrategy 将自动重定向 HEAD、GET 和 POST 请求。如需更严格的实现,请使用 DefaultRedirectStrategy。
【讨论】:
这个是4.1没有引入的,是4.2引入的。【参考方案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,但可以使用类似的解决方案。
【讨论】:
返回应该是 isRedirect 而不是 false【参考方案5】:httpclient.setRedirectHandler(new DefaultRedirectHandler());
见HttpClientJavadoc
【讨论】:
【参考方案6】:对于 GET 和 PUT 之外的其他方法,HttpClient 4.1 不会自动处理重定向。
【讨论】:
【参考方案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.
【讨论】:
以上是关于Httpclient 4,错误 302。如何重定向?的主要内容,如果未能解决你的问题,请参考以下文章