springboot:各种下载文件的方式
Posted yololee_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot:各种下载文件的方式相关的知识,希望对你有一定的参考价值。
文章目录
springboot:各种下载文件的方式
一、使用response输出流下载
注意第一种方式返回值必须为void
@GetMapping("/t1")
public void down1(HttpServletResponse response) throws Exception
response.reset();
response.setContentType("application/octet-stream;charset=utf-8");
response.setHeader(
"Content-disposition",
"attachment; filename=test.png");
try(
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\\\desktop\\\\1.png"));
// 输出流
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
)
byte[] buff = new byte[1024];
int len = 0;
while ((len = bis.read(buff)) > 0)
bos.write(buff, 0, len);
二、使用ResponseEntity
@GetMapping("/t2")
public ResponseEntity<InputStreamResource> down2() throws Exception
InputStreamResource isr = new InputStreamResource(new FileInputStream("E:\\\\desktop\\\\1.png"));
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header("Content-disposition", "attachment; filename=test1.png")
.body(isr);
@GetMapping("/t3")
public ResponseEntity<ByteArrayResource> down3() throws Exception
byte[] bytes = Files.readAllBytes(new File("E:\\\\desktop\\\\1.png").toPath());
ByteArrayResource bar = new ByteArrayResource(bytes);
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header("Content-disposition", "attachment; filename=test2.png")
.body(bar);
三、注意
后端使用前三种的一种方式,请求方式使用非GET请求,前端使用Blob类型接收
某些情况下,在下载时需要向后端POST一些参数,这时需要前端做一定配合,将接收类型设定为Blob
@PostMapping("/t4")
public ResponseEntity<ByteArrayResource> down4(String fileName, @RequestBody Map data) throws Exception
System.out.println(data);
byte[] bytes = Files.readAllBytes(new File("E:\\\\desktop\\\\1.png").toPath());
ByteArrayResource bar = new ByteArrayResource(bytes);
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header("Content-disposition", "attachment; filename=test.png")
.body(bar);
前端代码(这里使用了原生的ajax):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function download()
var ajax = new XMLHttpRequest();
ajax.withCredentials = true;
ajax.responseType = "blob";
const fileName = "ttt.txt";
ajax.open('post','http://localhost:7901/demo/down/file/t4?fileName=' + fileName);
ajax.setRequestHeader("Content-Type","application/json;charset=utf-8");
// ajax.setRequestHeader("Accept","application/json;charset=utf-8");
ajax.send(JSON.stringify(firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"));
ajax.onreadystatechange = function ()
if (ajax.readyState==4 &&ajax.status==200)
console.log(ajax.response);
const href = URL.createObjectURL(ajax.response);
const a = document.createElement('a');
a.setAttribute('href', href);
a.setAttribute('download', fileName);
a.click();
URL.revokeObjectURL(href);
</script>
</head>
<body>
<input type="button" value="下载" onclick="download();"/>
</body>
</html>
springboot 中使用groovy脚本的各种方式
springboot 中使用groovy脚本的各种方式
准备工作
1. 环境
java1.8,springboot2.1.6
引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-demo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-demo1</name>
<description>springboot-demo1</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.21</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. groovy 运行
依赖了groovy后,idea便可以创建groovy class了:
创建了groovy脚本,右键 run 就可以单独运行脚本了,无需配置groovy环境。
一、动态执行groovy脚本
动态执行,就是没有固定的脚本文件,代码是传入的或动态生成的。
1. groovy通过import的方式直接调用java类
package com.demo.groovy;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
public class GroovyTest1
public String testQuery(long id)
return "查询成功, id=" + id;
public static void main(String[] args)
fun1();
/**
* groovy可以通过import的方式直接调用java类
*/
private static void fun1()
//创建脚本对象
GroovyShell groovyShell = new GroovyShell();
//脚本内容,内容中倒入了java类
String scriptContent = "import com.demo.groovy.GroovyTest1\\n" +
"def res = new GroovyTest1().testQuery(1L);\\n" +
"res";
//执行脚本
Script script = groovyShell.parse(scriptContent);
System.out.println(script.run());
2. groovy通过GroovyShell预设对象调用JAVA对象的方法
groovy支持通过GroovyShell预设对象,在groovy动态脚本中直接调用预设对象的方法
package com.demo.groovy;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
public class GroovyTest1
public String testQuery(long id)
return "查询成功, id=" + id;
public static void main(String[] args)
fun2();
/**
*groovy支持通过GroovyShell预设对象,在groovy动态脚本中直接调用预设对象的方法
*/
public static void fun2()
//1.预设对象,就是将java对象作为变量绑定到groovy中
Binding groovyBinding = new Binding();
groovyBinding.setVariable("groovyTest", new GroovyTest1());
//也可以用setProperty
groovyBinding.setProperty("num", 100L);
//2.创建脚本对象
GroovyShell groovyShell = new GroovyShell(groovyBinding);
//3.脚本内容
String scriptContent = "def res = groovyTest.testQuery(num);\\n" +
"res";
//4.执行脚本,得到返回值
Object evaluate = groovyShell.evaluate(scriptContent);
System.out.println(evaluate);
groovyShell.evaluate()方法中会先parse脚本为Script对象。parse相对耗时,如果脚本内容是固定的,可以parse后作为全局变量使用。
3.controller中执行groovy script
package com.demo.groovy;
import groovy.lang.GroovyShell;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequestMapping("/groovy")
public class GroovyController
@PostMapping("/execute")
public Object execute(@RequestBody String scriptContent)
log.info("开始执行脚本,scriptContent=", scriptContent);
GroovyShell groovyShell = new GroovyShell();
Object res = groovyShell.evaluate(scriptContent);
log.info("结束脚本执行,res=", res);
return res;
调用:
4. 将所有SpringBean作为groovy变量
上文说到,可以通过setVariable
和setProperty
将对象作为变量传入groovy脚本。那么,我们就可以通过ApplicationContext获取所有bean,然后作为变量传入groovy。
如此以来,就可以在groovy脚本中使用所有Spring Bean对象了😄!
使用配置类,将所有bean绑定到groovy。因为这些bean都是通用的,存入一次,重复使用即可。
package com.demo.groovy;
import groovy.lang.Binding;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
@Configuration
public class GroovyBindingConfig
@Bean("groovyBinding")
public Binding groovyBinding(ApplicationContext applicationContext)
Binding groovyBinding = new Binding();
Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class);
//遍历设置所有bean,可以根据需求在循环中对bean做过滤
for (String beanName : beanMap.keySet())
groovyBinding.setVariable(beanName, beanMap.get(beanName));
return groovyBinding;
/*@Bean("groovyBinding1")
public Binding groovyBinding1()
Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class);
return new Binding(beanMap); //如果不需要对bean做过滤,直接用beanMap构造Binding对象即可
*/
新建个service类用来注入,并测试
package com.demo.groovy;
import org.springframework.stereotype.Service;
@Service
public class GroovyService
public String executeService(String msg)
return "这是msg="+msg;
控制器:
package com.demo.groovy;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@Slf4j
@RequestMapping("/groovy")
public class GroovyController
@Resource
private ApplicationContext applicationContext;
//注入绑定对象
@Resource
private Binding groovyBinding;
@PostMapping("/execute")
public Object execute(@RequestBody String scriptContent)
log.info("开始执行脚本,scriptContent=", scriptContent);
//shell中加入绑定对象
GroovyShell groovyShell = new GroovyShell(groovyBinding);
Object res = groovyShell.evaluate(scriptContent);
log.info("结束脚本执行,res=", res);
return res;
测试:
二、加载并执行groovy脚本文件
下面介绍一种隐式加载
方式和三种显示加载
方式
1. new一个groovy对象来隐式加载
1.1 新建脚本类
这个脚本必须在项目src下,也就是与java代码在一起,就可以直接new这个groovy类的对象,然后调用它的方法了。
demo.groovy
package com.demo.groovy
interface Simple
String str1();
class Example implements Simple
@Override
String str1()
println System.currentTimeMillis()+"==11111"
1.2在java代码中调用:
package com.demo.groovy;
import java.io.IOException;
public class GroovyTest1
public static void main(String[] args) throws IOException, InterruptedException
new Example().str1()
这是隐式加载
方式,脚本就像普通的java类,只会加载一次,如果脚本变化了,运行中的程序不会变。要想动态感知变化,那么得每次使用重新加载或定时加载
。
下面是显示加载
的方式。
2. 通过evaluate方法调用groovy脚本文件
2.1 新建一个脚本
2.2 evaluate加载并执行脚本
package com.demo.groovy
def sayHello(String name)
println 'Hello ,'+name;
sayHello(name)
调用脚本并执行:
public static void main(String[] args) throws IOException
Binding binding = new Binding();
binding.setProperty("name","张三");
GroovyShell groovyShell = new GroovyShell(binding);
groovyShell.evaluate(new File("src/main/java/com/demo/groovy/demo.groovy"));
执行结果:
Hello ,张三
3. GroovyClassLoader动态加载Groovy Class
你也许熟悉Java的ClassLoader类加载器,当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM运行,负责加载Java class的这部分就叫做Class Loader。而GroovyClassLoader,顾名思义,就是用来加载Groovy类的加载器。
3.1 新建groovy class
src/main/java/com/demo/groovy/demo.groovy
package com.demo.groovy
class demo02
String sayHello(String name, String sex, int age)
return "name: " + name + ", sex: " + sex + ", age: " + age;
3.2 使用反射调用groovy
package com.demo.groovy;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import org.codehaus.groovy.control.CompilerConfiguration;
import java.io.File;
/**
* 使用反射调用groovy
**/
public class Test02
private static GroovyClassLoader groovyClassLoader = null;
public static void initGroovyClassLoader()
CompilerConfiguration config = new CompilerConfiguration();
config.setSourceEncoding("UTF-8");
// 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认)
groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
/**
* 通过GroovyClassLoader加载GroovyShell_2,并反射调用其sayHello(String name, String sex, int age)方法
*/
public static String invokeSayHello(String name, String sex, int age)
String result = "";
File groovyFile = new File("src/main/java/com/demo/groovy/demo.groovy");
if (!groovyFile.exists())
return result;
try
// 获得GroovyShell_2加载后的class
Class<?> groovyClass = groovyClassLoader.parseClass(groovyFile);
// 获得GroovyShell_2的实例
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
// 反射调用sayHello方法得到返回值
Object methodResult = groovyObject.invokeMethod("sayHello", new Object[]name, sex, age);
if (methodResult != null)
result = methodResult.toString();
catch (Exception e)
e.getStackTrace();
return result;
public static void main(String[] args) throws Exception springboot启动方式