使用Spring Boot RESTful Web流式資料 | Techshard
流資料是向Web瀏覽器傳送資料的一種全新方法,可顯著加快頁面載入速度。通常,我們需要允許使用者在Web應用程式中下載檔案。當資料太大時,提供良好的使用者體驗變得非常困難,使用StreamingResponseBody,我們現在可以輕鬆地為高度併發的應用程式流式傳輸資料。
在本文中,我們將看一個使用StreamingResponseBody下載檔案的示例。在這種方法中,資料被處理並以塊的形式寫入OutputStream。
設定Spring Boot專案
為Maven POM新增一些基本依賴項:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <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> |
我們現在將建立一個控制器並新增一個API端點以供下載。這是完整的控制器。
@RestController @RequestMapping ("/api") public class DownloadController { private final Logger logger = LoggerFactory.getLogger(DownloadController.class); @GetMapping (value = "/download", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<StreamingResponseBody> download(final HttpServletResponse response) { response.setContentType("application/zip"); response.setHeader( "Content-Disposition", "attachment;filename=sample.zip"); StreamingResponseBody stream = out -> { final String home = System.getProperty("user.home"); final File directory = new File(home + File.separator + "Documents" + File.separator + "sample"); final ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream()); if(directory.exists() && directory.isDirectory()) { try { for (final File file : directory.listFiles()) { final InputStream inputStream=new FileInputStream(file); final ZipEntry zipEntry=new ZipEntry(file.getName()); zipOut.putNextEntry(zipEntry); byte[] bytes=new byte[1024]; int length; while ((length=inputStream.read(bytes)) >= 0) { zipOut.write(bytes, 0, length); } inputStream.close(); } zipOut.close(); } catch (final IOException e) { logger.error("Exception while reading and streaming data {} ", e); } } }; logger.info("steaming response {} ", stream); return new ResponseEntity(stream, HttpStatus.OK); } } |
在此API端點中,我們從目錄中讀取多個檔案並建立zip檔案。我們在StreamingResponseBody中執行此過程。在使用 ResponseEntity將寫入的資訊傳遞迴客戶端之前, 會將資料直接寫入OutputStream 。這意味著下載過程將立即在客戶端上啟動,而伺服器正在處理並以塊的形式寫入資料。
動伺服器並使用http:// localhost:8080 / api / download測試此端點 。
使用StreamingResponseBody時,強烈建議配置Spring MVC中使用的TaskExecutor來執行非同步請求。TaskExecutor是一個抽象Runnable執行的介面。
讓我們配置TaskExecutor。這是AsyncConfiguration類,它使用WebMvcCofigurer配置超時,並且還註冊在超時時呼叫的攔截器,以防您需要一些特殊處理。
@Configuration @EnableAsync @EnableScheduling public class AsyncConfiguration implements AsyncConfigurer { private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class); @Override @Bean (name = "taskExecutor") public AsyncTaskExecutor getAsyncExecutor() { log.debug("Creating Async Task Executor"); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new SimpleAsyncUncaughtExceptionHandler(); } /** Configure async support for Spring MVC. */ @Bean public WebMvcConfigurer webMvcConfigurerConfigurer(AsyncTaskExecutor taskExecutor, CallableProcessingInterceptor callableProcessingInterceptor) { return new WebMvcConfigurer() { @Override public void configureAsyncSupport(AsyncSupportConfigurer configurer) { configurer.setDefaultTimeout(360000).setTaskExecutor(taskExecutor); configurer.registerCallableInterceptors(callableProcessingInterceptor); WebMvcConfigurer.super.configureAsyncSupport(configurer); } }; } @Bean public CallableProcessingInterceptor callableProcessingInterceptor() { return new TimeoutCallableProcessingInterceptor() { @Override public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception { log.error("timeout!"); return super.handleTimeout(request, task); } }; } } |
在GitHub儲存庫中找到本文的示例。
相關文章
- 【流式傳輸】使用Spring Boot實現ChatGpt流式傳輸Spring BootChatGPT
- 使用Docker實現Spring Boot Restful Web服務案例原始碼DockerSpring BootRESTWeb原始碼
- Spring boot restful api demoSpring BootRESTAPI
- spring boot構建restful服務Spring BootREST
- Spring Boot中使用PostgreSQL資料庫Spring BootSQL資料庫
- 使用Spring Boot開發Web專案Spring BootWeb
- Spring Boot 構建 Restful API 和測試Spring BootRESTAPI
- Spring Boot實戰:Restful API的構建Spring BootRESTAPI
- Spring Boot學習5:spring-boot web容器Spring BootWeb
- spring boot(三)web模組Spring BootWeb
- Java Web之Spring BootJavaWebSpring Boot
- Shiro+JWT+Spring Boot Restful簡易教程JWTSpring BootREST
- Spring Boot中使用Swagger2構建RESTful APIs介紹Spring BootSwaggerRESTAPI
- 使用Spring Boot配置JNDI資料來源 -Roy教程Spring Boot
- 使用Spring Boot配置多個資料來源 - UdithSpring Boot
- 【Spring Boot】使用JDBC 獲取相關的資料Spring BootJDBC
- Spring Boot中使用時序資料庫InfluxDBSpring Boot資料庫UX
- 使用Spring Boot實現資料庫整合配置案例Spring Boot資料庫
- Spring Boot入門系列(二十)快速打造Restful API 介面Spring BootRESTAPI
- 基於 Spring Boot 2.0 構建一個 RESTful WebServiceSpring BootRESTWeb
- Spring Boot實現Web SocketSpring BootWeb
- Spring Boot 的 Web 開發Spring BootWeb
- 使用 Spring 3 MVC HttpMessageConverter 功能構建 RESTful web 服務SpringMVCHTTPRESTWeb
- spring mvc實現Restful返回xml格式資料SpringMVCRESTXML
- Spring Boot 高效資料聚合之道Spring Boot
- Spring Boot(十八):使用 Spring Boot 整合 FastDFSSpring BootAST
- Spring Boot(五):Spring Boot Jpa 的使用Spring Boot
- 使用 Postgres、Debezium 和 Kafka 流式傳輸資料Kafka
- 使用Pandas IO工具流式傳輸源資料
- Spring Boot學習3:web篇(中)-Spring boot Rest學習Spring BootWebREST
- Spring Boot 2.0(四):使用 Docker 部署 Spring BootSpring BootDocker
- Spring Boot(十一):Spring Boot 中 MongoDB 的使用Spring BootMongoDB
- Spring Boot(十六):使用 Jenkins 部署 Spring BootSpring BootJenkins
- Spring Boot(三):Spring Boot 中 Redis 的使用Spring BootRedis
- 使用 Spring Boot 和 @WebMvcTest 測試 MVC Web ControllerSpring BootWebMVCController
- Spring Boot(二):Web 綜合開發Spring BootWeb
- Spring Boot Web Error Page處理Spring BootWebError
- Spring Boot (二):Web 綜合開發Spring BootWeb