SpringBoot上传文件返回进度
导入的包 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); } } } Controller 接口@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 实现类@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 上传返回进度【最新】 - 小波博客
时光很暖,脚步很慢清晨,秋雨潇潇,寒风阵阵,幸福小镇大街小巷只有稀稀疏疏过路的人。虽然已过六点,太阳却迟迟没有露出光亮,似乎被什么力量遏制,无法脱身。滴答滴答,几颗黄豆大的雨点突然从阴霾的空中落下,
群狼逐鹿,加冕荣耀!狼人杀英雄联赛总决赛明日开战逻辑对决,破晓加冕!2022狼人杀英雄联赛WPL总决赛高燃来袭!12支来自主播精英赛线上淘汰赛人气复活赛等多个晋级通道,经历了层层选拔的最强门派集结,正式展开终极对决!10月28日
不要嘲笑下山的神,但是下山的神能不能别逗我们这些凡人笑世间宇宙万物有盛有衰,任何事物不可能永恒强盛,否则这世界就太无趣了,毕竟更迭才是永恒的,而强盛只是暂时的,大部分人都该接受自己有一天会衰老会死亡!西罗作为曾经有些逆天的神,创造了大
孤独而自由我想自由的人大概都是孤独的吧。可能是因为我的浅薄让我这么认为,可能我以后会改变想法,但这一刻我确实是这么认为的。风是自由的,但若吹入小巷,与青瓦便有了交集,这一刻的风纠缠了烟火气变
十日谈乌桕微丹菊渐开满大街的低头族,能有几个认得乌桕树并懂得欣赏它的美呢?乌桕,是山野里最美的树。几场秋风刮过,天蓝得透亮,三棵乌桕站在溪水边,和流云一起把影子投进深潭。人在青石古桥上,一腔心思被簌簌
真正的母爱应该是有温度且有分寸的曾经读到一篇关于母亲的文章,里面这样写母亲是暖暖的人,像个太阳,她走到哪里,哪里就是亮堂堂的,暖和和的,空气里的温度都要上升几度。我想,最好的母亲,该是如此吧。真正的母爱应该是有温
两个人的烟花,一个人的等待李氏呓语20131129一有一种沉淀的感觉叫做寂寞2006年我被公司从家门口调到了外地,即使满心不愿意,也不得不去。唐山是一个北方的重工业城市,人们生活节奏还是习惯日出而作日落而息
聪明人的个人成长读书笔记我们获得成长的一个最主要途径就是持续发现更多关于我们自己关于外部世界的现实真相。无论你过着什么样的生活,都必然会从这种生活中获得某些经验。但是,如果你能够清醒自主地探求真相远离虚伪
中国红温暖欧洲中国挽救欧洲?因众所周知的原因,欧洲面临巨大的能源危机,这让本就寒冷的冬天雪上加霜。由于天然气和电费太高,很多欧洲人转而使用传统的煤炭进行供暖,有的甚至在砍树劈柴为冬天做准备。然而缺少了俄罗斯的
夜雨丨胡德在观音阁老茶馆饮尽时光(组诗)在观音阁老茶馆饮尽时光(组诗)胡德在观音阁老茶馆饮尽时光一溜青石板铺叙而成的老街拼接着穿抖木瓦房的孤独彭镇,用倒流的时光突兀成一种网红观音阁老茶馆流动的茶客品饮着百年的刀光剑影杨柳
凝望岁月随遇而安凝望岁月随遇而安文雪映梅花丹桂飘香,秋高气爽醉了秋日好时光斑斓且听秋日风吟秋日私语亦无言才是最高的境界人世繁华,四季轮回人生也有四季,走过春夏秋冬酸甜苦辣随缘自在学会放下放下过往冷