当前位置: 首页 > news >正文

深圳我的网站深圳市工程交易服务网宝安

深圳我的网站,深圳市工程交易服务网宝安,网站平台怎么建立,公司网站设计图01 引言 之前专门介绍过流式响应的数据的接收、发送以及使用SSE由服务端推送数据的文章,但是要求前端必须使用EventSource订阅实现。 有没有通过直接通过浏览器访问或者Fetch API直接调用的方式呢?效果还能和ChatGPT一样,实现打字机的效果呢&…

01 引言

之前专门介绍过流式响应的数据的接收、发送以及使用SSE由服务端推送数据的文章,但是要求前端必须使用EventSource订阅实现。

有没有通过直接通过浏览器访问或者Fetch API直接调用的方式呢?效果还能和ChatGPT一样,实现打字机的效果呢?

当然有。Spring框架在4.2及以后引入了强大额异步响应特性,其中ResponseBodyEmitterStreamingResponseBody是处理 HTTP 响应流式输出的两大核心利器,既不阻塞线程又不影响系统的相应能力。

我们一起了解一下吧!

02 StreamingResponseBody

全限定类名:

org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody

2.1 简介

StreamingResponseBody是一个函数式接口,适用于需要直接向 HttpServletResponse 的输出流写入原始字节数据的场景。它提供了一种低层次、高效的方式来流式传输数据。

StreamingResponseBody没有默认的实现,只有一个方法writeTo()。将文件或者数据直接写入输出流中,可以通过输出流的flush()方法,将数据刷出磁盘,减少内存的占用。

当我们需要将大量的数据或者文件响应给客户端时,由于处理耗时合作和内存的限制,我们就可以通过这种方式,逐步将数据响应给客户端,既可以提高用户体验又可以节省内存。

2.2 最佳实践

为了演示的方便,我们选择将文本内容逐步输出到浏览器端。

代码案例

间隔1s将数据包传给客户端:

@GetMapping(value = "/srb")
public StreamingResponseBody srb(HttpServletResponse response) {response.setContentType(MediaType.TEXT_EVENT_STREAM_VALUE);StreamingResponseBody stream = os -> {for (int i = 0; i < 5; i++) {String data = "SRB 数据包【"+(i+1)+"】\n";os.write(data.getBytes());System.out.print(data);// 刷出磁盘os.flush();try {// 间隔1sThread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}};return stream;
}

因为没有默认的实现,这里使用了匿名内部类实现。

响应结果

03 ResponseBodyEmitter

全限定类名:

org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter

3.1 简介

ResponseBodyEmitter是一个类,官方还给出了具体的使用案例。该类使用异步线程发送数据,最终需要使用complete()结束数据的传输,否则就会一直等待的状态。

有没有发现我们之前介绍的SseEmitterResponseBodyEmitter有点类似,SseEmitter其实是ResponseBodyEmitter的子类。

SseEmitter作为特殊的ResponseBodyEmitter,专门支持Server-Sent Events的。

ResponseBodyEmitter 的抽象层次更高。它不仅可以发送字节,更重要的是可以发送对象,这些对象会被配置的 HttpMessageConverter 转换后发送(如转换为 JSON)。它允许你多次发送数据,非常适合服务器端事件(Server-Sent Events, SSE)或分块 JSON

3.2 最佳实践

代码案例

@GetMapping(value = "/rbe")
public ResponseBodyEmitter rbe(HttpServletResponse response) {response.setContentType(MediaType.TEXT_EVENT_STREAM_VALUE);ResponseBodyEmitter emitter = new ResponseBodyEmitter(0L);CompletableFuture.runAsync(() -> {for (int i = 0; i < 5; i++) {String data = "RBE 数据包【"+(i+1)+"】\n";try {emitter.send(data);System.out.print(data);// 间隔1sThread.sleep(1000);} catch (Exception e) {throw new RuntimeException(e);}}emitter.complete();});return emitter;
}

响应结果

04 注意事项

两个类的案例中均有一行设置ContentType类型的代码:

response.setContentType(MediaType.TEXT_EVENT_STREAM_VALUE);

设置响应类型为text/event-stream,这一步很关键。否则直到全部的结果返回才会展示在浏览器端。

@GetMappingproduces属性并不能解决该问题,produces指定返回的内容类型,仅当request 请求头中的(Accept)类型中包含该指定类型才返回。

05 番外

聊到异步线程的响应,又想到了另外一个Spring MVC 专门处理异步请求的类DeferredResult,用法类似ResponseBodyEmitter,不同的是DeferredResult只能设置一次结果。

@GetMapping("/async")
public DeferredResult<String> async() {DeferredResult<String> deferredResult = new DeferredResult<>();CompletableFuture.runAsync(() -> {System.out.println("DeferredResult触发,等待结果");String data = "DeferredResult 数据包";try {// 间隔1sThread.sleep(2000);deferredResult.setResult(data);System.out.println("DeferredResult触发,完结");} catch (Exception e) {throw new RuntimeException(e);}});return deferredResult;
}

执行结果发现:他会等待deferredResult.setResult(data)发送数据之后才会结束响应。

http://www.dtcms.com/a/519325.html

相关文章:

  • php制作wap网站开发我国酒店网站建设存在的问题
  • 金坛网站建设企业手机网站建设渠道
  • 做网站要不要钱东莞网站快速优化排名
  • 做微信营销网站建设dw个人简历网页制作
  • 建个免费的销售网站好asp net4.0网站开发
  • 给个能看的网站中国500强企业名称
  • 网站一般用什么免费字体云主机wordpress
  • 旅游网站流程图电子商务网站开发的视频
  • 网站集约化建设流程专业网站建设价位
  • 食品网站建设客户需求调查表网站硬件费用
  • 深圳做网站600百度官网首页网址
  • 购物网站前端浮动特效怎么做西宁大型网站建设
  • 电脑网站制作教程网站空间商是什么意思
  • 网站开发范围游戏模板 wordpress
  • 企业网站 免费 php商标logo创意免费一键生成
  • 河南省建设监理协会官方网站大学英语精品课程网站建设
  • php公司网站什么是企业营销型网站?
  • 做音乐网站曲库在哪找带动画引导的网站
  • 加强政协机关网站建设辽宁省建设局网站
  • 广州微信网站开发公司内网网站建设主流语言
  • 互联网站备案信息查询tp3企业网站开发百度云
  • 国外网站建设什么价格赤峰建设银行网站
  • 济南营销网站建设价格今天高清视频免费播放
  • 沈阳网站建设策划造价工程师注册公示查询
  • 网站设计类型湘潭城乡建设发展集团网站
  • 赤坎手机网站建设毕业设计音乐网站开发背景
  • 东铁匠营网站建设怎么做网站的域名解析
  • 黑龙江公司网站开发自己如何建设个网站首页
  • 湖南电子科技网站建设深圳网站建设电话咨询
  • 盐城高端网站制作公司地方性小网站的建设