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
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 说点对这几个容易混淆的词的理解:1、c++中的virtual方法的 virtual关键字主要是防止继承中重复继承父类的同一个方法而设置的标识
- 摘要:想必大家做开发的时候都会用到下拉刷新的控件,现在各种第三方的下拉刷新控件不胜枚举。当然最NB的还是XListView。其他也有针对Gr
- public class BeanDefinitionHolder implements BeanMetadataElement { &nb
- 本文接上文“java反射之方法反射的基本操作方法”,利用反射了解下java集合中泛型的本质1、初始化两个集合,一个使用泛型,一个不使用Arr
- 把三状态转换图放在这,方便分析方法的作用:1.Session的save()方法Session是Hibernate所有接口中最重要的接口,提供
- 本文实例讲述了Java针对ArrayList自定义排序的2种实现方法。分享给大家供大家参考,具体如下:Java中实现对list的自定义排序主
- 1.雪崩效应 雪崩效应如上图所示,假设我们有3个微服务A,B,C,A调用B,B调用C,如果C挂掉了,由于B是同步调用,不断等待,导致资源耗尽
- Mybatis-Plus是一个优秀的Mybatis增强工具,目前更新到3.1.1。Mybatis-Plus原生提供了很多单表操作的方法,极大
- 缘由:今天好友拿着下面的代码,问我为什么 Map.Entry 这个接口没有实现 getKey() 和 getValue() 方法,却可以使用
- 一、银行存取款1.前言毕竟谁不喜欢钱呢!(不是😅)我看谁不喜欢在知识的海洋中遨游😤!2.描述银行存取款的流程是人们非常熟悉的事情,用户可以在
- 一、数据类型与变量的介绍在程序运行的过程中计算机需要记录大量的状态 数据(这里我们统称数据)。那这些数据都存放在哪呢?程序在运行过程中的数据
- 前言今天遇到一个问题,我们有个ip.dat二进制文件,通过里面内容可以解析ip所在的地域信息,本地单元测试都是OK的,部署到测试环境后,发现
- 第一种查看防火墙是否打开6379端口 查看防火墙状态systemctl status firewalld如果防火墙没有启动的话。可以选择直接
- 合成聚合复用原则合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP
- 目录事件最基本的用法理解路由事件WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇
- Dubbo作为国内最出名的分布式服务框架,是Java程序员必备必会的框架之一,更是中高级测试面试过程中经常会问的技术,无论你是否用过,你都必
- 介绍:%是求余运算符,也叫模除运算符,用于求余数。%要求两个操作数均为整数(或可以隐式转换成整数的类型)。标准规定:如果%左边的操作数为负数
- 用Stream解决两层List属性求和假设一个人有很多个银行账户,每个银行账户中存有不同金额的存款,那么我们如何用Stream求一组人的所有
- 1、首先导入solrj需要的的架包2、需要注意的是低版本是solr是使用SolrServer进行URL实例的,5.0之后已经使用SolrCl
- Springboot swagger-ui.html访问不到问题在前面的Swagger2的基本配置中是可以访问到swagger-ui.htm