以前寫過一篇文章:springmvc不斷輸出文本到網頁,採用的是對response不斷進行write和flush實現的。在spring 4.2版本的時候提供了一個SseEmitter能夠直接用來實現這個功能。html
@Controller @RequestMapping("/sse") public class SseEmitterController { private static final Logger LOGGER = LoggerFactory.getLogger(SseEmitterController.class); @Autowired @Qualifier("mvcTaskExecutor") ThreadPoolTaskExecutor mvcTaskExecutor; @GetMapping("") public SseEmitter sseDemo() throws InterruptedException { final SseEmitter emitter = new SseEmitter(0L); //timeout設置爲0表示不超時 mvcTaskExecutor.execute(() -> { try { for(int i=0;i<100;i++){ emitter.send("hello"+i); LOGGER.info("emit:{}","hello"+i); Thread.sleep(1000*1); } emitter.complete(); } catch (Exception e) { emitter.completeWithError(e); } }); return emitter; } }
輸出實例java
data:"hello0" data:"hello1" data:"hello2" data:"hello3" data:"hello4" data:"hello5" //......
除了使用上述的放入線程池的方式,也能夠直接調用標記有async的方法
若是不設置爲0,那麼若是SseEmitter在指定的時間(AsyncSupportConfigurer設置的timeout,默認爲30秒
)未完成會拋出異常git
org.springframework.web.context.request.async.AsyncRequestTimeoutException: null at org.springframework.web.context.request.async.TimeoutDeferredResultProcessingInterceptor.handleTimeout(TimeoutDeferredResultProcessingInterceptor.java:42) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.context.request.async.DeferredResultInterceptorChain.triggerAfterTimeout(DeferredResultInterceptorChain.java:75) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.context.request.async.WebAsyncManager$5.run(WebAsyncManager.java:392) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.onTimeout(StandardServletAsyncWebRequest.java:143) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.apache.catalina.core.AsyncListenerWrapper.fireOnTimeout(AsyncListenerWrapper.java:44) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.catalina.core.AsyncContextImpl.timeout(AsyncContextImpl.java:134) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:153) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:224) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) ~[tomcat-embed-core-8.5.16.jar:8.5.16] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar:8.5.16] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_71] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_71] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar:8.5.16] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_71]
SseEmitter在運行比較耗時的任務時很是好用,好比實時查看部署進度,好比查看定時任務的實時輸出等。github