2024年5月27日 新增切片上传,兼容ftp
This commit is contained in:
parent
eccafa4eee
commit
81a838bc03
|
@ -241,6 +241,48 @@ public class KcKetangbiaoController extends JeecgController<KcKetangbiao, IKcKet
|
||||||
return Result.OK(pageList);
|
return Result.OK(pageList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/getBizPath")
|
||||||
|
public Result<?> getBizPath(String rwbh, String xqxn, String wjlx, String kkdw, String kcmc, String skjs) {
|
||||||
|
Result<String> r = new Result<>();
|
||||||
|
if(StringUtils.isNotBlank(rwbh) && StringUtils.isNotBlank(xqxn) && StringUtils.isNotBlank(wjlx)) {
|
||||||
|
//根据任务编号查询80%数据
|
||||||
|
QueryWrapper<KcKetangbiao> qw = new QueryWrapper<>();
|
||||||
|
qw.last("limit 1");
|
||||||
|
KcKetangbiao ketangbiao = kcKetangbiaoService.getOne(qw);
|
||||||
|
String sb = xqxn + "/" +
|
||||||
|
ketangbiao.getKkdw() + "/" +
|
||||||
|
ketangbiao.getKcmc() + "/" +
|
||||||
|
ketangbiao.getSkjs() + "/" +
|
||||||
|
wjlx;
|
||||||
|
r.setResult(sb);
|
||||||
|
}else{
|
||||||
|
if(StringUtils.isNotBlank(xqxn) && StringUtils.isNotBlank(wjlx) && StringUtils.isNotBlank(kkdw) && StringUtils.isNotBlank(kcmc) && StringUtils.isNotBlank(skjs)){
|
||||||
|
String sb = xqxn + "/" +
|
||||||
|
kkdw + "/" +
|
||||||
|
kcmc + "/" +
|
||||||
|
skjs + "/" +
|
||||||
|
wjlx;
|
||||||
|
r.setResult(sb);
|
||||||
|
}else{
|
||||||
|
r.setSuccess(false);
|
||||||
|
r.setMessage("缺少关键参数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//rwbh
|
||||||
|
//xqxn
|
||||||
|
//学期学年不能为空
|
||||||
|
//kkdw
|
||||||
|
//开课单位不能为空
|
||||||
|
//kcmc
|
||||||
|
//课程名称不能为空
|
||||||
|
//skjs
|
||||||
|
//授课教师不能为空
|
||||||
|
//wjlx
|
||||||
|
//文件类型不能为空
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加
|
* 添加
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FastByteArrayOutputStream;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.fileupload.FileItem;
|
||||||
|
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.SymbolConstant;
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
|
@ -13,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.http.server.ServletServerHttpRequest;
|
import org.springframework.http.server.ServletServerHttpRequest;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
@ -20,6 +29,7 @@ import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
@ -27,7 +37,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.util.Map;
|
import java.nio.file.Files;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -77,7 +89,7 @@ public class CommonController {
|
||||||
|
|
||||||
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
||||||
if (oConvertUtils.isNotEmpty(bizPath)) {
|
if (oConvertUtils.isNotEmpty(bizPath)) {
|
||||||
if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
|
if (bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)) {
|
||||||
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,6 +97,25 @@ public class CommonController {
|
||||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||||
// 获取上传文件对象
|
// 获取上传文件对象
|
||||||
MultipartFile file = multipartRequest.getFile("file");
|
MultipartFile file = multipartRequest.getFile("file");
|
||||||
|
|
||||||
|
savePath = upload(bizPath, file);
|
||||||
|
if(oConvertUtils.isNotEmpty(savePath)){
|
||||||
|
result.setMessage(savePath);
|
||||||
|
result.setSuccess(true);
|
||||||
|
}else {
|
||||||
|
result.setMessage("上传失败!");
|
||||||
|
result.setSuccess(false);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 文件上传统一方法
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String upload(String bizPath, MultipartFile file) throws Exception {
|
||||||
|
String savePath = "";
|
||||||
if(oConvertUtils.isEmpty(bizPath)){
|
if(oConvertUtils.isEmpty(bizPath)){
|
||||||
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
||||||
//未指定目录,则用阿里云默认目录 upload
|
//未指定目录,则用阿里云默认目录 upload
|
||||||
|
@ -122,14 +153,7 @@ public class CommonController {
|
||||||
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
||||||
//update-end-author:taoyan date:20200814 for:文件上传改造
|
//update-end-author:taoyan date:20200814 for:文件上传改造
|
||||||
}
|
}
|
||||||
if(oConvertUtils.isNotEmpty(savePath)){
|
return savePath;
|
||||||
result.setMessage(savePath);
|
|
||||||
result.setSuccess(true);
|
|
||||||
}else {
|
|
||||||
result.setMessage("上传失败!");
|
|
||||||
result.setSuccess(false);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,21 +163,35 @@ public class CommonController {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String uploadLocal(MultipartFile mf,String bizPath){
|
private String uploadLocal(MultipartFile mf,String bizPath){
|
||||||
|
return uploadLocal(mf,null,bizPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地文件上传
|
||||||
|
* @param mf 文件
|
||||||
|
* @param bizPath 自定义路径
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String uploadLocal(MultipartFile mf,String _fileName,String bizPath){
|
||||||
try {
|
try {
|
||||||
String ctxPath = uploadpath;
|
String ctxPath = uploadpath;
|
||||||
String fileName = null;
|
String fileName = _fileName;
|
||||||
File file = new File(ctxPath + File.separator + bizPath + File.separator );
|
File file = new File(ctxPath + File.separator + bizPath + File.separator );
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
// 创建文件根目录
|
// 创建文件根目录
|
||||||
file.mkdirs();
|
file.mkdirs();
|
||||||
}
|
}
|
||||||
// 获取文件名
|
// 获取文件名
|
||||||
String orgName = mf.getOriginalFilename();
|
if(fileName == null){
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
String orgName = mf.getOriginalFilename();
|
||||||
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
|
if (orgName != null) {
|
||||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
}else{
|
if(orgName.contains(SymbolConstant.SPOT)){
|
||||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
|
}else{
|
||||||
|
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String savePath = file.getPath() + File.separator + fileName;
|
String savePath = file.getPath() + File.separator + fileName;
|
||||||
File savefile = new File(savePath);
|
File savefile = new File(savePath);
|
||||||
|
@ -223,6 +261,185 @@ public class CommonController {
|
||||||
// return result;
|
// return result;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class SectionUploadData{
|
||||||
|
private Integer chunkCount;
|
||||||
|
private String fileMd5;
|
||||||
|
private String biz;
|
||||||
|
private String fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//切片上传
|
||||||
|
@PostMapping(value = "/sectionUpload/init")
|
||||||
|
public Result<?> sectionUploadInit(@RequestBody SectionUploadData sectionUploadData) throws Exception {
|
||||||
|
log.info("初始化文件!");
|
||||||
|
//创建文件
|
||||||
|
Integer chunkCount = sectionUploadData.getChunkCount();
|
||||||
|
String fileMd5 = sectionUploadData.getFileMd5();
|
||||||
|
String fileName = sectionUploadData.getFileName();
|
||||||
|
String bizPath = sectionUploadData.getBiz();
|
||||||
|
if (oConvertUtils.isNotEmpty(bizPath)) {
|
||||||
|
if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
|
||||||
|
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建一个空文件夹,里面有个文件信息
|
||||||
|
String ctxPath = uploadpath;
|
||||||
|
File file = new File(ctxPath + File.separator + bizPath + File.separator + fileMd5 );
|
||||||
|
if (!file.exists()) {
|
||||||
|
// 创建文件根目录
|
||||||
|
file.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
File fileInfo = new File(ctxPath + File.separator + bizPath + File.separator + fileMd5 + File.separator + "file.info" );
|
||||||
|
FileUtil.writeUtf8String("fileMd5:" + fileMd5 + "\nchunkCount:" + chunkCount + "\nfileName:" + fileName,fileInfo);
|
||||||
|
return Result.OK("init ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/sectionUpload/upload")
|
||||||
|
public Result<?> sectionUploadUpload(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
log.info("上传文件!");
|
||||||
|
String bizPath = request.getParameter("biz");
|
||||||
|
String fileMd5 = request.getParameter("fileMd5");
|
||||||
|
String partNumber = request.getParameter("partNumber");
|
||||||
|
|
||||||
|
//LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
|
||||||
|
if (oConvertUtils.isNotEmpty(bizPath)) {
|
||||||
|
if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
|
||||||
|
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||||
|
// 获取上传文件对象
|
||||||
|
MultipartFile file = multipartRequest.getFile("file");
|
||||||
|
|
||||||
|
String savePath = this.uploadLocal(file, partNumber, bizPath + File.separator + fileMd5);
|
||||||
|
|
||||||
|
if(StringUtils.isBlank(savePath)){
|
||||||
|
return Result.error("upload error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.OK("upload ok");
|
||||||
|
}
|
||||||
|
@PostMapping(value = "/sectionUpload/end")
|
||||||
|
public Result<?> sectionUploadEnd(@RequestBody SectionUploadData sectionUploadData){
|
||||||
|
log.info("合并文件!");
|
||||||
|
Result<?> result = new Result<>();
|
||||||
|
Integer chunkCount = sectionUploadData.getChunkCount();
|
||||||
|
String fileMd5 = sectionUploadData.getFileMd5();
|
||||||
|
String fileName = sectionUploadData.getFileName();
|
||||||
|
String orgName = fileName;
|
||||||
|
String bizPath = sectionUploadData.getBiz();
|
||||||
|
|
||||||
|
if (oConvertUtils.isNotEmpty(bizPath)) {
|
||||||
|
if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){
|
||||||
|
throw new JeecgBootException("上传目录bizPath,格式非法!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建一个空文件夹,里面有个文件信息
|
||||||
|
String ctxPath = uploadpath;
|
||||||
|
String folderPath = ctxPath + File.separator + bizPath + File.separator + fileMd5;
|
||||||
|
File fileFolder = new File(folderPath);
|
||||||
|
|
||||||
|
|
||||||
|
//savePath = this.uploadLocal(file,bizPath)
|
||||||
|
|
||||||
|
List<String> allFileNameList = FileUtil.listFileNames(fileFolder.getPath());
|
||||||
|
List<String> fileNameList = allFileNameList.stream().filter(x -> !StringUtils.equals("file.info",x))
|
||||||
|
.sorted(Comparator.comparing(Integer::parseInt))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (orgName != null) {
|
||||||
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
|
if(orgName.contains(SymbolConstant.SPOT)){
|
||||||
|
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
|
}else{
|
||||||
|
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
File outFile = FileUtil.newFile(ctxPath + File.separator + bizPath + File.separator + fileName);
|
||||||
|
|
||||||
|
|
||||||
|
// FastByteArrayOutputStream ais = IoUtil.w
|
||||||
|
try {
|
||||||
|
Vector<InputStream> streams = new Vector<>();
|
||||||
|
fileNameList.forEach(sectionFileName -> {
|
||||||
|
InputStream is = FileUtil.getInputStream(folderPath + File.separator + sectionFileName);
|
||||||
|
streams.add(is);
|
||||||
|
});
|
||||||
|
|
||||||
|
Enumeration<InputStream> enumerations = streams.elements();
|
||||||
|
|
||||||
|
SequenceInputStream sis = new SequenceInputStream(enumerations);
|
||||||
|
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(outFile.toPath()));
|
||||||
|
|
||||||
|
byte[] bys = new byte[1024];
|
||||||
|
int len = 0;
|
||||||
|
while((len = sis.read(bys)) != -1){
|
||||||
|
bos.write(bys, 0, len);
|
||||||
|
}
|
||||||
|
IoUtil.close(sis);
|
||||||
|
IoUtil.close(bos);
|
||||||
|
streams.forEach(IoUtil::close);
|
||||||
|
|
||||||
|
//删除临时文件
|
||||||
|
FileUtil.del(fileFolder);
|
||||||
|
|
||||||
|
//本地上传不做处理,
|
||||||
|
if(!CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||||
|
String savePath = upload(bizPath, getMultipartFile(outFile));
|
||||||
|
if(oConvertUtils.isNotEmpty(savePath)){
|
||||||
|
result.setMessage(savePath);
|
||||||
|
result.setSuccess(true);
|
||||||
|
}else {
|
||||||
|
result.setMessage("上传失败!");
|
||||||
|
result.setSuccess(false);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
//本地上传不做处理,直接返回地址即可
|
||||||
|
result.setSuccess(true);
|
||||||
|
result.setMessage(bizPath + "/" + fileName);//地址
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
result.setSuccess(false);
|
||||||
|
result.setMessage(e.getMessage());//地址
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file转MultipartFile
|
||||||
|
* @param file File对象
|
||||||
|
* @return MultipartFile 对象
|
||||||
|
*/
|
||||||
|
public static MultipartFile getMultipartFile(File file) {
|
||||||
|
FileItem item = new DiskFileItemFactory().createItem("file"
|
||||||
|
, MediaType.MULTIPART_FORM_DATA_VALUE
|
||||||
|
, true
|
||||||
|
, file.getName());
|
||||||
|
try (InputStream input = Files.newInputStream(file.toPath());
|
||||||
|
OutputStream os = item.getOutputStream()) {
|
||||||
|
// 流转移
|
||||||
|
IOUtils.copy(input, os);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Invalid file: " + e, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CommonsMultipartFile(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
//切片上传END
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预览图片&下载文件
|
* 预览图片&下载文件
|
||||||
* 请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
* 请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
||||||
|
|
Loading…
Reference in New Issue