在调用公司的某个接口时,直接通过浏览器配置代理服务器可以请求到如下数据:
请求url地址:http://wwwnei.xuebusi.com/rd-interface/getsales.jsp?cid=12007036
<Root>
<Result>1</Result>
<Message></Message>
<SalesLevel>
<![CDATA[KU6]]>
</SalesLevel>
<BranchId>
<![CDATA[]]>
</BranchId>
<ENName>
<![CDATA[jamie.liu]]>
</ENName>
<Mobile>
<![CDATA[]]>
</Mobile>
<BranchCompany>
<![CDATA[集团总部]]>
</BranchCompany>
<Telephone>
<![CDATA[010-58344688-65578]]>
</Telephone>
<Email>
<![CDATA[jamie.liu@xuebusi.com]]>
</Email>
<CNName>
<![CDATA[张三]]>
</CNName>
<CityForLive800>
<![CDATA[集团总部]]>
</CityForLive800>
</Root>
但是,在java代码中,没有配置代理服务器的情况下,直接使用HttpClient测试请求该接口时,却返回如下数据:
Active connections: 1
server accepts handled requests
786216 786216 788311
Reading: 0 Writing: 1 Waiting: 0
解决方案:
使用HttpClient模拟浏览器发送请求时,配置自己公司的代理服务器地址和端口号,然后接口就能正常返回了。
import com.xuebusi.ihr.core.utils.HttpClientUtil;
import com.xuebusi.ihr.core.utils.Xml2Json;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* http使用代理服务器发送请求测试类
* Created by SYJ on 2017/9/19.
*/
public class HttpProxyTest { public static void main(String[] args) throws ParseException, IOException, KeyManagementException, NoSuchAlgorithmException {
String saleUserInfoXml = getSaleUserInfoXml();
System.out.println("\nxml转成json格式:\n" + saleUserInfoXml); } /**
* 测试调用rd查询销售顾问信息接口
* 将接口返回的xml格式数据转成json
* @return
*/
public static String getSaleUserInfoXml() {
String url = "http://wwwnei.xuebusi.com/rd-interface/getsales.jsp";
HashMap<String, Object> map = new HashMap<>();
map.put("cid", "12007036");
String responseBody;
String xml2JsonStr = "";
try {
responseBody = send(url, map, "utf-8");
System.out.println("\n接口返回xml格式数据:\n" + responseBody);
xml2JsonStr = Xml2Json.xml2Json(responseBody).toJSONString();
} catch (Exception e) {
e.printStackTrace();
}
return xml2JsonStr;
} /**
* 设置代理
*
* @param hostOrIP
* @param port
* @return
*/
public static HttpClientBuilder proxy(String hostOrIP, int port) {
// 依次是代理地址,代理端口号,协议类型
HttpHost proxy = new HttpHost(hostOrIP, port, "http");
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
return HttpClients.custom().setRoutePlanner(routePlanner);
} /**
* 模拟请求
*
* @param url 资源地址
* @param map 参数列表
* @param encoding 编码
*/
public static String send(String url, Map<String, Object> map, String encoding) throws Exception {
String body = "";
SSLContext sslcontext = createIgnoreVerifySSL();//绕过证书验证,处理https请求
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslcontext))
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager); //创建自定义的httpclient对象,指定自己公司的代理服务器地址和端口号
CloseableHttpClient client = proxy("192.168.20.6", 3128).setConnectionManager(connManager).build();
//CloseableHttpClient client = HttpClients.createDefault(); HttpGet httpGet = buildHttpGet(url, map); //设置header信息
httpGet.setHeader("Content-Type", "text/xml;charset=UTF-8");
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"); try {
CloseableHttpResponse response = client.execute(httpGet);//执行请求操作,并拿到结果(同步阻塞)
HttpEntity entity = response.getEntity();//获取结果实体
if (entity != null) {
body = EntityUtils.toString(entity, encoding);//按指定编码转换结果实体为String类型
}
EntityUtils.consume(entity);
response.close();//释放链接
} catch (IOException e) {
e.printStackTrace();
}
return body;
} /**
* httpGet传参
*
* @param url
* @param params
* @return
*/
public static HttpGet buildHttpGet(String url, Map<String, Object> params) {
String parmStr = HttpClientUtil.getUrlParamsByMap(params);
try {
url = HttpClientUtil.urlFormat(url, parmStr, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return new HttpGet(url);
} /**
* httpPost传参
*
* @param url
* @param params
* @return
*/
public static HttpPost buildHttpPost(String url, Map<String, Object> params) {
HttpPost httpPost = new HttpPost(url);//创建post方式请求对象
List<NameValuePair> nvps = new ArrayList<>();//装填参数
if (params != null) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
nvps.add(new BasicNameValuePair(entry.getKey(), (String) entry.getValue()));
}
}
try {
//设置参数到请求对象中
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("请求地址:" + url + "请求参数:" + nvps.toString());
return httpPost;
} /**
* 绕过验证
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSLv3"); // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}
}
上面只是在本地测试调用预上线接口时的解决方案,实际上将项目部署到公司预上线时,是不需要配置代理服务器的,直接使用HttpClient就可以正常调用的,也能正常返回xml格式数据。