直接用 jdk 的 HttpURLConnection 上传文件,通过模拟 post 提交方法
具体代码如下:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
/**
* http 网络访问工具
*
* @author wonderful.
* @version 3.0.0
*/
public class HttpClient {private final static Logger LOGGER = Logger.getLogger(HttpClient.class);
private String method = null;
private String CONTENT_TYPE = null; // 默认
/**
* 默认 POST
*
* @return String
*/
public String getMethod() {if (method == null) {return "POST";}
return method;
}
/**
* POST 或 GET
*
* @param method .
*/
public void setMethod(String method) {this.method = method;}
/**
* 执行调用 serviceURL 地址 方法
* @param serviceURL webService 地址.
* @param param String.
* @param ContentType 请求的与实体对应的 MIME 信息 如:Content-Type: application/x-www-form-urlencoded,application/json,application/xml
* @return String.
*/
public String pub(String serviceURL, String param,String contentType) {
CONTENT_TYPE = contentType;
return pub(serviceURL,param);
}
/**
* 执行调用 serviceURL 地址 方法
* @param serviceURL webService 地址.
* @param param String.
* @return String.
*/
public String pub(String serviceURL, String param) {
URL url = null;
HttpURLConnection connection = null;
StringBuffer buffer = new StringBuffer();
LOGGER.info("request:" + serviceURL + "?" + param);
try {url = new URL(serviceURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod(getMethod());
connection.setConnectTimeout(5000);//30 秒连接
connection.setReadTimeout(5*60*1000);// 5 分钟读数据
connection.setRequestProperty("Content-Length", param.length() + "");
if(CONTENT_TYPE != null){connection.setRequestProperty("Content-Type", CONTENT_TYPE);
}
OutputStream outputStream = connection.getOutputStream();
outputStream.write(param.getBytes("UTF-8"));
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line = "";
while ((line = reader.readLine()) != null) {buffer.append(line);
}
reader.close();} catch (IOException e) {LOGGER.error(e);
} finally {if (connection != null) {connection.disconnect();
}
}
LOGGER.info("response:" + buffer.toString());
return buffer.toString();}
/**
* 上传文件
*
* @param serviceURL
* @param textMap
* 表单参数
* @param fileMap
* 文件参数
* @return
* @throws IOException
*/
public static String formUpload(String serviceURL, Map<String, String> textMap, Map<String, String> fileMap) throws IOException {Map<String, LinkedHashSet<String>> tempMap = new HashMap<>();
if (!Objects.isNull(fileMap) && !fileMap.isEmpty()) {Iterator<Map.Entry<String, String>> iter = fileMap.entrySet().iterator();
while (iter.hasNext()) {Map.Entry<String, String> entry = iter.next();
String inputName = entry.getKey();
String inputValue = entry.getValue();
if (StringUtils.isAnyBlank(inputName, inputValue)) {continue;}
LinkedHashSet<String> values = new LinkedHashSet<>();
values.add(inputValue);
tempMap.put(inputName, values);
}
}
return formUploadMulti(serviceURL, textMap, tempMap);
}
/**
* 上传文件, 允许同一个属性上传多个文件
*
* @param serviceURL
* @param textMap
* 表单参数
* @param fileMap
* 文件参数
* @return
* @throws IOException
*/
public static String formUploadMulti(String serviceURL, Map<String, String> textMap, Map<String, LinkedHashSet<String>> fileMap) throws IOException {LOGGER.trace(String.format("调用文件上传,传入参数:serviceURL=%s,textMap=%s,fileMap=%s", serviceURL, textMap, fileMap));
String res = "";
HttpURLConnection conn = null;
OutputStream out = null;
BufferedReader reader = null;
String BOUNDARY = "---------------------------" + System.currentTimeMillis(); // boundary 就是 request 头和上传文件内容的分隔符
try {URL url = new URL(serviceURL);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);// 30 秒连接
conn.setReadTimeout(5 * 60 * 1000);// 5 分钟读数据
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
out = new DataOutputStream(conn.getOutputStream());
// text
if (!Objects.isNull(textMap) && !textMap.isEmpty()) {StringBuffer strBuf = new StringBuffer();
Iterator<Map.Entry<String, String>> iter = textMap.entrySet().iterator();
while (iter.hasNext()) {Map.Entry<String, String> entry = iter.next();
String inputName = entry.getKey();
String inputValue = entry.getValue();
if (StringUtils.isAnyBlank(inputName, inputValue)) {continue;}
strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
strBuf.append(inputValue);
}
out.write(strBuf.toString().getBytes());
}
// file
if (!Objects.isNull(fileMap) && !fileMap.isEmpty()) {Iterator<Entry<String, LinkedHashSet<String>>> iter = fileMap.entrySet().iterator();
while (iter.hasNext()) {Entry<String, LinkedHashSet<String>> entry = iter.next();
String inputName = entry.getKey();
LinkedHashSet<String> inputValue = entry.getValue();
if (StringUtils.isAnyBlank(inputName) || inputValue.isEmpty()) {continue;}
for (String filePath : inputValue) {File file = new File(filePath);
String filename = file.getName();
Path path = Paths.get(filePath);
String contentType = Files.probeContentType(path);
StringBuffer strBuf = new StringBuffer();
strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\""+ filename +"\"\r\n");
strBuf.append("Content-Type:" + contentType + "\r\n\r\n");
LOGGER.trace(String.format("filename:%s,contentType:%s", filename, contentType));
out.write(strBuf.toString().getBytes());
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {out.write(bufferOut, 0, bytes);
}
in.close();}
}
}
byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
out.write(endData);
out.flush();
// 读取返回数据
LOGGER.trace(String.format("http 返回状态:ResponseCode=%s,ResponseMessage=%s", conn.getResponseCode(), conn.getResponseMessage()));
StringBuffer strBuf = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {strBuf.append(line).append("\n");
}
res = strBuf.toString();
LOGGER.trace(String.format("http 返回数据:%s", res));
reader.close();
reader = null;
} catch (IOException e) {throw e;} finally {if (!Objects.isNull(out)) {out.close();
out = null;
}
if (!Objects.isNull(reader)) {reader.close();
reader = null;
}
if (conn != null) {conn.disconnect();
conn = null;
}
}
return res;
}
}
上面的两个方法有待优化,未处理