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

做了一个功能,前端查看一些数据, 而数据在后端 是通过大量的分析 比较 得到了, 时间比较长! 假如得到这些数据(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>

猜你喜欢

转载自www.cnblogs.com/bignew/p/10023064.html