Spring MVC,Rest Ajax Call和Session Scope Objects

时间:2017-05-17 12:24:19

标签: ajax rest spring-mvc session thymeleaf

我想解决以下问题。我有一个带Thymeleaf的Spring-MVC应用程序,有一个post请求(由表单发送)我触发一个模拟任务,可能需要几分钟。任务处理大量数据,我们希望通过JavaScript获得进度条。如果有两个会话,则应独立触发模拟,并且每个浏览器都会显示其进度状态。

目前我们有一个解决方案,一直不能很好地运作。

MVC Controller获取Post请求:

@Autowired SimulatorView view;  // SESSION SCOPE
@PostMapping("/view")
public String run(@ModelAttribute(CHECKS) ChecksDto checksWrapper, Model model) throws InterruptedException, ExecutionException {
    view.setStatisticDto(simulate(checksWrapper)); // Can take several minutes
    return "simulation/result :: simulated";
}

当我在我的WebGUI上触发模拟时,会显示一个进度条,并且通过JavaScript我经常调用Rest Methods来询问进度的状态。

RestController
@RequestMapping("simulation/api")
public class SimulatorApi {
    @Autowired SimulatorView view;  // SESSION SCOPE

    @RequestMapping("/progressStream")
    public double progressStream() {
        return view.getProgress().progressStream();
    }   

    @RequestMapping("/progressInvoice")
    public double progressInvoice() {
        return view.getProgress().progressInvoice();
    }
}

我的JavaScript代码段如下:

function registerSimulationRunEvent() {
    // this is the id of the form
    $("#simulatorForm").submit(function(e) {
        handleSimulationStarted();

        var url = location.protocol + "//" + location.host + "/fdsclient/simulation/view";

        $.ajax({
            type: "POST",
            url: url,
            data: $("#simulatorForm").serialize(), // serializes the form's elements.
            success:    function(data) { handleSimulationFinished(); },
            error:      function(xhr, error) { handleSimulationError(); }
        });

        e.preventDefault(); // avoid to execute the actual submit of the form.
    });
}

function handleSimulationStarted() {
    replaceResultPanelRunning(); // THYMELEAF FRAGMENT EXCHANGE
}

function handleSimulationFinished() {
    stopResultPanelAnimation(); // STOP PROGRESS BAR ANIMATION
    replaceResultPanelSimulated(); // EXCHANGE THYMELEAF FRAGMENT
}

function handleSimulationError() {
    stopResultPanelAnimation();
    replaceResultPanelError();
}

function replaceResultPanelRunning() {
    var url = // URL;
    $("#resultDiv").load(url);
    startResultPanelAnimation();
}

// ANIMATION

var animationInterval = null;

function startResultPanelAnimation() {
    animationInterval = setInterval(animateResultPanel,4000);
}

function stopResultPanelAnimation() {
    clearInterval(animationInterval); // stop the interval
}

function animateResultPanel() {
    $("#simulatorProgressLabel").animate({opacity: '0.4'}, "slow");
    $("#simulatorProgressLabel").animate({opacity: '1.0'}, "slow");
}

我知道使用会话范围进行休息服务是一件坏事,但我还不知道什么是一个好的和简单的解决方案。另一方面,目前不同的浏览器可以独立模拟,但并不总是进度条工作(特别是当第一次触发时大多数都不起作用)。 IE11仅在激活开发人员工具时才有效。在进度时停用工具时,进度条会停止增长。

我想知道的是,当使用模板引擎与Spring-MVC和Thymeleaf触发流程并通过Javascript(作为JQUery)显示进度状态时,一个好的解决方案是怎样的。先感谢您。

2 个答案:

答案 0 :(得分:0)

我使用Jquery AJAX POST提交做了类似的事情。你可以做这样的事情。这将把POST请求作为JSON格式提交给控制器并等待响应。在此等待期间可以显示进度UI组件。

              //Start Progress display
              function setStatistic(){

                    var data = JSON.stringify(//build your ChecksDto)
                    if (data) {
                        $.ajax({
                            url : '/view',
                            headers : {
                                'Content-Type' : 'application/json'
                            },
                            method : 'POST',
                            dataType : 'json',
                            data : data,
                            success : function(data) {
                                if (data.status == 200) {
                                    // Stop Progress display
                                    // Handle success status
                                } 
                            },

                            error : function(xhr, status, error) {
                                // Stop Progress display
                                // Handle errors here
                            }
                        });
                    }
                }

您还需要更改Controller方法以检索ajax请求,如下所示,

@ResponseBody
@PostMapping("/view")
public String run(@RequestBody ChecksDto checksWrapper, Model model) throws InterruptedException, ExecutionException

答案 1 :(得分:0)

至少我在另一个Stackoverflow页面找到了解决方案。神奇的词是将ajax缓存设置为false。

$.ajaxSetup ({
    // Disable caching of AJAX responses */
    cache: false
});