SpringBoot AsyncContext printWriter 推送数据到前端 观察者模式
程序员文章站
2024-01-16 12:33:10
做了一个功能,前端查看一些数据, 而数据在后端 是通过大量的分析 比较 得到了, 时间比较长! 假如得到这些数据(List
做了一个功能,前端查看一些数据, 而数据在后端 是通过大量的分析 比较 得到了, 时间比较长! 假如得到这些数据(list<object>)需要10分钟, 所以现在只要后端得到一条数据 <object>就直接推送到前端;
使用观察者模式, 和 asynccontext 异步处理
视图大概是这样
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>
下一篇: Java基础之数组