当前位置: 首页 > 最新文章 > 正文

Spring Boot 上传文件返回进度

导入的包 commons-fileupload commons-fileupload 1.4// 根据自己需要 org.projectlombok lombok true进度返回类** * @author Linux‘s导入的包<dependency> <groupId>commons-fileupload</groupId> &

admin

导入的包 commons-fileupload commons-fileupload 1.4// 根据自己需要 org.projectlombok lombok true进度返回类** * @author Linux's

导入的包

<dependency>   <groupId>commons-fileupload</groupId>   <artifactId>commons-fileupload</artifactId>   <version>1.4</version></dependency>// 根据自己需要<dependency>   <groupId>org.projectlombok</groupId>   <artifactId>lombok</artifactId>   <optional>true</optional></dependency>

进度返回类

** * @author Linux's user: FB * device: Windows 11 * create time: 2022/3/2 * remarks: [] */@Datapublic 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();        }    }}

文件上传监听器

@Componentpublic class FileUploadListener implements ProgressListener {    private final Map<String, Progress> 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);    }}

文件上传解析器

@Componentpublic 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<FileItem> 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 接口

@RestControllerpublic 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 实现类

@Servicepublic class UploadServiceImpl implements UploadService {    private final StringBuilder stringBuilder = new StringBuilder();    private final Map<String, Object> 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<String, Object>     */    // 进度 Map    @Override    public Map<String, Object> 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();    }}

效果

上传准备

Spring Boot 上传文件返回进度

点击上传后,file 是文件的唯一标识,上传时也需要传入

Spring Boot 上传文件返回进度

然后看效果(item 是文件个数)

Spring Boot 上传文件返回进度

Spring Boot 上传文件返回进度

Spring Boot 上传文件返回进度

项目地址:

Spring Boot 上传返回进度【最新】 - 小波博客


上一篇: shell文字颜色(shell表示颜色是什么颜色) 下一篇:验证码都有什么类型,附项目分享
返回顶部