HttpClient 301问题
问题
项目中使用到了apache的HttpClient 4.5版本来进行http操作。
最近在开发时和其他服务端使用post进行对接,有些接口报错,报错如下:
responseResult : HttpResponseProxy{HTTP/1.1 301 Moved Permanently
鉴于和运维沟通麻烦,修改域名不方便等问题,决定在自己这边做一下兼容,即返回301后自动请求新的url。
解决方案
自定义一个重定向策略,对返回值301进行处理
HttpClientBuilder.create().setRedirectStrategy(new CustomLaxRedirectStrategy()).build();
static class CustomLaxRedirectStrategy extends LaxRedirectStrategy {
@Override
public HttpUriRequest getRedirect(
final HttpRequest request,
final HttpResponse response,
final HttpContext context) throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
//针对post请求301重定向问题
if (status == HttpStatus.SC_TEMPORARY_REDIRECT || status == HttpStatus.SC_MOVED_PERMANENTLY) {
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
}
过程
当遇到问题,最简单的就是百度。发现都是推荐使用LaxRedirectStrategy策略来解决。于是,我就改了下:HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
然后重新向问题接口发起请求。但是返回依然是301。
于是,我对execute进行断点,执行顺序如下:
在这里该方法会判断是否进行重定向以及以何种方式进行重定向。
public HttpUriRequest getRedirect(
final HttpRequest request,
final HttpResponse response,
final HttpContext context) throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
//由于不是head,也不是get,是post方法,因此进入了这里,但这里只对307进行了处理,其他都返回get请求
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
于是我自定义了重定向策略,继承自LaxRedirectStrategy,当再次请求时,就进入了自定义的getRedirect方法。此时判断status,由于是301,于是复制请求,并进行重定向。
if (status == HttpStatus.SC_TEMPORARY_REDIRECT || status == HttpStatus.SC_MOVED_PERMANENTLY) {
return RequestBuilder.copy(request).setUri(uri).build();
}