在调用公司的某个接口时,直接通过浏览器配置代理服务器可以请求到如下数据:
请求url地址:http://wwwnei.xuebusi.com/rd-interface/getsales.jsp?cid=12007036
1 <Root> 2 <Result>1</Result> 3 <Message></Message> 4 <SalesLevel> 5 <![CDATA[KU6]]> 6 </SalesLevel> 7 <BranchId> 8 <![CDATA[0]]> 9 </BranchId> 10 <ENName> 11 <![CDATA[jamie.liu]]> 12 </ENName> 13 <Mobile> 14 <![CDATA[15001038876]]> 15 </Mobile> 16 <BranchCompany> 17 <![CDATA[集团总部]]> 18 </BranchCompany> 19 <Telephone> 20 <![CDATA[010-58344688-65578]]> 21 </Telephone> 22 <Email> 23 <![CDATA[jamie.liu@xuebusi.com]]> 24 </Email> 25 <CNName> 26 <![CDATA[张三]]> 27 </CNName> 28 <CityForLive800> 29 <![CDATA[集团总部]]> 30 </CityForLive800> 31 </Root>
但是,在java代码中,没有配置代理服务器的情况下,直接使用HttpClient测试请求该接口时,却返回如下数据:
Active connections: 1
server accepts handled requests
786216 786216 788311
Reading: 0 Writing: 1 Waiting: 0
解决方案:
使用HttpClient模拟浏览器发送请求时,配置自己公司的代理服务器地址和端口号,然后接口就能正常返回了。
1 import com.xuebusi.ihr.core.utils.HttpClientUtil; 2 import com.xuebusi.ihr.core.utils.Xml2Json; 3 import org.apache.http.HttpEntity; 4 import org.apache.http.HttpHost; 5 import org.apache.http.NameValuePair; 6 import org.apache.http.ParseException; 7 import org.apache.http.client.entity.UrlEncodedFormEntity; 8 import org.apache.http.client.methods.CloseableHttpResponse; 9 import org.apache.http.client.methods.HttpGet; 10 import org.apache.http.client.methods.HttpPost; 11 import org.apache.http.config.Registry; 12 import org.apache.http.config.RegistryBuilder; 13 import org.apache.http.conn.socket.ConnectionSocketFactory; 14 import org.apache.http.conn.socket.PlainConnectionSocketFactory; 15 import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 16 import org.apache.http.impl.client.CloseableHttpClient; 17 import org.apache.http.impl.client.HttpClientBuilder; 18 import org.apache.http.impl.client.HttpClients; 19 import org.apache.http.impl.conn.DefaultProxyRoutePlanner; 20 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 21 import org.apache.http.message.BasicNameValuePair; 22 import org.apache.http.util.EntityUtils; 23 24 import javax.net.ssl.SSLContext; 25 import javax.net.ssl.TrustManager; 26 import javax.net.ssl.X509TrustManager; 27 import java.io.IOException; 28 import java.io.UnsupportedEncodingException; 29 import java.security.KeyManagementException; 30 import java.security.NoSuchAlgorithmException; 31 import java.security.cert.CertificateException; 32 import java.util.ArrayList; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.Map; 36 37 /** 38 * http使用代理服务器发送请求测试类 39 * Created by SYJ on 2017/9/19. 40 */ 41 public class HttpProxyTest { 42 43 public static void main(String[] args) throws ParseException, IOException, KeyManagementException, NoSuchAlgorithmException { 44 String saleUserInfoXml = getSaleUserInfoXml(); 45 System.out.println(" xml转成json格式: " + saleUserInfoXml); 46 47 } 48 49 /** 50 * 测试调用rd查询销售顾问信息接口 51 * 将接口返回的xml格式数据转成json 52 * @return 53 */ 54 public static String getSaleUserInfoXml() { 55 String url = "http://wwwnei.xuebusi.com/rd-interface/getsales.jsp"; 56 HashMap<String, Object> map = new HashMap<>(); 57 map.put("cid", "12007036"); 58 String responseBody; 59 String xml2JsonStr = ""; 60 try { 61 responseBody = send(url, map, "utf-8"); 62 System.out.println(" 接口返回xml格式数据: " + responseBody); 63 xml2JsonStr = Xml2Json.xml2Json(responseBody).toJSONString(); 64 } catch (Exception e) { 65 e.printStackTrace(); 66 } 67 return xml2JsonStr; 68 } 69 70 /** 71 * 设置代理 72 * 73 * @param hostOrIP 74 * @param port 75 * @return 76 */ 77 public static HttpClientBuilder proxy(String hostOrIP, int port) { 78 // 依次是代理地址,代理端口号,协议类型 79 HttpHost proxy = new HttpHost(hostOrIP, port, "http"); 80 DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); 81 return HttpClients.custom().setRoutePlanner(routePlanner); 82 } 83 84 /** 85 * 模拟请求 86 * 87 * @param url 资源地址 88 * @param map 参数列表 89 * @param encoding 编码 90 */ 91 public static String send(String url, Map<String, Object> map, String encoding) throws Exception { 92 String body = ""; 93 SSLContext sslcontext = createIgnoreVerifySSL();//绕过证书验证,处理https请求 94 // 设置协议http和https对应的处理socket链接工厂的对象 95 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() 96 .register("http", PlainConnectionSocketFactory.INSTANCE) 97 .register("https", new SSLConnectionSocketFactory(sslcontext)) 98 .build(); 99 PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 100 HttpClients.custom().setConnectionManager(connManager); 101 102 //创建自定义的httpclient对象,指定自己公司的代理服务器地址和端口号 103 CloseableHttpClient client = proxy("192.168.20.6", 3128).setConnectionManager(connManager).build(); 104 //CloseableHttpClient client = HttpClients.createDefault(); 105 106 HttpGet httpGet = buildHttpGet(url, map); 107 108 //设置header信息 109 httpGet.setHeader("Content-Type", "text/xml;charset=UTF-8"); 110 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"); 111 112 try { 113 CloseableHttpResponse response = client.execute(httpGet);//执行请求操作,并拿到结果(同步阻塞) 114 HttpEntity entity = response.getEntity();//获取结果实体 115 if (entity != null) { 116 body = EntityUtils.toString(entity, encoding);//按指定编码转换结果实体为String类型 117 } 118 EntityUtils.consume(entity); 119 response.close();//释放链接 120 } catch (IOException e) { 121 e.printStackTrace(); 122 } 123 return body; 124 } 125 126 /** 127 * httpGet传参 128 * 129 * @param url 130 * @param params 131 * @return 132 */ 133 public static HttpGet buildHttpGet(String url, Map<String, Object> params) { 134 String parmStr = HttpClientUtil.getUrlParamsByMap(params); 135 try { 136 url = HttpClientUtil.urlFormat(url, parmStr, "utf-8"); 137 } catch (Exception e) { 138 e.printStackTrace(); 139 } 140 return new HttpGet(url); 141 } 142 143 /** 144 * httpPost传参 145 * 146 * @param url 147 * @param params 148 * @return 149 */ 150 public static HttpPost buildHttpPost(String url, Map<String, Object> params) { 151 HttpPost httpPost = new HttpPost(url);//创建post方式请求对象 152 List<NameValuePair> nvps = new ArrayList<>();//装填参数 153 if (params != null) { 154 for (Map.Entry<String, Object> entry : params.entrySet()) { 155 nvps.add(new BasicNameValuePair(entry.getKey(), (String) entry.getValue())); 156 } 157 } 158 try { 159 //设置参数到请求对象中 160 httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); 161 } catch (UnsupportedEncodingException e) { 162 e.printStackTrace(); 163 } 164 System.out.println("请求地址:" + url + "请求参数:" + nvps.toString()); 165 return httpPost; 166 } 167 168 /** 169 * 绕过验证 170 * 171 * @return 172 * @throws NoSuchAlgorithmException 173 * @throws KeyManagementException 174 */ 175 public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { 176 SSLContext sc = SSLContext.getInstance("SSLv3"); 177 178 // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法 179 X509TrustManager trustManager = new X509TrustManager() { 180 @Override 181 public void checkClientTrusted( 182 java.security.cert.X509Certificate[] paramArrayOfX509Certificate, 183 String paramString) throws CertificateException { 184 } 185 @Override 186 public void checkServerTrusted( 187 java.security.cert.X509Certificate[] paramArrayOfX509Certificate, 188 String paramString) throws CertificateException { 189 } 190 @Override 191 public java.security.cert.X509Certificate[] getAcceptedIssuers() { 192 return null; 193 } 194 }; 195 sc.init(null, new TrustManager[]{trustManager}, null); 196 return sc; 197 } 198 }
上面只是在本地测试调用预上线接口时的解决方案,实际上将项目部署到公司预上线时,是不需要配置代理服务器的,直接使用HttpClient就可以正常调用的,也能正常返回xml格式数据。