post请求
前言
java后端平时会有一些调用后端接口的需求,http协议的接口都好处理,都给httpClient就可以实现,这里就不赘述了;比较难搞定的就是https接口了,这类接口直接用httpClient去调用是不可以的,这个时候,就需要使用我们封装的工具类来实现了;
代码
public class CertificateValidationIgnored {
//获取org.apache.http.client.HttpClient对象
public static HttpClient getNoCertificateHttpClient(){
return getCertificateValidationIgnoredHttpClient();
}
//忽略证书,即使默认端口不是433也可以
public static SSLConnectionSocketFactory getSslsf() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContext.getInstance("SSL");//sslContext= SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return sslsf;
}
//默认端口是443
private static HttpClient getCertificateValidationIgnoredHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);
//核心代码,创建一个UnVerifySocketFactory对象,验证证书时总是返回true
SSLSocketFactory sf = new UnVerifySocketFactory(trustStore);
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) {
System.out.println("CertificateValidationIgnored,创建忽略用户证书的HttpClient对象失败,尝试创建普通HttpClient对象");
e.printStackTrace();
return new DefaultHttpClient();
}
}
/**
* 核心类
* UnVerifySocketFactory:一个验证证书时总是返回true的SSLSocketFactory的子类
*/
private static X509HostnameVerifier ignoreVerifier;
private static class UnVerifySocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public UnVerifySocketFactory(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 void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
// TODO Auto-generated method stub
ignoreVerifier = new X509HostnameVerifier() {
@Override
public void verify(String arg0, String[] arg1, String[] arg2)
throws SSLException {
}
@Override
public void verify(String arg0, X509Certificate arg1)
throws SSLException {
}
@Override
public void verify(String arg0, SSLSocket arg1)
throws IOException {
}
//最最核心代码
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
};
super.setHostnameVerifier(ignoreVerifier);
}
@Override
public X509HostnameVerifier getHostnameVerifier() {
return ignoreVerifier;
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
调用接口,传参方式1
CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(CertificateValidationIgnored.getSslsf()).build();//实例化HttpClients对象
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
//参数放到request域中
qparams.add(new BasicNameValuePair("method","targetmethod"));//需要对应传参的name和value
qparams.add(new BasicNameValuePair("orderID",orderID));//需要对应传参的name和value
httpPost.setEntity(new UrlEncodedFormEntity(qparams, HTTP.UTF_8));
HttpResponse response1 = client.execute(httpPost);
//获取结果实体
HttpEntity entity = response1.getEntity();
if (entity != null) {
//按指定编码转换结果实体为String类型
jsonString = EntityUtils.toString(entity, "UTF-8");
net.sf.json.JSONObject jsonOBj = net.sf.json.JSONObject.fromObject(jsonString);
return CommonDao.isnull(jsonOBj.get("status"));
}
传参方式2
HttpPost httpPost = new HttpPost(targeturl);
JSONObject jsonTo = new JSONObject();
jsonTo.put("data", "data");
//将json作为参数,将参数放到requestbody中传递
httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
//表单提交
//stringEntity.setContentType("application/x-www-form-urlencoded");
StringEntity se = new StringEntity(CommonDao.isnull(jsonTo.toString()));
httpPost.setEntity(se);
插曲
在jdk1.7+tomcat7+windows server2012的环境下运行这段代码报了个错误java运行报错:nested exception is java.lang.NoSuchFieldError: INSTANCE,原因是,当前项目的jar包存在版本冲突,默认加载版本低的;我项目里有两个httpclient jar包:4.1版本和4.3版本;删除低版本后就解决了报错;
get请求
和post请求基本一致,区别在于get方式是通过setParameter传参
URI uri = new URIBuilder(url).setParameter("method", method).setParameter("param",param).build();
HttpGet httpGet = new HttpGet(uri);
//之前没有设置header的时候,给我返回http418状态码
//通过模拟postman请求,避免返爬虫给我禁了
httpGet.addHeader("User-Agent","PostmanRuntime/7.26.8");
httpGet.addHeader("Connection","keep-alive");
httpGet.addHeader("Accept-Encoding","gzip, deflate, br");
HttpResponse response1 = client.execute(httpGet);
HttpClient的请求示例
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
postMethod.addParameter("入参","可以是0-n个");
httpClient.executeMethod(postMethod);
InputStream inputStream = postMethod.getResponseBodyAsStream();
//接口响应数据
String result = getResultStrFromStream(inputStream);
//ajax的形式
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type","application/json;charset=UTF-8");
ObjectNode objectNode = objectMapper.createObjectNode(); objectNode.put("interfacekey",INTERFACEKEY).put("name",personName).put("sfzh",idCard).put("base64",faceBase64);
String requestStr = AesUtil.encrypt(objectNode.toString(), AES_KEY);
objectNode.removeAll().put("signdata",requestStr);
StringRequestEntity stringRequestEntity = new StringRequestEntity(objectNode.toString(),null,"utf-8");
postMethod.setRequestEntity(stringRequestEntity);
httpClient.executeMethod(postMethod);
String result = postMethod.getResponseBodyAsString();