commons-fileupload
commons-fileupload
1.4
// 根据自己需要
org.projectlombok
lombok
true
**
* @author Linux's user: FB
* device: Windows 11
* create time: 2022/3/2
* remarks: []
*/
@Data
public class Progress implements Cloneable {
private long bytesRead;
private long contentLength;
private long items;
private static final Progress progress = new Progress();
public static Progress getInstance() {
return progress.clone();
}
@Override
public Progress clone() {
try {
return (Progress) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
@Component
public class FileUploadListener implements ProgressListener {
private final Map map = new ConcurrentHashMap<>();
private final HttpServletRequest request;
public FileUploadListener(HttpServletRequest request) {
this.request = request;
}
/**
* @param bytesRead 当前上传大小
* @param contentLength 总大小
* @param items 当前上传个数
*/
@Override
public void update(long bytesRead, long contentLength, int items) {
Progress progress = Progress.getInstance();
progress.setBytesRead(bytesRead);
progress.setContentLength(contentLength);
progress.setItems(items);
// 可替换成 redis / session
map.put(request.getHeader("file"), progress);
}
public Progress getMap(String header) {
return map.get(header);
}
}
@Component
public class CustomMultipartResolver extends CommonsMultipartResolver {
private final FileUploadListener fileUploadListener;
public CustomMultipartResolver(FileUploadListener fileUploadListener) {
this.fileUploadListener = fileUploadListener;
}
@Override
protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
// 设置上传监听器
fileUpload.setProgressListener(fileUploadListener);
try {
List fileItems = ((ServletFileUpload)fileUpload).parseRequest(request);
return this.parseFileItems(fileItems, encoding);
} catch (FileUploadBase.SizeLimitExceededException var5) {
throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), var5);
} catch (FileUploadBase.FileSizeLimitExceededException var6) {
throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), var6);
} catch (FileUploadException var7) {
throw new MultipartException("Failed to parse multipart servlet request", var7);
}
}
}
@RestController
public class UploadController {
private final UploadService uploadService;
public UploadController(UploadService uploadService) {
this.uploadService = uploadService;
}
@PostMapping("/upload")
public R upload (MultipartFile[] file) {
uploadService.upload(file);
return R.ok().message("上传成功");
}
@GetMapping("/progress")
public R progress (HttpServletRequest request) {
String file = request.getHeader("file");
if (StringUtils.isNullOrEmpty(file)) return R.error().message("需要 header: [file=xxx] 标识");
return R.ok().message(uploadService.getUploadDone(file) ? "上传完成" : "上传中...").data(uploadService.getProgressStyle(file));
}
}
@Service
public class UploadServiceImpl implements UploadService {
private final StringBuilder stringBuilder = new StringBuilder();
private final Map map = new HashMap<>(4);
// 构造注入上传监听
private final FileUploadListener listener;
public UploadServiceImpl(FileUploadListener listener) {
this.listener = listener;
}
/**
* 返回进度参数信息
* "progress": "[##########] 100%",
* "item": 3,
* "percent": 100,
* "status": "over"
* @param header 文件标识
* @return Map
*/
// 进度 Map
@Override
public Map getProgressStyle (String header) {
Progress progress = listener.getMap(header);
if (progress == null) throw new CustomException("未上传文件");
long read = progress.getBytesRead();
long percent = 0;
if (read != 0) percent = (read * 100) / progress.getContentLength();
map.put("percent", percent);
map.put("status", percent == 100 ? "over" : "active");
map.put("progress", getStyleOfCount(percent));
map.put("item", progress.getItems());
return map;
}
/**
* 判断文件是否上传文成
* @param header 文件标识
* @return true / false
*/
@Override
public boolean getUploadDone(String header) {
Progress progress = listener.getMap(header);
if (progress == null) throw new CustomException("未上传文件");
return progress.getBytesRead() == progress.getContentLength();
}
/**
* 文件保存操作
* 这里做存储文件等其他操作操作
* 这里也需要返回进度的话,上面的进度需要 / 2,各记 50%
* @param file 文件
*/
@Override
public void upload(MultipartFile[] file) {
Arrays.asList(file).forEach(f -> {
if (f.isEmpty()) {
throw new CustomException("文件为空");
} else {
System.out.println("文件名:" + f.getOriginalFilename());
System.out.println("文件大小:" + f.getSize());
System.out.println("文件类型:" + f.getContentType());
}
});
}
/**
* 进度样式
* @param percent 进度百分比
* @return [### ] 30%
*/
private String getStyleOfCount (long percent) {
stringBuilder.setLength(0);
stringBuilder.append("[");
for (int i = 0; i < percent / 10; i++) {
stringBuilder.append("#");
}
for (int i = 0; i < 10 - (percent / 10); i++) {
stringBuilder.append(" ");
}
stringBuilder.append("] ").append(percent).append("%");
return stringBuilder.toString();
}
}
上传准备
点击上传后,file 是文件的唯一标识,上传时也需要传入
然后看效果(item 是文件个数)
项目地址:
Spring Boot 上传返回进度【最新】 - 小波博客
页面更新:2024-03-20
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号