这篇文章将为大家详细讲解有关如何在SpringBoot中使用fileUpload获取文件的上传进度,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
公司主营业务:成都做网站、成都网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联建站是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联建站推出重庆免费做网站回馈大家。
本功能基于commons fileUpload 组件实现
1.首先,不能在程序中直接使用 fileUpload.parseRequest(request)的方式来获取 request 请求中的 multipartFile 文件对象,原因是因为在 spring 默认的文件上传处理器 multipartResolver 指向的类CommonsMultipartResolver 中就是通过 commons fileUpload 组件实现的文件获取,因此,在代码中再次使用该方法,是获取不到文件对象的,因为此时的 request 对象是不包含文件的,它已经被CommonsMultipartResolver 类解析处理并转型。
CommonsMultipartResolver 类中相关源码片段:
protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { String encoding = determineEncoding(request); FileUpload fileUpload = prepareFileUpload(encoding); try { ListfileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadBase.FileSizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex); } catch (FileUploadException ex) { throw new MultipartException("Failed to parse multipart servlet request", ex); } }
2.由于spring 中的 CommonsMultipartResolver 类中并没有加入 processListener 文件上传进度监听器,所以,直接使用 CommonsMultipartResolver 类是无法监听文件上传进度的,如果我们需要获取文件上传进度,就需要继承 CommonsMultipartResolver 类并重写 parseRequest 方法,在此之前,我们需要创建一个实现了 processListener 接口的实现类用于监听文件上传进度。
processListener接口实现类:
import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.ProgressListener; import org.springframework.stereotype.Component; @Component public class UploadProgressListener implements ProgressListener{ private HttpSession session; public void setSession(HttpSession session){ this.session=session; ProgressEntity status = new ProgressEntity(); session.setAttribute("status", status); } /* * pBytesRead 到目前为止读取文件的比特数 pContentLength 文件总大小 pItems 目前正在读取第几个文件 */ @Override public void update(long pBytesRead, long pContentLength, int pItems) { ProgressEntity status = (ProgressEntity) session.getAttribute("status"); status.setpBytesRead(pBytesRead); status.setpContentLength(pContentLength); status.setpItems(pItems); } }
ProgressEntity 实体类:
import org.springframework.stereotype.Component; @Component public class ProgressEntity { private long pBytesRead = 0L; //到目前为止读取文件的比特数 private long pContentLength = 0L; //文件总大小 private int pItems; //目前正在读取第几个文件 public long getpBytesRead() { return pBytesRead; } public void setpBytesRead(long pBytesRead) { this.pBytesRead = pBytesRead; } public long getpContentLength() { return pContentLength; } public void setpContentLength(long pContentLength) { this.pContentLength = pContentLength; } public int getpItems() { return pItems; } public void setpItems(int pItems) { this.pItems = pItems; } @Override public String toString() { float tmp = (float)pBytesRead; float result = tmp/pContentLength*100; return "ProgressEntity [pBytesRead=" + pBytesRead + ", pContentLength=" + pContentLength + ", percentage=" + result + "% , pItems=" + pItems + "]"; } }
最后,是继承 CommonsMultipartResolver 类的自定义文件上传处理类:
import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUpload; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.multipart.MultipartException; import org.springframework.web.multipart.commons.CommonsMultipartResolver; public class CustomMultipartResolver extends CommonsMultipartResolver{ @Autowired private UploadProgressListener uploadProgressListener; @Override protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { String encoding = determineEncoding(request); FileUpload fileUpload = prepareFileUpload(encoding); uploadProgressListener.setSession(request.getSession());//问文件上传进度监听器设置session用于存储上传进度 fileUpload.setProgressListener(uploadProgressListener);//将文件上传进度监听器加入到 fileUpload 中 try { ListfileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadBase.FileSizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex); } catch (FileUploadException ex) { throw new MultipartException("Failed to parse multipart servlet request", ex); } } }
3.此时,所有需要的类已经准备好,接下来我们需要将 spring 默认的文件上传处理类取消自动配置,并将 multipartResolver 指向我们刚刚创建好的继承 CommonsMultipartResolver 类的自定义文件上传处理类。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.MultipartResolver; import com.example.listener.CustomMultipartResolver; /* * 将 spring 默认的文件上传处理类取消自动配置,这一步很重要,没有这一步,当multipartResolver重新指向了我们定义好 * 的新的文件上传处理类后,前台传回的 file 文件在后台获取会是空,加上这句话就好了,推测不加这句话,spring 依然 * 会先走默认的文件处理流程并修改request对象,再执行我们定义的文件处理类。(这只是个人推测) * exclude表示自动配置时不包括Multipart配置 */ @EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class}) @Configuration @ComponentScan(basePackages = {"com.example"}) @ServletComponentScan(basePackages = {"com.example"}) public class UploadProgressApplication { /* * 将 multipartResolver 指向我们刚刚创建好的继承 CommonsMultipartResolver 类的自定义文件上传处理类 */ @Bean(name = "multipartResolver") public MultipartResolver multipartResolver() { CustomMultipartResolver customMultipartResolver = new CustomMultipartResolver(); return customMultipartResolver; } public static void main(String[] args) { SpringApplication.run(UploadProgressApplication.class, args); } }
至此,准备工作完成,我们再创建一个测试用的 controller 和 html 页面用于文件上传。
controller:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/uploadProgress") public class UploadController { @RequestMapping(value = "/showUpload", method = RequestMethod.GET) public ModelAndView showUpload() { return new ModelAndView("/UploadProgressDemo"); } @RequestMapping("/upload") @ResponseBody public void uploadFile(MultipartFile file) { System.out.println(file.getOriginalFilename()); } }
HTML:
测试 这里写代码片 这是文件上传页面
关于如何在SpringBoot中使用fileUpload获取文件的上传进度就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。