提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
最近遇到一个给第三方系统上传和下载的需求,第三方只作为服务方,这里记录一下(非前端调用)。
下载-如需要拿到某业务信息,包括附件也需要下载
上传-审批的结果需要推送给第三方,其中也包括附件
/**
* 上传文件
* request: {"sign":"B85FB491665FAFBB7C5F3377BDBE986C","fileCount":"2"}
* requestBody: ["D:\\LZH\\Desktop\\2023年1月28日设计批复通过.xlsx","D:\\LZH\\Desktop\\2023年1月28日设计批复通过2.xlsx"]
* response:[{"fileName":"2023年1月28日设计批复通过.xlsx","size":57191,"remark":"上传成功","id":"6f8a2755-0c00-4f40-ac94-705cfe8e4d7e","uuid":"6f8a2755-0c00-4f40-ac94-705cfe8e4d7e","url":"http://127.0.0.1/cmsr/6f8a2755-0c00-4f40-ac94-705cfe8e4d7e"},{"errorIndex":1,"remark":"上传失败"}]
*
*/
@RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
public String uploadFile(HttpServletRequest request) {
Map<String,Object> result = new HashMap<>();
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
final int fileCount = Integer.parseInt(request.getParameter("fileCount"));
List<Map<String,Object>> list=new ArrayList<>(fileCount);
for (int i = 0; i < fileCount; i++) {
MultipartFile file = multipartRequest.getFile("file"+i);// 获取上传文件对象
Map<String,Object> map = new HashMap<>();
try {
// 上传并返回新文件名称
String uuid = FileUploadUtils.upload(file, "xcall");
final Optional<Attachment> attOptional = Attachment.findByUuid(uuid);
if (attOptional.isEmpty()) {
throw new Exception("上传失败");
}
Attachment att = attOptional.get();
String url = serverConfig.getUrl() + "/" + uuid;
map.put("id", uuid);
map.put("uuid", uuid);
map.put("fileName", att.getName());
map.put("size", att.getLength());
map.put("url", url);
map.put("remark", "上传成功");
} catch (Exception e) {
map.put("remark", "上传失败");
map.put("errorIndex", i);
log.error("XCallController uploadFile e:",e);
}
list.add(map);
}
result.put("attachment",list);
return JSON.toJSONString(list);
// return JSON.toJSONString(result);
}
List<SysFile> sysFiles = fileService.listByIds(ids);
List<File> files = new ArrayList<>(sysFiles.size());
for (SysFile f : sysFiles) {
File file = new File(aPath +File.separator+f.getPath());
files.add(file);
}
HashMap<String, String> body = new HashMap<>();
body.put("fileCount", String.valueOf(files.size()));
body.put("sign", getMd5(body));
HashMap<String, Object> headers = new HashMap<>();
String result = HttpUtils.httpPostByFile(a.getHost()+"/uploadFile", body, headers, files);
o.setReportFiles(result);
log.info("uploadFile result:"+result);
代码如下(示例):
/**
* 下载文件
*/
@RequestMapping(value = "/downloadFile",method = RequestMethod.GET)
public void downloadFile(@RequestParam("uuid") String uuid, HttpServletResponse response) {
try {
Attachment attachment = Attachment.findByUuid(uuid).get();
String filePath = a.getProfile() + attachment.getPath();
response.setHeader("fileName", URLEncoder.encode(attachment.getName(), StandardCharsets.UTF_8));
response.setHeader("uuid",attachment.getUuid()+"");
FileUtils.writeBytes(filePath, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
代码如下(示例):
/**
* 下载附件
*
* @return
*/
public void downloadFile(ReportRecord r) {
List<Map<String ,String>>files=new ArrayList<>();
List<SysFile>list=new ArrayList<>();
for (String uuid : r.getFileIds().split(",")) {
try {
HashMap<String, String> params = new HashMap<>();
params.put("uuid", uuid);
params.put("sign", getMd5(params));
HashMap<String, Object> headers = new HashMap<>();
final Map<String, Object> resultMap = HttpUtils.httpGet(xcall.getHost()+"cmsr/report/downloadFile", params, headers);
String id = IdUtil.getSuid();
final String fileName = resultMap.getOrDefault("fileName",id).toString();
String ext = fileName.substring(fileName.lastIndexOf('.'));
// 1 先上传文件
String path = upload((byte[]) resultMap.get("bytes"), id + ext);//以id为文件名保证不重复
// 2 建立SysFile数据
SysFile sysFile = new SysFile();
sysFile.setId(id);
sysFile.setName(fileName);
sysFile.setUploader("ordinary");
sysFile.setPath(path);
list.add(sysFile);
Map<String ,String> f=new HashMap<>(2);
f.put("id",id);
f.put("name",fileName);
files.add(f);
} catch (Exception e) {
r.putRemark("附件下载失败,uuid:"+uuid);
}
}
r.setAccessory(JSON.toJSONString(files));
fileService.saveBatch(list);
}
public String upload(byte[] bytes, String name) {
String path = getPath(name);
String fullPath = xbpmRootPath + File.separator + path;
// FileUtil.writeFromStream(is, fullPath);
FileUtil.writeBytes(bytes,fullPath);
return path;
}
private static CloseableHttpClient httpClient;
static {
try {
SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
RequestConfig config = RequestConfig.custom().setConnectTimeout(10000).setSocketTimeout(10000).build();
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String httpPostByFile(String url, Map<String, String> body, Map<String, Object> headers, List<File> files) {
String result = "";
try {
HttpPost httpPost = new HttpPost(url);
for (Map.Entry<String, Object> header : headers.entrySet()) {
httpPost.setHeader(header.getKey(), String.valueOf(header.getValue()));
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
// 设置请求的编码格式
builder.setCharset(Consts.UTF_8);
builder.setContentType(ContentType.MULTIPART_FORM_DATA);
// 添加文件,也可以添加字节流
// builder.addBinaryBody("file", files);
//或者使用字节流也行,根据具体需要使用
for (int i = 0; i < files.size(); i++) {
try {
builder.addBinaryBody("file"+i, Files.readAllBytes(files.get(i).toPath()), ContentType.APPLICATION_OCTET_STREAM,files.get(i).getName());
} catch (IOException e) {
log.error("httpPostByFile 文件不存在 e:",e);
}
}
// 或者builder.addPart("file",new FileBody(file));
for (Map.Entry<String, String> map : body.entrySet()) {
builder.addTextBody(map.getKey(), map.getValue());
}
HttpEntity reqEntity = builder.build();
httpPost.setEntity(reqEntity);
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
}
EntityUtils.consume(entity);
response.close();
return result;
} catch (Exception e) {
e.printStackTrace();
log.error("发送http请求异常 e:",e);
return "";
}
}
public static Map<String, Object> httpGet(String url, Map<String, String> params, Map<String, Object> headers) {
HttpGet httpGet;
Map<String,Object> map=new HashMap<>();
try {
List<NameValuePair> nameValuePairArrayList = new ArrayList<>();
if (params != null) {
for (Map.Entry<String, String> param : params.entrySet()) {
nameValuePairArrayList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
}
}
//参数转换为字符串
String paramsStr = EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairArrayList, StandardCharsets.UTF_8));
httpGet = new HttpGet(url + "?" + paramsStr);
for (Map.Entry<String, Object> header : headers.entrySet()) {
httpGet.setHeader(header.getKey(), String.valueOf(header.getValue()));
}
CloseableHttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
entity.writeTo(outputStream);
// final long copy = IoUtil.copy(inputStream, outputStream);
final byte[] bytes = outputStream.toByteArray();
// FileUtil.writeBytes(bytes,"D:\\data\run\\dy_admin\\upload\\xcall\\2023\\02\\23\\a.xlsx");
// FileUtil.writeBytes(bytes,"D:\\LZH\\Desktop\\2023年1月28日设计批复通过4.xlsx");
map.put("bytes",bytes);
map.put("fileName", URLDecoder.decode(response.getHeaders("filename")[0].getValue(), StandardCharsets.UTF_8));
map.put("uuid", response.getHeaders("uuid")[0].getValue());
EntityUtils.consume(entity);
response.close();
} catch (Exception e) {
log.error("发送http请求异常 e:",e);
}
return map;
}
1.上传是批量进行的,如果文件过大会导致内存问题吧
2.上传下载没有重试机会,一旦因为网络或者其他不可控因素导致中断