最近在开发WebService接口的时候,碰见了一个特殊的接口地址,这个接口是IBM Tivoli产品提供的WebService的接口,先来看一下这个接口地址是什么样的吧!
http://127.0.0.1:1920///cms/soap
这是它提供的一个WebService的接口地址,让我很奇怪的是,这个接口和平常的调用的WebService的接口有很多不一样的地方,但是最重要的就是URL中存在了///的字符,起初没有在意在浏览器中,和DEMO中提供的例子中都可以返回正确的SOAP响应结果,HTTP的接口测试工具也可以返回正确的响应,但是当我在项目中用HttpClient去调用的时候,发现提示404的错误了,很明显这是一个路径没有找到的错误,后来我又看了其他人用HttpClient访问的例子,返现居然好使,这让我很纳闷。于是开始进行了一番探索。
首先我发现好使的HttpClient是旧版本的,不是4这个版本的,而我使用的是HttpClient4.4这个版本的,换成了4.5也不行。用网络请求拦截工具代理拦截后,发现原本应该:
POST ///cms/soap
变成了:
POST /cms/soap
所以才会提示404,为什么HttpClient4会有这个问题,经过了调试源码后找到了问题。
当调用HttpClient的execcute的方法时,内部会调用一些执行链的类,其中有个类叫做ProtocolExec,位于org.apache.http.impl.execchain下,如下图所示:
在类中有这样一行代码:
// Re-write request URI if needed rewriteRequestURI(request, route);
我很奇怪,注释里意思是需要的时候重写,但是这样的代码根据我的经验应该是有个字段动态判断吧,这样才可以根据需要或者不需要进行重写URI的操作,但是HttpClient4的代码中并不存在这个判断的操作,所以就是访问任何的时候,都会调用重写URI的这个方法,那么注释就没有任何的意义了,所以我在源码中的此处加上了一个判断操作,如下所示:
final HttpParams params = request.getParams();
// Re-write request URI if needed
boolean notWrite = params.getBooleanParameter("notWrite",false);
if(!notWrite){
rewriteRequestURI(request, route);
}
HttpPost post = new HttpPost(url);
HttpParams params = new BasicHttpParams();
params.setBooleanParameter("notWrite", true);
post.setParams(params);
希望可以帮助到遇到此类问题的人们!