Java Springboot如何基于图片生成下载链接
作者:NemoWang 发布时间:2023-05-19 19:57:32
标签:下载,链接,Java,Spring,boot
现有一些图片在服务器上的链接,在浏览器中打开这些链接是直接显示在浏览器页面的形式。
现在需要生成这些图片的单独下载以及打包下载链接,即在浏览器中打开下载链接后弹出下载框提示下载。由于前端存在跨域问题,所以图片下载由后台接口完成。
首先编写文件下载工具类:
import java.net.URL;
import java.net.MalformedURLException;
import org.apache.commons.io.FileUtils;
public class FileDownloadUtil {
/**
* 下载文件---返回下载后的文件存储路径
*
* @param url 文件路径
* @param dir 目标存储目录
* @param fileName 存储文件名
* @return
*/
public static void downloadHttpUrl(String url, String dir, String fileName) throws BusinessException {
try {
URL httpurl = new URL(url);
File dirfile = new File(dir);
if (!dirfile.exists()) {
dirfile.mkdirs();
}
FileUtils.copyURLToFile(httpurl, new File(dir+fileName));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();26 }
}
public static boolean deleteFile(File file) {
if (file.exists()) {
return file.delete();
}
return false;
}
}
单张图片下载
Controller层接口:
import org.apache.commons.lang.StringUtils;
import java.io.*;
protected HttpServletResponse response;
/**
* 单张图片下载
*
* @param url 要下载的图片url
* @author: nemowang
*/
@ApiImplicitParams({
@ApiImplicitParam(name = "url", value = "图片url", required = true, dataType = "String", paramType = "query"),
})
@ApiOperation(value = "单张图片下载", notes = "单张图片下载")
@RequestMapping(value = "/downloadPicture", method = RequestMethod.GET)
public void downloadPicture(String url) {
// 拼接完整图片路径。这里填写图片链接
String urlPath = "";
// 获取图片文件后缀名
String postfix = "." + StringUtils.substringAfterLast(url, ".");
// 获取当前类的所在项目路径
File directory = new File("");
String courseFile;
String srcPath;
File srcFile = null;
FileInputStream fileInputStream = null;
InputStream fis = null;
OutputStream out = null;
try {
courseFile = directory.getCanonicalPath();
String fileName = "\\" + StringUtil.getUUID() + postfix;
// 下载文件
FileDownloadUtil.downloadHttpUrl(urlPath, courseFile, fileName);
srcPath = courseFile + fileName;
srcFile = new File(srcPath);
fileInputStream = new FileInputStream(srcPath);
fis = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
out = response.getOutputStream();
out.write(buffer);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (fis != null) {
fis.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 删除中间文件
if (srcFile != null) {
System.out.println(FileDownloadUtil.deleteFile(srcFile));
}
}
因为是GET请求,所以直接拼接接口路由+参数,用浏览器打开就能弹出下载。
至此单张图片下载接口结束。
多张图片打包下载
Controller层接口:
/**
* 图片打包下载
*/
@ApiImplicitParams({
@ApiImplicitParam(name = "urls", value = "图片url列表", required = true, dataType = "List", paramType = "query"),
})
@ApiOperation(value = "图片打包下载", notes = "图片打包下载")
@RequestMapping(value = "/downloadPictureList", method = RequestMethod.GET)
public void downloadPictureList(List urls) {
List<String> fileNameList = new ArrayList<>();
for (int i = 0; i < urls.size(); i++) {
// 获取文件名
fileNameList.add(StringUtils.substringAfterLast(urls.get(i), "/"));
// 拼接完整图片路径
urls.set(i, DOMAIN + urls.get(i));
}
// 获取当前类的所在项目路径
File directory = new File("");
String courseFile;
String srcPath;
File srcFile = null;
// 要打包的文件列表
List<File> fileList = new ArrayList<>();
ZipOutputStream zos = null;
OutputStream out = null;
try {
courseFile = directory.getCanonicalPath();
// 下载文件
for (int i = 0; i < urls.size(); i++) {
String fileName = "\\" + fileNameList.get(i);
FileDownloadUtil.downloadHttpUrl(urls.get(i), courseFile, fileName);
srcPath = courseFile + fileName;
srcFile = new File(srcPath);
fileList.add(srcFile);
}
long start = System.currentTimeMillis();
response.setContentType("application/x-zip-compressed");
response.setHeader("Content-disposition", "attachment;filename=" + StringUtil.getUUID() + ".zip");
out = response.getOutputStream();
zos = new ZipOutputStream(out);
for (File file : fileList) {
byte[] buf = new byte[BUFFER_SIZE];
zos.putNextEntry(new ZipEntry(file.getName()));
int len;
FileInputStream in = new FileInputStream(file);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) + " ms");
out.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils", e);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 删除中间文件
if (fileList != null) {
for (File file : fileList) {
System.out.println(FileDownloadUtil.deleteFile(file));
}
}
}
同样是GET请求,所以也是拼接接口路由+参数,用浏览器打开就能弹出下载。
来源:https://www.cnblogs.com/nemowang1996/p/11603848.html


猜你喜欢
- JDBC操作MySQL在实际的企业级开发环境中,如果数据规模特S别大,此时采用传统的SQL语句去处理的话一般需要分成很多批次处理,而且很容易
- .NET Framework为动态列表List提供泛型类List<T>。这个类实现了IList,ICollection,IEnu
- 由于项目这种类型的图片按钮比较多,所以重写了ImageButton类。package me.henji.widget;import andr
- 问题使用Runtime调用python脚本一直没有结果,经排查是因为 cv2 的 import 问题java代码:python代码:在导入c
- C#中List可谓是使用最广泛的一种数据类型了,使用他来规范数据时,往往会涉及到对数据的处理操作,相关处理数据方法也非常丰富,本文将简单介绍
- 动态数据源在很多具体应用场景的时候,我们需要用到动态数据源的情况,比如多租户的场景,系统登录时需要根据用户信息切换到用户对应的数据库。又比如
- 本文实例讲述了C#实现HTTP上传文件的方法。分享给大家供大家参考。具体实现方法如下:发送文件代码如下:/// <summary>
- 目录通过切面,实现超灵活的注解式数据校验Spring MVC的校验方式通过切面实现自己的注解式数据校验Spring boot aop注解数据
- 在程序中封装了一个List集合对象,然后需要把该集合中的实体插入到数据库中,由于项目使用了Spring+MyBatis的配置,所以打算使用M
- 利用Jconsole工具查看程序的资源占用请求。安装jdk时bin目录有jconsole.exe工具,或者通过 Win + R,输入jcon
- 1.简述描述:1、对输入的字符串进行加解密,并输出。2、加密方法为:当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如
- 本文主要介绍了spring-boot-maven-plugin报红解决方案,亲测有效,具体如下:<?xml version="
- 我们开启一个线程,线程每隔一秒发送一次消息,我们在消息中更新TextView上显示的时间就ok了。首先我们在布局文件中放一个TextView
- 目录springboot中定时任务的创建springboot通过注解创建定时任务首先引入pom直接上代码来一个栗子@Scheduled注解的
- 昨天,我试着在屏幕切换时,使View显示在不同的位置,在网上搜索了一些资料,自己做了一段时间,终于完成了功能。由于屏幕切换会调用activi
- 本Demo使用三个类一个Test类一个自定义的Stack类一个自定义的Queue类可以实现的功能:1.对于一个写在文本文件中的迷宫,能够将其
- 引言:序列化是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其带你过去的状态写入到临时或持储存区,反序列化就是重新创
- spring与IoCIoC:控制反转,将由代码操纵的对象控制权,交给第三方容器,反转给第三方容器。这种对象依赖的关系管理方式,称作IoC。I
- YAMLSpring Boot 提供了大量的自动配置,极大地简化了spring 应用的开发过程,当用户创建了一个 Spring Boot 项
- 1.如果执行了try块没有异常,则继续运行finally块中的语句,即使try块通过return,break,或者continue于最后的语