内容简介:流数据是向Web浏览器发送数据的一种全新方法,可显着加快页面加载速度。通常,我们需要允许用户在Web应用程序中下载文件。当数据太大时,提供良好的用户体验变得非常困难,使用StreamingResponseBody,我们现在可以轻松地为高度并发的应用程序流式传输数据。在本文中,我们将看一个使用
流数据是向Web浏览器发送数据的一种全新方法,可显着加快页面加载速度。通常,我们需要允许用户在Web应用程序中下载文件。当数据太大时,提供良好的用户体验变得非常困难,使用StreamingResponseBody,我们现在可以轻松地为高度并发的应用程序流式传输数据。
在本文中,我们将看一个使用 StreamingResponseBody 下载文件的示例。在这种方法中,数据被处理并以块的形式写入OutputStream。
设置Spring Boot项目
为Maven POM添加一些基本依赖项:
<?xml version=<font>"1.0"</font><font> encoding=</font><font>"UTF-8"</font><font>?> <project xmlns=</font><font>"http://maven.apache.org/POM/4.0.0"</font><font> xmlns:xsi=</font><font>"http://www.w3.org/2001/XMLSchema-instance"</font><font> xsi:schemaLocation=</font><font>"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</font><font>> <modelVersion>4.0.0</modelVersion> <groupId>com.techshard.streamingresponse</groupId> <artifactId>springboot-download</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath /> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> </dependencies> </project> </font>
我们现在将创建一个控制器并添加一个API端点以供下载。这是完整的控制器。
@RestController @RequestMapping (<font>"/api"</font><font>) <b>public</b> <b>class</b> DownloadController { <b>private</b> <b>final</b> Logger logger = LoggerFactory.getLogger(DownloadController.<b>class</b>); @GetMapping (value = </font><font>"/download"</font><font>, produces = MediaType.APPLICATION_JSON_VALUE) <b>public</b> ResponseEntity<StreamingResponseBody> download(<b>final</b> HttpServletResponse response) { response.setContentType(</font><font>"application/zip"</font><font>); response.setHeader( </font><font>"Content-Disposition"</font><font>, </font><font>"attachment;filename=sample.zip"</font><font>); StreamingResponseBody stream = out -> { <b>final</b> String home = System.getProperty(</font><font>"user.home"</font><font>); <b>final</b> File directory = <b>new</b> File(home + File.separator + </font><font>"Documents"</font><font> + File.separator + </font><font>"sample"</font><font>); <b>final</b> ZipOutputStream zipOut = <b>new</b> ZipOutputStream(response.getOutputStream()); <b>if</b>(directory.exists() && directory.isDirectory()) { <b>try</b> { <b>for</b> (<b>final</b> File file : directory.listFiles()) { <b>final</b> InputStream inputStream=<b>new</b> FileInputStream(file); <b>final</b> ZipEntry zipEntry=<b>new</b> ZipEntry(file.getName()); zipOut.putNextEntry(zipEntry); byte[] bytes=<b>new</b> byte[1024]; <b>int</b> length; <b>while</b> ((length=inputStream.read(bytes)) >= 0) { zipOut.write(bytes, 0, length); } inputStream.close(); } zipOut.close(); } <b>catch</b> (<b>final</b> IOException e) { logger.error(</font><font>"Exception while reading and streaming data {} "</font><font>, e); } } }; logger.info(</font><font>"steaming response {} "</font><font>, stream); <b>return</b> <b>new</b> ResponseEntity(stream, HttpStatus.OK); } } </font>
在此API端点中,我们从目录中读取多个文件并创建zip文件。我们在StreamingResponseBody中执行此过程。在使用 ResponseEntity将写入的信息传递回客户端之前, 会将数据直接写入OutputStream 。这意味着下载过程将立即在客户端上启动,而服务器正在处理并以块的形式写入数据。
动服务器并使用 http:// localhost:8080 / api / download 测试此端点 。
使用StreamingResponseBody时,强烈建议配置Spring MVC中使用的TaskExecutor来执行异步请求。TaskExecutor是一个抽象Runnable执行的接口。
让我们配置TaskExecutor。这是AsyncConfiguration类,它使用WebMvcCofigurer配置超时,并且还注册在超时时调用的拦截器,以防您需要一些特殊处理。
@Configuration @EnableAsync @EnableScheduling <b>public</b> <b>class</b> AsyncConfiguration implements AsyncConfigurer { <b>private</b> <b>final</b> Logger log = LoggerFactory.getLogger(AsyncConfiguration.<b>class</b>); @Override @Bean (name = <font>"taskExecutor"</font><font>) <b>public</b> AsyncTaskExecutor getAsyncExecutor() { log.debug(</font><font>"Creating Async Task Executor"</font><font>); ThreadPoolTaskExecutor executor = <b>new</b> ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); <b>return</b> executor; } @Override <b>public</b> AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { <b>return</b> <b>new</b> SimpleAsyncUncaughtExceptionHandler(); } </font><font><i>/** Configure async support for Spring MVC. */</i></font><font> @Bean <b>public</b> WebMvcConfigurer webMvcConfigurerConfigurer(AsyncTaskExecutor taskExecutor, CallableProcessingInterceptor callableProcessingInterceptor) { <b>return</b> <b>new</b> WebMvcConfigurer() { @Override <b>public</b> <b>void</b> configureAsyncSupport(AsyncSupportConfigurer configurer) { configurer.setDefaultTimeout(360000).setTaskExecutor(taskExecutor); configurer.registerCallableInterceptors(callableProcessingInterceptor); WebMvcConfigurer.<b>super</b>.configureAsyncSupport(configurer); } }; } @Bean <b>public</b> CallableProcessingInterceptor callableProcessingInterceptor() { <b>return</b> <b>new</b> TimeoutCallableProcessingInterceptor() { @Override <b>public</b> <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception { log.error(</font><font>"timeout!"</font><font>); <b>return</b> <b>super</b>.handleTimeout(request, task); } }; } } </font>
在 GitHub存储库中 找到本文的示例。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 如何使用Azure数据迁移将数据移动到云端
- iOS数据持久化:使用NSKeyedArchiver进行数据归档
- WordPress插件开发 -- 在插件使用数据库存储数据
- 使用Pig清洗数据
- 使用“数据驱动测试”之前
- 数据安全治理中的开发测试环境数据安全使用技术
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Open Data Structures
Pat Morin / AU Press / 2013-6 / USD 29.66
Offered as an introduction to the field of data structures and algorithms, Open Data Structures covers the implementation and analysis of data structures for sequences (lists), queues, priority queues......一起来看看 《Open Data Structures》 这本书的介绍吧!