springmvc http请求,支持get,post,附件传输和参数传输
主要解决http请求支持get,post,put,delete等常规方法,支持@RequestParam,@RequestBody,@PathVariable等参数格式传输,支持传输附件同时传递参数等,主体代码如下:
package mes.client.action;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import mes.client.pojo.po.CommonEntityPo;
import mes.client.pojo.vo.ResponseInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class MesMomConnectAction {
private static Logger logger = LoggerFactory.getLogger(MesMomConnectAction.class);
/**
* 无请求体body,向指定URL发送方法的请求
*
* @param url 发送请求的URL
* @return URL 所代表远程资源的响应结果
*/
public static ResponseInfo getHttpParamReq(String url,String requestMethodType) {
StringBuilder result = new StringBuilder();
BufferedReader in = null;
HttpURLConnection connection = null;
try {
URL getUrl = new URL(url);
// 打开和URL之间的连接
connection = (HttpURLConnection) getUrl.openConnection();
// 在connect之前,设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.setRequestProperty("Charsert", "UTF-8");
//添加必须的头部信息
addHeader(connection);
// 配置本次连接的Content-type,form表单是"application/x-www-form-urlencoded",json是"application/json"等
// 根据需求自己调整Content-type
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 设置连接主机服务器的超时时间:15000毫秒
connection.setConnectTimeout(15000);
// 设置读取远程返回的数据时间:60000毫秒
connection.setReadTimeout(60000);
// 设置连接方式:get
connection.setRequestMethod(requestMethodType);
// 建立实际的连接,可不写,注意connection.getOutputStream会隐含的进行connect。
connection.connect();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
ResponseInfo responseInfo = JSON.parseObject(result.toString(), ResponseInfo.class);
if(responseInfo.getStatusCode() == null){
return getFailResponse(result.toString());
}
return responseInfo;
} catch (Exception e) {
logger.error("调用MES4.0接口异常",e);
return getExceptionResponse(e);
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
if (connection != null) {
//关闭连接
connection.disconnect();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
/**
* @description: get请求
* @date: 2023-10-16 16:58:30
* @param url
* @return ResponseInfo
*/
public static ResponseInfo sendGet(String url){
return getHttpParamReq(url,"GET");
}
/**
* @description:方法说明
* @date: 2023-10-16 15:42:33
* @param url
* @return ResponseInfo
*/
public static ResponseInfo sendDelete(String url) {
return getHttpParamReq(url,"DELETE");
}
/**
* @description: post请求
* @date: 2023-10-16 17:04:07
* @param url
* @param param
* @return ResponseInfo
*/
public static ResponseInfo sendPost(String url, CommonEntityPo param){
return getHttpBodyReq(url,param,"POST");
}
/**
* @description: put请求
* @date: 2023-10-16 17:05:05
* @param url
* @param param
* @return ResponseInfo
*/
public static ResponseInfo sendPut(String url, CommonEntityPo param){
return getHttpBodyReq(url,param,"PUT");
}
/**
* 有请求体body,向指定 URL 发送方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数。
* @return 所代表远程资源的响应结果
*/
public static ResponseInfo getHttpBodyReq(String url, CommonEntityPo param, String requestMethodType) {
BufferedReader in = null;
InputStream inputStream = null;
HttpURLConnection connection = null;
StringBuilder result = new StringBuilder();
try {
URL postUrl = new URL(url);
// 打开和URL之间的连接
connection = (HttpURLConnection) postUrl.openConnection();
// 在connect之前,设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.setRequestProperty("Charsert", "UTF-8");
//添加一些必要的请求头信息
addHeader(connection);
//connection.setRequestProperty("Authorization","Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJiUlR5WGJ0Q05aaS1fUkVKSGUwNHNEd2RYaTNVSHRLOWZoWndXdGdPdWdNIn0.eyJleHAiOjE2OTc0MzM5NDksImlhdCI6MTY5NzAwMTk0OSwiYXV0aF90aW1lIjoxNjk2NzYwOTcxLCJqdGkiOiJiMjcyYzM2My1kMDQ1LTRhMTAtOTc5Ni0xZGE0ZmYwNDkxYTkiLCJpc3MiOiJodHRwOi8vaWRtLWRldi5zdW53b2RhLWV2Yi5jb20vYXV0aC9yZWFsbXMvc3RhbmRhcmQiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmIxOTE4NWYtODcxZi00NTk1LWIxZTUtYTIwZTQ1MzcyZjQ3IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibnRzLWZyb250LXRlc3QiLCJub25jZSI6Ijc3MjBkM2QyLTg3NDQtNDI3Yy1iMzBhLTE5YWU2ZDM5NzY3NiIsInNlc3Npb25fc3RhdGUiOiJhNDJlNzU0ZC04MmRjLTQxNTgtOWQyYi1iZWZkNzNmMGI4NzUiLCJhY3IiOiIwIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoi6IuP5pWPIiwicHJlZmVycmVkX3VzZXJuYW1lIjoieHdkMTYiLCJnaXZlbl9uYW1lIjoi6IuP5pWPIiwibG9jYWxlIjoiemgtQ04ifQ.AUnf5meZWqYNYbfbzyqY3C9WoiL-ISCoVebvtJV-1EF8iQe2FXVEE22CLKnTvHBEoY-W62F8LtG3eW3B5LP54WBXq0JyxnMSLTjqZWMfvYmxNLfjO3rcviK9jAqqxrvLy1IR4ZVFz8ez4ThfCr3TrbammQvZgxF1jie_hx_-3RTiLTra1qyTUj8CrFRaVDBvWTt8nDu6FsRBAkqImPgZ3Jdhf-WDeVlwOkDCGPd5cUQ9KAQs2JUMY4H_jC9cgcSpQuUjNOQOnu1lnYjnsREswR7iBNSkaW6DlRry-HhD8FRs1QLOwKGcgFCBU7O9O-NCH8EyrZOriSpiPaElE2-i2Q");
connection.setConnectTimeout(15000);
connection.setReadTimeout(60000);
// 发送POST请求必须设置如下两行,参数要放在http正文内
connection.setDoOutput(true);
connection.setDoInput(true);
// 默认是 GET方式
connection.setRequestMethod(requestMethodType);
// Post 请求不使用缓存
connection.setUseCaches(false);
// 配置连接的Content-type,form表单是"application/x-www-form-urlencoded",json是"application/json"等
connection.setRequestProperty("Content-Type", "application/json");
connection.connect();
//参数处理
if(param != null){
//打印接口入参
logger.info("post请求接口入参:{}",JSON.toJSONString(param.getData()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
writer.write(JSON.toJSONString(param.getData()));
writer.close();
}
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
ResponseInfo responseInfo = JSON.parseObject(result.toString(), ResponseInfo.class);
if(responseInfo.getStatusCode() == null){
return getFailResponse(result.toString());
}
return responseInfo;
} catch (Exception e) {
logger.error("调用MES4.0接口异常",e);
return getExceptionResponse(e);
} finally {
try {
if (in != null) {
in.close();
}
if(inputStream != null){
inputStream.close();
}
if (connection != null) {
//关闭连接
connection.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/*public static void main(String[] args) throws IOException {
//=========================================邮箱==================================================
List<Map<String, Object>> files = new ArrayList<>();
Map<String, Object> map = new HashMap();
File file = new File("C:\\Users\\86188\\Desktop\\t1.png");
map.put("name", "t1.png");
map.put("file", file);
files.add(map);
Map<String, Object> param = new HashMap();
param.put("data", "data");
sendFileUrl("http://127.0.0.1:8080/sendReport", files, param);
}*/
/**
* @description: 有附件和参数的发送方法的请求(调用方式参考实例如上方法)
* @date: 2023-10-23 10:41:40
* @param actionUrl :请求链接url
* @param files : 附件
* @param param :请求参数
* @return ResponseInfo
*/
public static void sendFileUrl(String actionUrl, List<Map<String, Object>> files, Map<String, Object> param){
HttpURLConnection conn = null;
DataOutputStream outStream = null;
try {
final String NEWLINE = "\r\n";
String BOUNDARY = java.util.UUID.randomUUID().toString();
String PREFIX = "--", LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
URL uri = new URL(actionUrl);
conn = (HttpURLConnection) uri.openConnection();
conn.setConnectTimeout(15000);
conn.setReadTimeout(60000);
conn.setDoInput(true);// 允许输入
conn.setDoOutput(true);// 允许输出
conn.setUseCaches(false);
conn.setRequestMethod("POST"); // Post方式
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Accept", "application/json;charset=UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
+ ";boundary=" + BOUNDARY);
outStream = new DataOutputStream(
conn.getOutputStream());
// 获取表单中上传控件之外的控件数据,写入到输出流对象(根据上面分析的抓包的内容格式拼凑字符串);
if (param != null && !param.isEmpty()) { // 这时请求中的普通参数,键值对类型的,相当于上面分析的请求中的username,可能有多个
for (Map.Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey(); // 键,相当于上面分析的请求中的username
Object value = param.get(key); // 值,相当于上面分析的请求中的sdafdsa
outStream.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线,就是前缀+分界线+换行
outStream.writeBytes("Content-Disposition: form-data; "
+ "name=\"" + key + "\"" + NEWLINE); // 拼接参数名,格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键,别忘了最后的换行
outStream.writeBytes(NEWLINE); // 空行,一定不能少,键和值之间有一个固定的空行
outStream.write(value.toString().getBytes("UTF-8")); // 将值写入,用字节流防止乱码
// 或者写成:dos.write(value.toString().getBytes(charset));
outStream.writeBytes(NEWLINE); // 换行
}
}
// 发送文件数据
if (files != null)
for (Map<String, Object> file : files) {
StringBuilder sb1 = new StringBuilder();
sb1.append(PREFIX);
sb1.append(BOUNDARY);
sb1.append(LINEND);
sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\""
+ file.get("name") + "\"" + LINEND);
sb1.append("Content-Type: application/octet-stream; charset="
+ CHARSET + LINEND);
sb1.append(LINEND);
outStream.write(sb1.toString().getBytes("utf-8")); //getBytes()不加utf-8 传输中文名附件时,接收附件的地方解析文件名会乱码
InputStream is = new FileInputStream((File) file.get("file"));
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
outStream.write(LINEND.getBytes());
}
// 请求结束标志
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(end_data);
outStream.flush();
// 得到响应码
int res = conn.getResponseCode();
//if (res == 200) {
InputStream in = conn.getInputStream();
InputStreamReader isReader = new InputStreamReader(in,"UTF-8");
BufferedReader bufReader = new BufferedReader(isReader);
String line = "";
String data = "";
while ((line = bufReader.readLine()) != null) {
data += line;
}
logger.info("读取后最后结果:" + data);
//}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭流
if(outStream != null){
outStream.close();
}
//关闭连接
if(conn != null){
conn.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//multipartFile格式文件发送
public static void sendMultipartFileUrl(String actionUrl, MultipartFile file, Map<String, Object> param){
HttpURLConnection conn = null;
DataOutputStream outStream = null;
try {
final String NEWLINE = "\r\n";
String BOUNDARY = java.util.UUID.randomUUID().toString();
String PREFIX = "--", LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
URL uri = new URL(actionUrl);
conn = (HttpURLConnection) uri.openConnection();
conn.setConnectTimeout(15000);
conn.setReadTimeout(60000);
conn.setDoInput(true);// 允许输入
conn.setDoOutput(true);// 允许输出
conn.setUseCaches(false);
conn.setRequestMethod("POST"); // Post方式
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Accept", "application/json;charset=UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
+ ";boundary=" + BOUNDARY);
outStream = new DataOutputStream(
conn.getOutputStream());
// 获取表单中上传控件之外的控件数据,写入到输出流对象(根据上面分析的抓包的内容格式拼凑字符串);
if (param != null && !param.isEmpty()) { // 这时请求中的普通参数,键值对类型的,相当于上面分析的请求中的username,可能有多个
for (Map.Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey(); // 键,相当于上面分析的请求中的username
Object value = param.get(key); // 值,相当于上面分析的请求中的sdafdsa
outStream.writeBytes(PREFIX + BOUNDARY + NEWLINE); // 像请求体中写分割线,就是前缀+分界线+换行
outStream.writeBytes("Content-Disposition: form-data; "
+ "name=\"" + key + "\"" + NEWLINE); // 拼接参数名,格式就是Content-Disposition: form-data; name="key" 其中key就是当前循环的键值对的键,别忘了最后的换行
outStream.writeBytes(NEWLINE); // 空行,一定不能少,键和值之间有一个固定的空行
outStream.write(value.toString().getBytes("UTF-8")); // 将值写入,用字节流防止乱码
// 或者写成:dos.write(value.toString().getBytes(charset));
outStream.writeBytes(NEWLINE); // 换行
}
}
// 发送文件数据
if (file != null){
StringBuilder sb1 = new StringBuilder();
sb1.append(PREFIX);
sb1.append(BOUNDARY);
sb1.append(LINEND);
sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\""
+ file.getOriginalFilename() + "\"" + LINEND);
sb1.append("Content-Type: application/octet-stream; charset="
+ CHARSET + LINEND);
sb1.append(LINEND);
outStream.write(sb1.toString().getBytes("utf-8")); //getBytes()不加utf-8 传输中文名附件时,接收附件的地方解析文件名会乱码
InputStream is = file.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
outStream.write(LINEND.getBytes());
}
// 请求结束标志
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(end_data);
outStream.flush();
// 得到响应码
int res = conn.getResponseCode();
//if (res == 200) {
InputStream in = conn.getInputStream();
InputStreamReader isReader = new InputStreamReader(in,"UTF-8");
BufferedReader bufReader = new BufferedReader(isReader);
String line = "";
String data = "";
while ((line = bufReader.readLine()) != null) {
data += line;
}
logger.info("读取后最后结果:" + data);
//}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭流
if(outStream != null){
outStream.close();
}
//关闭连接
if(conn != null){
conn.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* @description: 需要额外添加一些请求头信息
* @date: 2023-10-11 14:42:07
*/
private static void addHeader(HttpURLConnection connection){
//针对一些第三方系统加密header
}
/**
* @description: 返回请求异常信息
* @date: 2023-10-15 17:43:36
* @param e
* @return ResponseInfo
*/
private static ResponseInfo getExceptionResponse(Exception e){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
String failMsg = baos.toString();
return getFailResponse(failMsg);
}
/**
* @description: 封装返回信息结果
* @date: 2023-10-19 19:44:23
* @param failMsg
* @return ResponseInfo
*/
private static ResponseInfo getFailResponse(String failMsg){
ResponseInfo responseInfo = new ResponseInfo();
responseInfo.setStatusCode(400);
responseInfo.setMessage(failMsg);
return responseInfo;
}
}