Httpclient 4,错误302.如何redirect?

我想要访问一个首先需要(tomcat服务器)validation的站点,然后使用POST请求login,并让该用户查看该站点的页面。 我使用Httpclient 4.0.1

第一个身份validation正常工作,但不是总是抱怨这个错误的login:“302 Moved Temporarily”

我保持cookies&我保持一个上下文,但什么也没有。 实际上,这个login看起来很有效,因为如果我写了不正确的参数或用户||密码,我就看到了login页面。 所以我猜测什么是不工作的自动redirect。

我的代码,总是抛出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 } } 

对于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; } }); 

在更高版本的HttpCLient(4.1+)中,你可以这样做:

 DefaultHttpClient client = new DefaultHttpClient() client.setRedirectStrategy(new LaxRedirectStrategy()) 

LaxRedirectStrategy将自动redirectHEAD,GET和POST请求。 对于更严格的实现,请使用DefaultRedirectStrategy。

对于HttpClient 4.3.x:

 HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build(); 

您必须实现自定义redirect处理程序,该处理程序将指示对POST的响应是redirect。 这可以通过覆盖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,但是可以使用类似的解决scheme。

 httpclient.setRedirectHandler(new DefaultRedirectHandler()); 

请参阅HttpClient Javadoc

HttpClient 4.1除了GET和PUT以外的其他方法不会自动处理redirect。

 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.