1、首先,https是颁发给域名的,如果采取 ip加https访问的机制,会出现证书不安全的问题,直接使用HttpClient去连接会出现客户端无法信任服务器的问题。
解决思想:如果我们去调用这种服务器,从实现上,我们知道这个服务器应该是可信的,所以可以实现忽略这种判断。
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
/**
*
* @param truststore
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
*/
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
/**
* 在使用时直接调用它即可,,,, 直接得略过https的ssl验证过程
* @return
*/
public static HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
}
然后,在你创建httpClient的时候使用这个方法去创建就可以了,例如:
HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);
2、如果从服务器返回的网页是乱码,这个时候你首先得注意一下编码问题,如果编码没有问题。查看服务器的返回头信息中有没有说gzip等信息,如果有,说明网页被压缩了,解压即可。例如下面这个方法
String body = "";
HttpEntity httpEntity = response.getEntity();
if (Objects.nonNull(httpEntity)) {
InputStream is = httpEntity.getContent();
is = new GZIPInputStream(is);//解压缩
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"));
String str = null;
StringBuffer stringBuffer = new StringBuffer();
while (Objects.nonNull(str = reader.readLine())) {
if (StringUtils.isBlank(str)) {
continue;
}
stringBuffer.append(str);
}
body = stringBuffer.toString();
}
3、如果你需要登录某网站获取cookie然后直接利用这个cookie访问别的接口,可以使用如下办法:
// 获取cookieStore
cookieStore = ((DefaultHttpClient) httpclient).getCookieStore();
// 设置cookieStore
((DefaultHttpClient) httpclient).setCookieStore(cookieStore);
不需要把cookie取出来自己操作,只需要保存一个对象属性cookieStore即可
4、HttpGet或者HttpPost绑定参数
// httpget demo
param.add(new BasicNameValuePair("xxxx", xxxx));
param.add(new BasicNameValuePair("yyyy", yyyy));
param.add(new BasicNameValuePair("zzzz", zzzz));
param.add(new BasicNameValuePair("wwww", wwww));
String paramStr = "";
try {
paramStr = EntityUtils.toString(new UrlEncodedFormEntity(param, "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
String loginUrl1 = loginUrl + paramStr;
HttpGet httpget = new HttpGet(loginUrl1);
// httppost demo
HttpPost httpPost = new HttpPost(url);
param.add(new BasicNameValuePair("xxxx", xxxx));
param.add(new BasicNameValuePair("yyyy", yyyy));
param.add(new BasicNameValuePair("zzzz", zzzz));
param.add(new BasicNameValuePair("wwww", wwww));
try {
httpPost.setEntity(new UrlEncodedFormEntity(param, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}