HTTP及HTTPS协议说明及各类请求使用
HTTP及HTTPS协议说明
HTTP:超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使用浏览器
更加高效,使网络传输减少
HTTPS: 是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即 HTTP下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。
HTTP 和 HTTPS 的区别?
1、http是明文传输,数据都是未加密的,安全性较差,https数据传输过程是加密的,安全性较好(http+ssl)。
2、使用https协议需要到CA(数字认证机构)申请证书。
3、http协议响应速度比https快,主要是因为http使用TCP三次握手建立链接,客户端和服务器需要交换3个包,
而https除了TCP的三个包,还要加上SSL握手的9个包,所以一共12个包。
4、http协议端口80,https端口443。
5、https是建立在SSL/TLS之上的http协议,所以更耗费服务器资源。
HTTPS协议的工作原理:
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤:
- 客户使用HTTPS url访问服务器,则要求web服务器建立SSL链接。
- web服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或者说传输给客户端
- 客户端和web服务端开始协商SSL链接的安全等级,也就是加密等级
- 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
- web服务器通过自己的私钥解密钥出会话密钥,web服务器通过会话密钥加密与客户端之间的通信。
HTTPS协议的优点
使用HTTPS协议可以认证用户和服务器,确保数据发送到正确的客户机和服务器;
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,要比HTTP协议安全,可防止数据在传输过程中不被窃取,改变,确保数据的完整性。
HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅度增加了中间人攻击的成本。
HTTPS协议的缺点
HTTPS握手阶段比较费时,会使页面加载时间延长50%,增加10%~20%的耗电。HTTPS缓存不如HTTP高效,会增加数据开销。SSL证书也需要钱,功能越强大的证书费用越高。SSL证书需要绑定IP,不能再同一个IP上绑定多个域名,ipv4资源支持不了这种消耗。
HTTPS加密协议
可见:https://blog.csdn.net/qzwzsl/article/details/125731575
HTTP各类请求
package HTTP.http;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Slf4j
@Component
public class HttpUtil {
@Resource
private RestTemplate restTemplate;
/**
* 创建POST请求 入参使用数据流的形式调取接口
* @param httpUrl 发送请求的 URL
* @param param 请求参数应该是{"key":"==99d"}的形式。
* @return result 返回结果
*/
public static String doPost(String httpUrl, String param) {
HttpURLConnection connection = null;
InputStream is = null;
OutputStream os = null;
BufferedReader br = null;
String result = null;
try {
URL url = new URL(httpUrl);
// 经过远程url链接对象打开链接
connection = (HttpURLConnection) url.openConnection();
// 设置链接请求方式
connection.setRequestMethod("POST");
// 设置链接主机服务器超时时间:15000毫秒
connection.setConnectTimeout(15000000);
// 设置读取主机服务器返回数据超时时间:60000毫秒
connection.setReadTimeout(600000000);
// 默认值为:false,当向远程服务器传送数据/写数据时,须要设置为true
connection.setDoOutput(true);
// 默认值为:true,当前向远程服务读取数据时,设置为true,该参数无关紧要
connection.setDoInput(true);
// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=----daf10c20d06");
connection.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");
connection.setRequestProperty("Accept-Language", "zh-cn");
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");
connection.setRequestProperty("Host", "208.208.134.66:8077");
connection.setRequestProperty("Content-Length", "2740000");
connection.setRequestProperty("Connection", "close");
connection.setRequestProperty("Cache-Control", "no-cache");
// 经过链接对象获取一个输出流
os = connection.getOutputStream();
// 经过输出流对象将参数写出去/传输出去,它是经过字节数组写出的
os.write(param.getBytes());
// 经过链接对象获取一个输入流,向远程读取
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 对输入流对象进行包装:charset根据工做项目组的要求来设置
br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
StringBuilder sbf = new StringBuilder();
String temp = null;
// 循环遍历一行一行读取数据
while ((temp = br.readLine()) != null) {
sbf.append(temp);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (IOException e) {
log.error("POST请求异常: ",e)
} finally {
// 关闭资源
if (null != br) {
try {
br.close();
} catch (IOException e) {
log.error("BufferedReader流关闭异常: ",e)
}
}
if (null != os) {
try {
os.close();
} catch (IOException e) {
log.error("OutputStream流关闭异常: ",e);
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
log.error("InputStream流关闭异常: ",e);
}
}
if(null != connection){
// 断开与远程地址url的链接
connection.disconnect();
}
}
return result;
}
/**
* 建立GET请求 入参使用流的形式调取接口
* @param httpUrl 请求url:请求参数用?拼接在url后边,请求参数应该是 name1=value1&name2=value2 的形式。
* @return result 返回结果
*/
public static String doGet(String httpUrl) {
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
String result = null;// 返回结果字符串
try {
// 建立远程url链接对象
URL url = new URL(httpUrl);
// 经过远程url链接对象打开一个链接,强转成httpURLConnection类
connection = (HttpURLConnection) url.openConnection();
// 设置链接方式:get
connection.setRequestMethod("GET");
// 设置链接主机服务器的超时时间:15000毫秒
connection.setConnectTimeout(15000);
// 设置读取远程返回的数据时间:60000毫秒
connection.setReadTimeout(60000);
// 发送请求
connection.connect();
// 经过connection链接,获取输入流
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 封装输入流is,并指定字符集
br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
// 存放数据
StringBuilder sbd = new StringBuilder();
String temp = null;
while ((temp = br.readLine()) != null) {
sbd.append(temp);
sbd.append("\r\n");
}
result = sbd.toString();
}
} catch (Exception e) {
log.error("GET请求异常: ",e);
} finally {
// 关闭资源
if (null != br) {
try {
br.close();
} catch (IOException e) {
log.error("BufferedReader流关闭异常: ",e);
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
log.error("InputStream流关闭异常: ",e);
}
}
if (null != connection){
connection.disconnect();// 关闭远程链接
}
}
return result;
}
/**
* 建立PUT请求 以form-data 形式
* @param url 请求url
* @param token 授权码
* @param paramMap 表单
* @return strResponse 返回结果
*/
public String doPutFormData(String url, Map<String, Object> paramMap, String token) {
log.info("PUT请求url为:{}",url);
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpPut httpPut = null;
String strResponse = null;
try{
// 创建Http实例
httpClient = HttpClients.createDefault();
// 创建HttpPut实例
httpPut = new HttpPut(url);
// 请求参数配置
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000)
.setConnectionRequestTimeout(10000).build();
httpPut.setConfig(requestConfig);
//构造请求头
httpPut.setHeader("AccessToken", token);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(StandardCharsets.UTF_8);
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
builder.addPart(entry.getKey(), new StringBody((String) entry.getValue(), ContentType.create("text/plain", Consts.UTF_8)));
}
HttpEntity entity = builder.build();
httpPut.setEntity(entity);
//执行请求
response = httpClient.execute(httpPut);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}", strResponse);
}
} catch (Exception e) {
log.error("调用httpPut异常: ",e);
} finally {
if (null != httpPut){
httpPut.releaseConnection();
}
if (null != response){
try {
response.close();
}catch(IOException e){
log.eror("httpResponse流关闭异常: ",e);
}
}
if (null != httpClient ) {
try {
httpClient.close();
} catch (IOException e) {
log.error("httpPut关闭异常: ",e);
}
}
log.info("接口返回参数为:{}",strResponse);
}
return strResponse;
}
/**
* 建立POST请求 以form-data 形式 发送 MultipartFile 文件数据
* @param url 请求url
* @param token 授权码
* @param paramMap 表单中存在:MultipartFile文件数据
* @return strResponse 返回结果
*/
public String doPostFormData(String url, Map<String, Object> paramMap, String token) {
log.info("POST请求url为:{}",url);
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpPut httpPut = null;
String strResponse = null;
try{
// 创建Http实例
httpClient = HttpClients.createDefault();
// 创建HttpPost实例
httpPost = new HttpPost(url);
// 请求参数配置
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000)
.setConnectionRequestTimeout(10000).build();
httpPost.setConfig(requestConfig);
//构造请求头
httpPost.setHeader("AccessToken", token);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(StandardCharsets.UTF_8);
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//表单中其他参数
for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
String fileParamName = entry.getKey();
if (fileParamName.equals("File")) {
MultipartFile multipartFile = (MultipartFile) entry.getValue();
String fileName = multipartFile.getOriginalFilename();
// 文件流
builder.addBinaryBody(fileParamName, multipartFile.getInputStream(), ContentType.MULTIPART_FORM_DATA,fileName);
}else {
builder.addPart(entry.getKey(), new StringBody((String) entry.getValue(), ContentType.create("text/plain",Consts.UTF_8)));
}
}
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
//执行请求
response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}", strResponse);
}
} catch (Exception e) {
log.error("调用HttpPost异常: ",e);
} finally {
if (null != httpPost){
httpPost.releaseConnection();
}
if (null != response){
try {
response.close();
}catch(IOException e){
log.eror("httpResponse流关闭异常: ",e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("httpClient关闭异常: ",e);
}
}
log.info("接口返回参数为:{}",strResponse);
}
return strResponse;
}
/**
* 建立 GET请求
* @param url 请求链接
* @param token 授权码
* @return strResponse 返回结果
*/
public String doGet(String url, Map<String, Object> UrlParams, String token) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpGet httpGet = null;
String strResponse = null;
try {
//初始化对象
httpClient = HttpClients.createDefault();
// 拼接参数
StringBuilder stringBuffer = new StringBuilder();
stringBuffer.append("?");
if (null != UrlParams && !UrlParams.isEmpty()) {
for (Map.Entry<String, Object> entry : UrlParams.entrySet()) {
stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
stringBuffer.deleteCharAt(stringBuffer.length() - 1);
url = url + stringBuffer;
log.info("GET请求url:{}", url);
httpGet = new HttpGet(url);
httpGet.setHeader("Content-type", "application/json; charset=utf-8");
if (StringUtils.isNotBlank(token)) {
httpGet.setHeader("Authorization", token);
}
//执行请求
response = httpClient.execute(httpGet);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}", strResponse);
}
} catch (IOException e) {
log.error("GET请求响应失败:" + e);
return "";
} finally {
if (null != httpGet) {
httpGet.releaseConnection();
}
if (null != response) {
try {
response.close();
} catch (IOException e) {
log.error("httpResponse流关闭异常:", e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("HttpClient关闭异常", e);
}
}
return strResponse;
}
/**
* 建立 GET 请求
* @param url 请求链接
* @param jsonString 请求参数
* @param token 授权码
* @return strResponse 返回结果
*/
public String get(String url, String jsonString, String token) {
log.info("GET请求url为:{}", url);
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpGet httpGet = null;
String strResponse = null;
try {
//初始化对象
httpClient = HttpClients.createDefault();
if (jsonString == null || jsonString.isEmpty()) {
httpGet = new HttpGet(url);
} else {
httpGet = new HttpGet(url + "?id=" + jsonString);
}
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000 * 60).setConnectTimeout(1000 * 60).build();
httpGet.setConfig(requestConfig);
//构造消息头
httpGet .setHeader("Content-type", "application/json; charset=utf-8");
if (StringUtils.isNotBlank(token)) {
httpGet.setHeader("AccessToken", token);
}
//执行请求
response = httpClient.execute(httpGet);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}", strResponse);
}
} catch (IOException e) {
log.error("GET请求失败: ",e);
} finally {
if (null != httpGet) {
httpGet.releaseConnection();
}
if (null != response) {
try {
response.close();
} catch (IOException e) {
log.error("httpResponse流关闭异常:", e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("HttpClient关闭异常", e);
}
}
log.info("接口返回参数为:{}",strResponse);
}
retuen strResponse;
}
/**
* 发送post请求
* @param url 请求url
* @param strReqBody 请求体
* @param token 授权码
* @return strResponse 返回结果
*/
public String doPost(String url, String strReqBody, String token) {
log.info("请求url为:{},请求参数:{}",url,strReqBody);
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpPost httpPost = null;
String strResponse = null;
try {
// 初始化对象
httpClient = HttpClients.createDefault();
httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000 * 60).setConnectTimeout(1000 * 60).build();
httpPost.setConfig(requestConfig);
// 构造消息头
httpPost.setHeader("Content-type", "application/json");
if (StringUtils.isNotBlank(token)) {
httpPost.setHeader("Authorization", token);
}
// 构造消息体
StringEntity requestEntity = new StringEntity(strReqBody, StandardCharsets.UTF_8);
httpPost.setEntity(requestEntity);
// 执行请求
response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}",strResponse );
}
} catch (Exception e) {
log.error("post请求失败", e);
} finally {
if (null != httpPost) {
httpPost.releaseConnection();
}
if (null != response) {
try {
response.close();
} catch (IOException e) {
log.error("httpResponse流关闭异常:", e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("HttpClient关闭异常", e);
}
}
log.info("接口返回参数为:{}",strResponse);
}
return strResponse;
}
/**
* 发送put请求
*
* @param url 请求url
* @param strReqBody 请求体
* @param token 授权码
* @return strResponse 返回结果
*/
public String doPut(String url, String strReqBody, String token) {
log.info("PUT请求url:{},入参为:{}", url, strReqBody);
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpPut httpPut = null;
String strResponse = null;
try {
// 初始化对象
httpClient = HttpClients.createDefault();
httpPut = new HttpPut(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000 * 60).setConnectTimeout(1000 * 60).build();
httpPut.setConfig(requestConfig);
// 构造消息头
httpPut.setHeader("Content-type", "application/json");
if (StringUtils.isNotBlank(token)) {
httpPut.setHeader("Authorization", token);
}
// 构造消息体
StringEntity requestEntity = new StringEntity(strReqBody, StandardCharsets.UTF_8);
httpPut.setEntity(requestEntity);
// 执行请求
response = httpClient.execute(httpPut);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}", strResponse);
}
} catch (Exception e) {
log.error("put请求失败", e);
} finally {
if (null != httpPut) {
httpPut.releaseConnection();
}
if (null != response) {
try {
response.close();
} catch (IOException e) {
log.error("httpResponse流关闭异常:", e);
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
log.error("HttpClient关闭异常", e);
}
}
}
return strResponse;
}
/**
* 发送del请求
*
* @param url 请求url
* @param jsonString 请求体
* @return strResponse 返回结果
*/
public String sendDelete(String url, String jsonString, String token) {
log.info("DEL请求URL:{},请求参数:{}", url, jsonString);
CloseableHttpResponse response = null;
String strResponse = null;
try {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 创建HttpDelete请求
HttpEntityEnclosingRequestBase httpdel = new HttpDeleteWithBody(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).
setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
httpdel.setConfig(requestConfig);
// 构造消息头
httpdel.setHeader("Content-type", "application/json");
httpdel.setHeader("AccessToken", token);
// 创建请求内容
if (jsonString != null) {
StringEntity entity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
httpdel.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpdel);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
log.info("返回参数:{}", strResponse);
}
} catch (Exception e) {
log.info("del请求异常: ",e);
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
log.error("httpResponse流关闭异常:", e);
}
}
return strResponse;
}
/**
* 发送HTTP请求
*
* @param requestParam 请求时带的实体类,参数等
* @param url HTTP 请求地址
* @param requestHeaders 请求头,没有请求头的设置为null即可
* @param requestMethod 请求方法 GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
* @param time 用于判断。3以上50004错误,不在刷新token,重新请求该次接口。
* @return 返回的是Object类型 其中ResponseEntity.getBody()请求返回json内容;ResponseEntity.getStatusCodeValue() 请求返回http状态码
*/
public <T> ResponseEntity remoteHttp(T requestParam, String url, org.springframework.http.HttpHeaders requestHeaders,
String requestMethod,int time) throws Exception {
ResponseEntity responseEntity;
String paramStr = "";
if (requestParam != null) {
paramStr = requestParam.toString();
}
//log.debug("第" + time + "次,restful请求url:" + url + ",请求方式:" + requestMethod + ",请求参数:" + paramStr);
org.springframework.http.HttpEntity<T> requestEntity = new org.springframework.http.HttpEntity<>(requestParam, requestHeaders);
HttpMethod httpMethod;
String method = requestMethod.toLowerCase();
switch (method) {
case "post":
httpMethod = HttpMethod.POST;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
case "put":
httpMethod = HttpMethod.PUT;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
case "delete":
httpMethod = HttpMethod.DELETE;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
case "patch":
httpMethod = HttpMethod.PATCH;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
case "head":
httpMethod = HttpMethod.HEAD;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
case "options":
httpMethod = HttpMethod.OPTIONS;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
case "trace":
httpMethod = HttpMethod.TRACE;
responseEntity = restTemplate.exchange(url, httpMethod, requestEntity, String.class);
break;
default:
httpMethod = HttpMethod.GET;
URI uri;
try {
uri = new URI(url);
} catch (URISyntaxException e) {
log.error("url转uri异常,异常信息:{}", e.getMessage(), e);
throw new Exception("uri创建异常:" + e.getMessage());
}
responseEntity = restTemplate.exchange(uri, httpMethod, requestEntity, String.class);
}
return responseEntity;
}
package HTTP.http;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import java.net.URI;
public class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase {
public static final String METHOD_NAME = "DELETE";
@Override
public String getMethod() { return METHOD_NAME; }
public HttpDeleteWithBody(final String url) {
super();
setURI(URI.create(url));
}
public HttpDeleteWithBody(final URI url) {
super();
setURI(url);
}
public HttpDeleteWithBody() {
super();
}
}
HTTPS各类请求
package HTTP.https;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HttpsUtils {
/**
* 创建Https的GET请求
*
* @param host 请求前缀:https://或http://
* @param path 请求url
* @param headers 请求头
* @param querys 请求参数
* @return strResponse 返回结果
*/
public static String doHttpsGet(String host, String path, Map<String, Object> headers, Map<String, Object> querys) {
String strResponse = null;
HttpClient httpClient = null;
try {
httpClient = wrapClient(host);
HttpGet request = new HttpGet(buildUrl(host, path, querys));
if (headers.size() != 0) {
for (Map.Entry<String, Object> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue().toString());
}
}
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
}
} catch (Exception e) {
log.error("Get请求异常: ", e);
}
return strResponse;
}
/**
* 创建Https的POST请求
*
* @param host 请求前缀
* @param path 请求url
* @param headers 请求头
* @param querys 请求条件
* @param body 请求参数
* @return strResponse 返回结果
*/
public static String doHttpsPost(String host, String path, Map<String, Object> headers, Map<String, Object> querys,
String body) {
String strResponse = null;
try {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry<String, Object> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue().toString());
}
if (StringUtils.isNotBlank(body)) {
request.setEntity(new StringEntity(body, "utf-8"));
}
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
}
} catch (Exception e) {
log.error("https的Post请求异常: ", e);
}
return strResponse;
}
/**
* 创建Https的PUT请求
*
* @param host 请求前缀
* @param path 请求url
* @param headers 请求头
* @param querys 请求条件
* @param body 请求参数-----请求参数为string类型
* @return strResponse 返回结果
*/
public static String doPut(String host, String path, Map<String, String> headers, Map<String, Object> querys, String body) {
String strResponse = null;
try {
HttpClient httpClient = wrapClient(host);
HttpPut request = new HttpPut(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (StringUtils.isNotBlank(body)) {
request.setEntity(new StringEntity(body, "utf-8"));
}
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
}
} catch (Exception e) {
log.error("https的PUT请求异常: ", e);
}
return strResponse;
}
/**
* 创建Https的PUT请求
*
* @param host 请求前缀
* @param path 请求url
* @param headers 请求头
* @param querys 请求条件
* @param body 请求参数-----请求参数为流的形式
* @return strResponse 返回结果
*/
public static String doPut(String host, String path, Map<String, String> headers, Map<String, Object> querys, byte[] body) {
String strResponse = null;
try {
HttpClient httpClient = wrapClient(host);
HttpPut request = new HttpPut(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (body != null) {
request.setEntity(new ByteArrayEntity(body));
}
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
}
} catch (Exception e) {
log.info("https的PUT请求异常: ", e);
}
return strResponse;
}
/**
* 创建Https的DELETE请求
*
* @param host 请求前缀
* @param path 请求url
* @param headers 请求头
* @param querys 请求条件
* @return strResponse 返回结果
*/
public static String doDelete(String host, String path, String method, Map<String, String> headers,
Map<String, Object> querys) {
String strResponse = null;
try {
HttpClient httpClient = wrapClient(host);
HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
strResponse = EntityUtils.toString(responseEntity, "utf-8");
}
} catch (Exception e) {
log.error("https的DEL请求异常: ", e);
}
return strResponse;
}
/**
* 创建Https的POST的Form表单请求
*
* @param host 请求前缀:http:// 或 https://
* @param path 请求url:ip:port/url-->例:127.0.0.1:80/seal/seals
* @param headers 请求头
* @param querys 请求条件
* @param bodys 请求参数
* @return strResponse 返回结果
*/
public static String doPostForm(String host, String path, Map<String, String> headers,
Map<String, Object> querys, Map<String, String> bodys) {
String strResponse = null;
try {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (bodys != null) {
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
for (String key : bodys.keySet()) {
nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
formEntity.setContentType("application/form-data; charset=UTF-8");
request.setEntity(formEntity);
}
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
strResponse = EntityUtils.toString(responseEntity, "utf-8");
} catch (Exception e) {
log.error("POST的表单请求异常: ", e);
}
return strResponse;
}
private static HttpClient wrapClient(String host) {
HttpClient httpClient = new DefaultHttpClient();
if (host.startsWith("https://")) {
sslClient(httpClient);
}
return httpClient;
}
private static String buildUrl(String host, String path, Map<String, Object> querys) throws UnsupportedEncodingException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(host);
if (!StringUtils.isBlank(path)) {
sbUrl.append(path);
}
if (null != querys) {
StringBuilder sbQuery = new StringBuilder();
for (Map.Entry<String, Object> query : querys.entrySet()) {
if (0 < sbQuery.length()) {
sbQuery.append("&");
}
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue().toString())) {
sbQuery.append(query.getValue());
}
if (!StringUtils.isBlank(query.getKey())) {
sbQuery.append(query.getKey());
if (!StringUtils.isBlank(query.getValue().toString())) {
sbQuery.append("=");
sbQuery.append(URLEncoder.encode(query.getValue().toString(), "utf-8"));
}
}
}
if (0 < sbQuery.length()) {
sbUrl.append("?").append(sbQuery);
}
}
log.info("HTTPS请求URL:{}", sbUrl);
return sbUrl.toString();
}
private static void sslClient(HttpClient httpClient) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry registry = ccm.getSchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
public static Map<String, Object> getHeaders(String token) {
Map<String, Object> headers = new HashMap<>();
headers.put("Content-type", "application/json; charset=utf-8");
if (StringUtils.isNotBlank(token)) {
headers.put("Authorization", token);
}
return headers;
}
}
http对应maven依赖
<!-- http -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.2</version>
</dependency>
调取HTTPS接口异常情况
Unrecognized SSL message, plaintext connection?https异常
此异常可能导致原因调取https请求的url中的端口问题导致
注意:http请求默认端口为80,https请求默认端口为443。
443端口即网页浏览端口,主要用于https请求,80端口是浏览网页的默认端口,是提供加密和通过安全端口传输的另一种HTTP。
在一些对安全性要求较高的网站,比如银行、证券、购物等,都采用HTTPS服务,这样在这些网站上的交换信息,
其他人抓包获取到的是加密数据,保证了交易的安全性。网页的地址以https://开始,而不是常见的http://
Get请求与POST请求
GET和POST请求的区别
1. 最直观的区别就是Get把参数包含在url中,post通过request body(请求体)传递参数。
2. get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息
3. get在浏览器回退时是无害的,而post会再次提交请求
4. get请求只能进行url编码,而post可以进行多种形式的编码
5. get请求参数会被浏览器完整的记录下来保留在历史记录里,而post参数不会被保留
6. get请求在url中传送的参数是有长度限制的,而post没有(浏览器导致)
7. 对参数的类型,get只接受ASCII码字符,而post没有限制。
异常情况
当springboot与springcloud配套使用时,版本过低会导致post不支持表单请求
解决方案,提高springboot和springcloud配套版本,如springboot版本为2.2.4.RELEASE,springCloud版本为Hoxton.SR1
项目中使用webflux导致接口不能使用@RequestParam注解问题
原因:webflux:1)get请求支持@RequestParam
2)post请求支持@RequestBody
3)表单请求支持@RequestPart:文件:FilePart,flux<FilePart>
请求头:ServerHttpRequest
web: 请求头:HttpServletRequest