springmvc实现文件上传和文件下载三种方法(包括js url传值中文乱码和springmvc下载中文文件名不显示以及上传的文件名重名覆盖等解决方案)
1.文件上传
@RequestMapping(value = "/upload.do", method = { RequestMethod.POST }) public @ResponseBody Object upload(HttpServletRequest request) throws IllegalStateException, IOException, FileUploadException { RequestResultVO rr = new RequestResultVO(); CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( request.getSession().getServletContext()); // 判断是否有多文件上传,即多次请求 if (multipartResolver.isMultipart(request)) { try { // 转成多部分的request MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; // 取得多文件的文件名 Iterator iter = multiRequest.getFileNames(); while (iter.hasNext()) { // 取得上传文件 MultipartFile f = multiRequest.getFile(iter.next() .toString()); if (f != null) { // 取得文件名称 String fileName = f.getOriginalFilename(); Long fileSize = f.getSize(); String fileType = request.getParameter("fileType");//获取文件类型 if (fileName.trim() != "") { String modelName=request.getParameter("modelName"); //String basepath = filepath+File.separator+modelName+File.separator+DateUtil.format(new Date(), "yyyyMMdd")+File.separator; //获取文件上传路径 String basepath=servletContext.getRealPath("/").substring(0, servletContext.getRealPath("/").lastIndexOf("seawin-webapp-base"))+"/seawin-uploadfile/"+modelName+"/"; FileUtil.mkDirs(basepath);// 创建文件夹 //解决文件名重名 String newFileName =UUID.randomUUID().toString().replace("-","")+"."+FilenameUtils.getExtension(fileName); File localFile = new File(basepath+File.separator+ fileName); int i = 1; newFileName = fileName; while(localFile.exists()){ if(fileName.indexOf(".") != -1){ newFileName = fileName.substring(0, fileName.indexOf(".")) +"-"+i+fileName.substring(fileName.indexOf(".")); }else{ newFileName = fileName +"-"+i; } i++; localFile = new File(basepath+File.separator+newFileName); } f.transferTo(localFile); // 保存到电脑当前目录下 String outPath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort(); String fileUrl=outPath +"/seawin-uploadfile/"+modelName+"/"+ newFileName; String message = "";// 0代表上传成功,1代表上传失败 if (!f.isEmpty() && f != null) { message = "0"; } else { message = "1"; } Long id = (long) Integer.parseInt(request .getParameter("BillId")); Long billId = null; if (StringUtils.isNotBlank(id.toString())) { List<CustomsDeclareBill> list = customsDeclareBillService .selectByPrimaryKey(id); if (!list.isEmpty() && list != null) { billId = list.get(0).getId(); } CustomsDeclareAttach attach = new CustomsDeclareAttach(); attach.setBillId(billId); attach.setFilePath(fileUrl); attach.setFileType(fileType); attach.setFileSize(fileSize.toString()); attach.setIsSign("0"); attach.setEntOrigFileName(newFileName); attach.setCreateTime(new Date()); attach.setAmendTime(new Date()); attach.setRespondsMessage(message); dataAuthorizeService.addDataAuthorizeInfo( attach, "insert"); int j = customsDeclareAttachService .insert(attach); if (j == 0) { rr.setContent(1, "上传失败", null); return rr; } else { rr.setContent(0, "上传成功", null); return rr; } } } } } } catch (Exception e) { e.printStackTrace(); rr.setContent(1, "上传失败", null); return rr; } } return rr; }
(3)第三种:
1 public ResponseEntity<byte[]> download(HttpServletRequest request, 2 Model model)throws Exception { 3 String deFileName=java.net.URLDecoder.decode(request.getParameter("fileName"),"utf-8");//获取文件名并且进行转码 4 //下载文件路径 5 String modelName=request.getParameter("modelName"); 6 String filePath=servletContext.getRealPath("/").substring(0, servletContext.getRealPath("/").lastIndexOf("seawin-webapp-base"))+"/seawin-uploadfile/"+modelName+"/"; 7 File file = new File(filePath + File.separator + deFileName); 8 HttpHeaders headers = new HttpHeaders(); 9 //下载显示的文件名,解决中文名称乱码问题 10 String downloadFielName = new String(deFileName.getBytes("UTF-8"),"iso-8859-1"); 11 //通知浏览器以attachment(下载方式)打开图片 12 headers.setContentDispositionFormData("attachment", downloadFielName); 13 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); 14 return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), 15 headers, HttpStatus.CREATED); 16 }
spring-mvc.xml:
- 基于ResponseEntity的实现的局限性还是很大,从代码中可以看出这种下载方式是一种一次性读取的下载方式,在文件较大的时候会直接抛出内存溢出(我自己亲测一个1.8G的文件在执行下载操作的时候直接抛出了内存溢出)。还有就是这种方式在进行下载统计的时候也存在局限性,无法统计在下载失败的情况已完成下载量,因此限制了对下载的功能扩展。虽然这种实现方式有局限性,但是也有着优点——简洁。在很多时候我们并不需要那么复杂的下载功能时,这种实现就应该是首选了。
- 然而下载java通用实现在功能上比第一种实现更加丰富,对下载的文件大小无限制(循环读取一定量的字节写入到输出流中,因此不会造成内存溢出,但是在下载人数过多的时候应该还是出现一些异常,不过下载量较大的文件一般都会使用ftp服务器来做吧),另外因为是这种实现方式是基于循环写入的方式进行下载,在每次将字节块写入到输出流中的时都会进行输出流的合法性检测,在因为用户取消或者网络原因造成socket断开的时候,系统会抛出SocketWriteException,系统可以捕捉这个过程中抛出的异常,当捕捉到异常的时候我们可以记录当前已经传输的数据量,这样就可以完成下载状态和对应状态下载量和速度之类的数据记录。另外这种方式实现方式还可以实现一种断点续载的功能
以上就是整个springmvc的文件上传和文件下载,以上代码都是本人经过亲自测试并且应用到实际项目当中,如果对你有帮助,那么就顶下文吧