网上关于“java中发送HTTP/HTTPS的POST请求”的技术文章非常多,有的可用,有的不可用,很难分辨,而这些又在日常开发中经常用到。所以个人对以前使用的三类进行了总结(均参考了网络资料,亲测可用),希望以后自己或者网友能够用到,如有不妥之处,欢迎讨论。
依赖包:
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
代码:
/**
* 发送form表单类型的Post请求
*
* @param url 发送的url
* @param headerMap 请求头参数集合 key参数名 value为参数值
* @param bodyMap 请求参数集合 key参数名 value为参数值
*/
public static String sendFormPost(String url, Map<String, String> headerMap, Map<String, String> bodyMap) {
//创建post请求对象
HttpPost post = new HttpPost(url);
try {
//创建参数集合
List<BasicNameValuePair> list = new ArrayList<>();
//添加参数
if (bodyMap != null) {
for (String str : bodyMap.keySet()
) {
list.add(new BasicNameValuePair(str, bodyMap.get(str)));
}
}
//把参数放入请求对象,,post发送的参数list,指定格式
post.setEntity(new UrlEncodedFormEntity(list, Constants.UTF8));
if (headerMap != null) {
for (String str : headerMap.keySet()
) {
post.addHeader(str, headerMap.get(str));
}
}
CloseableHttpClient client = HttpClients.createDefault();
//启动执行请求,并获得返回值
CloseableHttpResponse response = client.execute(post);
//得到返回的entity对象
HttpEntity entity = response.getEntity();
//把实体对象转换为string
String result = EntityUtils.toString(entity, Constants.UTF8);
//为防止频繁调用一个接口导致接口爆掉,每次调用完成后停留100毫秒
Thread.sleep(100);
//返回内容
return result;
} catch (Exception e1) {
e1.printStackTrace();
return "";
}
}
依赖:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
代码:
/**
* 发送json数据的post请求
* 不支持https
*
* @param url 路径
* @param sendData 参数(json串)
* @return 返回调接口返回信息
*/
public static String sendJsonPost(String url, String sendData) {
String body = "";
try {
CloseableHttpClient client = HttpClients.createDefault();
//创建post方式请求对象
HttpPost httpPost = new HttpPost(url);
//装填参数
StringEntity s = new StringEntity(sendData, Constants.UTF8);
s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
//设置参数到请求对象中
httpPost.setEntity(s);
//设置header信息
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//执行请求操作,并拿到结果(同步阻塞)
HttpResponse response = client.execute(httpPost);
//获取结果实体
HttpEntity entity = response.getEntity();
if (entity != null) {
//按指定编码转换结果实体为String类型
body = EntityUtils.toString(entity, Constants.UTF8);
}
EntityUtils.consume(entity);
//为防止频繁调用一个接口导致接口爆掉,每次调用完成后停留100毫秒
Thread.sleep(100);
} catch (Exception e) {
log.info("JSON数据发送失败,异常:{}", e.getMessage());
log.error("异常:", e);
}
return body;
}
依赖:
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
代码:
private static class TrustAnyTrustManager implements X509TrustManager {
/**
* 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,因此我们只需要执行默认的信任管理器的这
* 个方法。
* JSSE中,默认的信任管理器类为TrustManager。
*/
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
/**
* 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。
* 在实现该方法时,也可以简单的不做任何处理, 即一个空的函数体,由于不会抛出异常,它就会信任任何证书。(non-Javadoc)
*/
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
/**
* @return 返回受信任的X509证书数组。
*/
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
/**
* post方式请求服务器(https协议)
*
* @param url 求地址
* @param content 参数
* @return
*/
public static String sendJsonToHttpsPost(String url, String content) {
try {
/*
* 类HttpsURLConnection似乎并没有提供方法设置信任管理器。其实,
* HttpsURLConnection通过SSLSocket来建立与HTTPS的安全连接
* ,SSLSocket对象是由SSLSocketFactory生成的。
* HttpsURLConnection提供了方法setSSLSocketFactory
* (SSLSocketFactory)设置它使用的SSLSocketFactory对象。
* SSLSocketFactory通过SSLContext对象来获得,在初始化SSLContext对象时,可指定信任管理器对象。
*/
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{new TrustAnyTrustManager()},
new java.security.SecureRandom());
URL console = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.setDoOutput(true);
// 设置请求头
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.connect();
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(content.getBytes(Constants.UTF8));
// 刷新、关闭
out.flush();
out.close();
InputStream is = conn.getInputStream();
if (is != null) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
return new String(outStream.toByteArray(), Constants.UTF8);
}
} catch (Exception e) {
log.info("JSON数据发送失败,异常:{}", e.getMessage());
log.error("异常:", e);
}
return null;
}
依赖:
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.12</version>
</dependency>
代码:
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class HttpUtil {
/**
* 以post方式调用第三方接口,以form-data 形式 发送 MultipartFile 文件数据
*
* @param url post请求url
* @param fileParamName 文件参数名称
* @param multipartFile 文件
* @param otherFormDataMap 表单中的其他参数
* @param connectTimeout 连接超时时间
* @return 返回 接口返回结果
*/
public static String doPostFormDataFile(String url, String fileParamName, MultipartFile multipartFile, Map<String, String> otherFormDataMap,
int connectTimeout) throws IOException {
File toFile = transferToFile(multipartFile);
Map<String, Object> data = new HashMap<>();
data.put(fileParamName, toFile);
data.putAll(otherFormDataMap);
long t1 = System.currentTimeMillis();
log.info("doPostFormDataFile -- 开始接口调用,otherFormDataMap:{},fileName:{}", JSON.toJSONString(otherFormDataMap), multipartFile.getOriginalFilename());
String response = HttpRequest.post(url)
.form(data)
.contentType("multipart/form-data")
.setConnectionTimeout(connectTimeout)
.execute()
.body();
long t2 = System.currentTimeMillis();
log.info("doPostFormDataFile -- 调用接口结束,耗时:{},otherFormDataMap:{},fileName:{},响应结果:{}", t2 - t1, JSON.toJSONString(otherFormDataMap), multipartFile.getOriginalFilename(), response);
return response;
}
public static File transferToFile(MultipartFile multipartFile) throws IOException {
//选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
File file = null;
try {
String originalFilename = multipartFile.getOriginalFilename();
//获取文件后缀
String prefix = originalFilename.substring(originalFilename.lastIndexOf("."));
//创建临时文件
file = File.createTempFile(originalFilename, prefix);
multipartFile.transferTo(file);
//删除
file.deleteOnExit();
} catch (IOException e) {
log.error("transferToFile--异常:", e);
throw e;
}
return file;
}
}