spring mvc+jQuery ajax 实现后台数据实时返回前端

最近项目页面要做一个一键检测的功能,要求就是点击一键检测按钮后,前端实时输出后台检测信息,主要用ajax轮询实现。

代码从项目剥离出来的,未经测试。

控制层

package com.huak.web.home.health;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.huak.health.type.PollingType;
import com.huak.tools.HealthItem;
import com.huak.web.home.BaseController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Copyright (C), 2009-2012, XXXX.<BR>
 * ProjectName:emc<BR>
 * File name:  com.huak.web.home.health<BR>
 * Author:  lichao  <BR>
 * Project:emc    <BR>
 * Version: v 1.0      <BR>
 * Date: 2017/8/22<BR>
 * Description:   健康指数  <BR>
 * Function List:  <BR>
 */
@Controller
@RequestMapping("/health")
public class HealthController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static Queue<String> CONNECTIONS = new ConcurrentLinkedQueue<>();//消息队列

    private static boolean OVER = false;//标识

    private final static long TIMEOUT = 20000l;//超时时间

    @RequestMapping(method = RequestMethod.GET)
    public String page(Model model, HttpServletRequest request) {
        logger.info("跳转健康指数页面");
        model.addAttribute("healthItem", JSONArray.toJSONString(HealthItem.HEALTH_ITEM));
        return "health/inspect";
    }

    @RequestMapping(value = "/testing",method = RequestMethod.POST)
    @ResponseBody
    public void testing( HttpServletRequest request,HttpServletResponse response) {
        synchronized(this){
            CONNECTIONS.clear();
            OVER = false;
            //todo 业务数据入队列
            for(int i=0;i<20;i++){
                CONNECTIONS.offer(i+"次检测");
            }

            OVER = true;
        }

    }

    /**
     *
     *  开启长连接
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/polling",method = RequestMethod.GET)
    public @ResponseBody  DeferredResult<JSONObject> polling( HttpServletRequest request,HttpServletResponse response) {
        synchronized(this){
            DeferredResult<JSONObject> result = new DeferredResult<>(TIMEOUT,null);  //设置超时,超时返回null
            final JSONObject jo = new JSONObject();
            if(OVER && CONNECTIONS.isEmpty()){
                //消息接收完毕,返回结束标识
                jo.put(PollingType.END.getKey(),PollingType.END.getDes());
                result.setResult(jo);
            }else{
                //队列取值
                final String msg = CONNECTIONS.poll();
                jo.put(PollingType.MSG.getKey(),msg);
                result.setResult(jo);
                //结束后操作
                result.onCompletion(new Runnable() {
                    @Override
                    public void run() {
                        //System.out.println(jo.toJSONString());
                    }
                });
            }
            return result;
        }

    }




}

枚举

package com.huak.health.type;

/**
 * Copyright (C), 2009-2012,XXX.<BR>
 * ProjectName:emc<BR>
 * File name:  com.huak.health.type<BR>
 * Author:  lichao  <BR>
 * Project:emc    <BR>
 * Version: v 1.0      <BR>
 * Date: 2017/10/11<BR>
 * Description:   长连接返回标识  <BR>
 * Function List:  <BR>
 */
public enum PollingType {
    MSG("msg","消息"),
    NUM("num","异常数量"),
    END("end","结束");


    private String key;
    private String des;

    PollingType(String key, String des) {
        this.key = key;
        this.des = des;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }
}

页面js

$(function(){
    $("#runbtn").click(function() {
        polling();
        loadRuning1();
    });
});
    

function loadRuning1(){
    $.ajax({
        url : _web+"/health/testing",
        type : "POST",
        cache : false,
        dataType: "json",
        success : function(data) {
        }
    });
}

function polling(){
    $.ajax({
        url : _web+"/health/polling",
        type : "GET",
        timeout:30000,
        cache : false,
        dataType:"JSON",
        success : function(data) {
            if(data != null && data != ""){
                console.info(data);
                console.info(data.msg);
                console.info(data.end);
                if(data.end==null||data.end==""||data.end=="undefined"){
                    polling();
                }
            }else{
                polling();
            }

        },
        complete:function(XMLHttpRequest,status){
            console.info("status"+status);
            if(status=='timeout') {//超时,status还有success,error等值的情况
                polling();
            }
        }
    });
}

 

转载于:https://my.oschina.net/905430/blog/1549080

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值