现有一些图片在服务器上的链接,在浏览器中打开这些链接是直接显示在浏览器页面的形式。
现在需要生成这些图片的单独下载以及打包下载链接,即在浏览器中打开下载链接后弹出下载框提示下载。由于前端存在跨域问题,所以图片下载由后台接口完成。
首先编写文件下载工具类:
1 import java.net.URL; 2 import java.net.MalformedURLException; 3 import org.apache.commons.io.FileUtils; 4 5 public class FileDownloadUtil { 6 /** 7 * 下载文件---返回下载后的文件存储路径 8 * 9 * @param url 文件路径 10 * @param dir 目标存储目录 11 * @param fileName 存储文件名 12 * @return 13 */ 14 public static void downloadHttpUrl(String url, String dir, String fileName) throws BusinessException { 15 try { 16 URL httpurl = new URL(url); 17 File dirfile = new File(dir); 18 if (!dirfile.exists()) { 19 dirfile.mkdirs(); 20 } 21 FileUtils.copyURLToFile(httpurl, new File(dir+fileName)); 22 } catch (MalformedURLException e) { 23 e.printStackTrace(); 24 } catch (IOException e) { 25 e.printStackTrace();26 } 26 } 27 28 public static boolean deleteFile(File file) { 29 if (file.exists()) { 30 return file.delete(); 31 } 32 return false; 33 } 34 }
单张图片下载
Controller层接口:
1 import org.apache.commons.lang.StringUtils; 2 import java.io.*; 3 4 5 protected HttpServletResponse response; 6 7 /** 8 * 单张图片下载 9 * 10 * @param url 要下载的图片url 11 * @author: nemowang 12 */ 13 @ApiImplicitParams({ 14 @ApiImplicitParam(name = "url", value = "图片url", required = true, dataType = "String", paramType = "query"), 15 }) 16 @ApiOperation(value = "单张图片下载", notes = "单张图片下载") 17 @RequestMapping(value = "/downloadPicture", method = RequestMethod.GET) 18 public void downloadPicture(String url) { 19 20 // 拼接完整图片路径。这里填写图片链接 21 String urlPath = ""; 22 23 // 获取图片文件后缀名 24 String postfix = "." + StringUtils.substringAfterLast(url, "."); 25 26 // 获取当前类的所在项目路径 27 File directory = new File(""); 28 String courseFile; 29 30 String srcPath; 31 File srcFile = null; 32 FileInputStream fileInputStream = null; 33 InputStream fis = null; 34 OutputStream out = null; 35 try { 36 courseFile = directory.getCanonicalPath(); 37 String fileName = "\" + StringUtil.getUUID() + postfix; 38 // 下载文件 39 FileDownloadUtil.downloadHttpUrl(urlPath, courseFile, fileName); 40 41 srcPath = courseFile + fileName; 42 srcFile = new File(srcPath); 43 44 fileInputStream = new FileInputStream(srcPath); 45 fis = new BufferedInputStream(fileInputStream); 46 byte[] buffer = new byte[fis.available()]; 47 fis.read(buffer); 48 49 response.setContentType("application/octet-stream"); 50 response.setHeader("Content-disposition", "attachment;filename=" + fileName); 51 out = response.getOutputStream(); 52 out.write(buffer); 53 out.flush(); 54 out.close(); 55 } catch (Exception e) { 56 e.printStackTrace(); 57 } finally { 58 try { 59 if (fileInputStream != null) { 60 fileInputStream.close(); 61 } 62 if (fis != null) { 63 fis.close(); 64 } 65 if (out != null) { 66 out.close(); 67 } 68 } catch (IOException e) { 69 e.printStackTrace(); 70 } 71 } 72 73 // 删除中间文件 74 if (srcFile != null) { 75 System.out.println(FileDownloadUtil.deleteFile(srcFile)); 76 } 77 }
因为是GET请求,所以直接拼接接口路由+参数,用浏览器打开就能弹出下载。
至此单张图片下载接口结束。
多张图片打包下载
Controller层接口:
1 /** 2 * 图片打包下载 3 */ 4 @ApiImplicitParams({ 5 @ApiImplicitParam(name = "urls", value = "图片url列表", required = true, dataType = "List", paramType = "query"), 6 }) 7 @ApiOperation(value = "图片打包下载", notes = "图片打包下载") 8 @RequestMapping(value = "/downloadPictureList", method = RequestMethod.GET) 9 public void downloadPictureList(List urls) { 10 List<String> fileNameList = new ArrayList<>(); 11 12 for (int i = 0; i < urls.size(); i++) { 13 // 获取文件名 14 fileNameList.add(StringUtils.substringAfterLast(urls.get(i), "/")); 15 16 // 拼接完整图片路径 17 urls.set(i, DOMAIN + urls.get(i)); 18 } 19 20 // 获取当前类的所在项目路径 21 File directory = new File(""); 22 String courseFile; 23 24 String srcPath; 25 File srcFile = null; 26 27 // 要打包的文件列表 28 List<File> fileList = new ArrayList<>(); 29 30 ZipOutputStream zos = null; 31 OutputStream out = null; 32 try { 33 courseFile = directory.getCanonicalPath(); 34 35 // 下载文件 36 for (int i = 0; i < urls.size(); i++) { 37 String fileName = "\" + fileNameList.get(i); 38 FileDownloadUtil.downloadHttpUrl(urls.get(i), courseFile, fileName); 39 srcPath = courseFile + fileName; 40 srcFile = new File(srcPath); 41 fileList.add(srcFile); 42 } 43 44 45 46 long start = System.currentTimeMillis(); 47 48 response.setContentType("application/x-zip-compressed"); 49 response.setHeader("Content-disposition", "attachment;filename=" + StringUtil.getUUID() + ".zip"); 50 out = response.getOutputStream(); 51 zos = new ZipOutputStream(out); 52 for (File file : fileList) { 53 byte[] buf = new byte[BUFFER_SIZE]; 54 zos.putNextEntry(new ZipEntry(file.getName())); 55 int len; 56 FileInputStream in = new FileInputStream(file); 57 while ((len = in.read(buf)) != -1) { 58 zos.write(buf, 0, len); 59 } 60 zos.closeEntry(); 61 in.close(); 62 } 63 long end = System.currentTimeMillis(); 64 System.out.println("压缩完成,耗时:" + (end - start) + " ms"); 65 66 67 out.flush(); 68 } catch (IOException e) { 69 e.printStackTrace(); 70 } catch (Exception e) { 71 throw new RuntimeException("zip error from ZipUtils", e); 72 } finally { 73 if (zos != null) { 74 try { 75 zos.close(); 76 } catch (IOException e) { 77 e.printStackTrace(); 78 } 79 } 80 if (out != null) { 81 try { 82 zos.close(); 83 } catch (IOException e) { 84 e.printStackTrace(); 85 } 86 } 87 } 88 89 // 删除中间文件 90 if (fileList != null) { 91 for (File file : fileList) { 92 System.out.println(FileDownloadUtil.deleteFile(file)); 93 } 94 } 95 }
同样是GET请求,所以也是拼接接口路由+参数,用浏览器打开就能弹出下载。