欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot AsyncContext printWriter 推送数据到前端 观察者模式

程序员文章站 2022-04-09 18:17:10
做了一个功能,前端查看一些数据, 而数据在后端 是通过大量的分析 比较 得到了, 时间比较长! 假如得到这些数据(List)需要10分钟, 所以现在只要后端得到一条数据 就直接推送到前端; 使用观察者模式, 和 AsyncContext 异步处理 视图大概是这样 OK ......

做了一个功能,前端查看一些数据, 而数据在后端 是通过大量的分析 比较 得到了, 时间比较长! 假如得到这些数据(list<object>)需要10分钟, 所以现在只要后端得到一条数据 <object>就直接推送到前端;

使用观察者模式, 和  asynccontext 异步处理

视图大概是这样

SpringBoot   AsyncContext printWriter  推送数据到前端   观察者模式

ok,如图所示贴上代码

1.被观察者

 1 import java.util.arraylist;
 2 import java.util.list;
 3 import java.util.observable;
 4 
 5 import org.apache.commons.lang3.stringutils;
 6 
 7 import com.data2wisdom.res.dsmgr.common.stringutil;
 8 
 9 public class forginrelation extends observable {
10     private int total;
11     private int stepnum; //比对到第n个
12     private string relationid;
13     private int status = 0;  //比对状态    0:初始化    ,  1 :正在比对,  2:比对完成 , 3:异常
14     
15     private list<forginrelationobj> ffos = new arraylist<>();
16     
17     
18     
19     //这里是通知观察者
20     public void addonefr(forginrelationobj relationobj) {
21         system.out.println("执行了添加操作");
22         this.ffos.add(relationobj);
23         setchanged();
24         notifyobservers();
25     }
26     

2,,观察者

 2 
 3 import java.io.ioexception;
 4 import java.io.printwriter;
 5 import java.util.arraylist;
 6 import java.util.list;
 7 import java.util.observable;
 8 import java.util.observer;
 9 
10 import javax.servlet.asynccontext;
11 
12 import org.apache.log4j.logger;
13 
14 import com.google.gson.gson;
15 
16 public class findrelationobserver implements observer{
17     private static logger log = logger.getlogger(findrelationobserver.class);
18     private asynccontext  async;    
19     private int num ;
20     
21     public findrelationobserver(asynccontext  async,forginrelation forginrelation) {
22         super();
23         this.async = async;
24         forginrelation.addobserver(this);//添加被观察者
25     }
26 
27     @override
28     public void update(observable fr, object arg) {
29         try {
30             printwriter printwriter = null;
31             try {
32                 printwriter = async.getresponse().getwriter();
33             } catch (ioexception e) {
34                 e.printstacktrace();
35                 log.info("异步获取数据异常:"+e);    
36             }
37           //业务逻辑可以不看
38             forginrelation forginrelation = (forginrelation)fr;
39             list<forginrelationobj> ffos = forginrelation.getffos();
40             list<forginrelationobj> tempdata = new arraylist<>();
41             int temp = num;
42             num =  ffos.size();
43             for (int i = temp; i < num ; i++) {
44                 tempdata.add(ffos.get(i));
45             }
46             gson gson = new gson();
47             string json = gson.tojson(tempdata);
        //这里是数据输出到前端, flush一下 48 printwriter.write("<script> parent.datarender('"+json+"'); </script>"); //parent中打开, 看最后面的页面请求方式 49 printwriter.flush(); 50 51 if(forginrelation.getstatus() == 2 || forginrelation.getstatus() == 3) { 52 printwriter.close(); 53 forginrelation.deleteobserver(this);//异步结束,移除观察者 54 async.complete();//异步结束 55 } 56 } catch (exception e) { 57 58 e.printstacktrace(); 59 } 60 } 61 62 }

3.请求接口

 1 @requestmapping(value = "/result", method = { requestmethod.get })
 2     public void index(httpservletresponse response,httpservletrequest request,string relationid) {    
 3         response.setcontenttype("text/html;charset=utf-8");
 4         response.setcharacterencoding("utf-8");
 5         asynccontext async = null;
 6         printwriter writer = null;
 7         forginrelation relation = null;
 8         
 9         try {
10             async = request.startasync(request,response);
11             async.settimeout(0);  //超时设置
34             relation = relationmap.getforginrelationbyid(relationid);
35             async.addlistener(new forginrelationasynclistener());
36             async.start(new asyncresult(async, relation)); //这里由于数据传递需要实现runnable 所以包装了个对象asyncresult
39         }catch (exception e) {
40         
41             e.printstacktrace();
42             logger.info(e);
43         
44         }finally {
45             
46         } 
 1 import javax.servlet.asynccontext;
 2 
 3 public class asyncresult  implements runnable{
 4     private asynccontext  async;    
 5     
 6     private forginrelation relation;
 7     
 8     public asyncresult(asynccontext async,forginrelation relation){
 9         this.async = async;
10         this.relation = relation;
11     }
12 
13 
14     @override
15     public void run() {
16         new findrelationobserver(async, relation);
17     }

4.前端请求 没理解,需要form表单请求 不然会出问题,我也不理解啥原因

 1 <body>
 2 
 3     <div class="form-body layer-content">
 4 
 5         <div>
 6         
 7             <div style="padding:20px;">
 8                 <div class="form-group">
 9                 <!--     <h3 class="margin-bottom-10 sub">新增表</h3> -->
10                     <table class="layui-table" id="forginrelation"></table>
11                 </div>
12             </div>
13             
14         </div>
15         
16 
17     </div>
18 
19 
20     <div id="content" class="display_none" >
21         <form id="queryform" name="queryform" action="/rest/combing/findr/result" method="get">
22             <input type="text"  id="relationid" name="relationid" />
23         </form>
24     </div>
25 
26     <iframe id="datacometframe" src="" name="datacometframe" width="0" height="0" ></iframe>
     <script type="text/javascript">

      $("#queryform").attr("target", "datacometframe");  //需要在iframe中打开
      $("#relationid").val($("base").attr("relationid"))  //我的业务请求参数
      $("#queryform").submit();    //提交表单

      function datarender(data){
        console.log("datarender:");
        console.log(data);
      }

    </script>
27 </body>