这几天在研发公司自用的excel校验工具,需要将后台存储的excel通过http传递到excel校验服务端同时传递相关的参数,查询网上的解决方案并没有适合的,这里结合网上提供的解决方案给出我自己的解决办法:
Http传输工具类方法:
/**
* 文件上传
* @param httpUrl 文件上传的url
* @param uploadFilePath 需要上传的文件
* @param params 传递的参数
* @return
*/
@SuppressWarnings("finally")
public static String uploadFile(String httpUrl, String uploadFilePath, Map<String, String> params) {
String end = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
DataOutputStream ds = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
StringBuffer resultBuffer = new StringBuffer();
String tempLine = null;
try {
// 统一资源
URL url = new URL(httpUrl);
// 连接类的父类,抽象类
URLConnection urlConnection = url.openConnection();
// http的连接类
HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
// 设置是否从httpUrlConnection读入,默认情况下是true;
httpURLConnection.setDoInput(true);
// 设置是否向httpUrlConnection输出
httpURLConnection.setDoOutput(true);
// Post 请求不能使用缓存
httpURLConnection.setUseCaches(false);
// 设定请求的方法,默认是GET
httpURLConnection.setRequestMethod("POST");
// 设置字符编码连接参数
httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
// 设置字符编码
httpURLConnection.setRequestProperty("Charset", "UTF-8");
// 设置请求内容类型
httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
// 设置DataOutputStream
ds = new DataOutputStream(httpURLConnection.getOutputStream());
String uploadFile = uploadFilePath;
String filename = uploadFile;
//======传递文件======
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data; " + "name=\"excel" + "\";filename=\"" + filename
+ "\"" + end);
ds.writeBytes(end);
FileInputStream fStream = new FileInputStream(uploadFile);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length = -1;
while ((length = fStream.read(buffer)) != -1) {
ds.write(buffer, 0, length);
}
ds.writeBytes(end);
//======传递文件end======
//======传递参数======
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data; " + "name=\"param" + "\";filename=\"" + params.toString()
+ "\"" + end);
ds.writeBytes(end);
ds.writeBytes(end);
//======传递参数end======
fStream.close();
ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
ds.flush();
if (httpURLConnection.getResponseCode() >= 300) {
throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
}
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = httpURLConnection.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
reader = new BufferedReader(inputStreamReader);
tempLine = null;
resultBuffer = new StringBuffer();
while ((tempLine = reader.readLine()) != null) {
resultBuffer.append(tempLine);
resultBuffer.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ds != null) {
try {
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultBuffer.toString();
}
}
校验服务端部分代码:
/**
* excelFormatCheck
* @param file
* @param param
* @return
*/
@PostMapping("excelFormatCheck")
public Object excelFormatCheck(@RequestParam(value = "excel", required = false) MultipartFile file, @RequestParam(value = "param", required = false) MultipartFile param) {
Map<String, Object> result = new HashMap<>();
Map<String, List<String>> validateResult = new HashMap();
List<List<String>> validateResultLists = new ArrayList<>();
try {
if (null != file && !file.isEmpty()) {
Gson gson = new Gson();
Map<String, String> mapParams = new HashMap<String, String>();
mapParams = gson.fromJson(param.getOriginalFilename(), mapParams.getClass());//转换传递的参数
String templateId = mapParams.get("templateId");//获取模板id
result.put("code", 1);
result.put("msg", "excel校验完成");
} else {
result.put("code", -2);
result.put("msg", "未上传excel");
}
} catch (Exception e) {
e.printStackTrace();
result.put("code", -1);
result.put("msg", "excel校验接口异常");
}
return result;
}
测试方法:
public static void main(String[] args) {
String path = "F:/aa.xls";
Map<String, String> map = new HashMap<>();
map.put("templateId", "aa-dsa");
String result = uploadFile("http://localhost:8002/exCheck/excelValidateCtl/excelFormatCheck", path, map);
System.out.println(result);
}
总结下简单说就是一旦我们将Content-Type设置为multipart/form-data原先通过k-v获取参数的方式就不再可行,因此这里除了传递真实的文件外,再传递一个仅记录文件名即所需传递参数的空文件,然后在服务端通过获取文件的文件名然后将其解析成参数即可。