Spring MVC,Rest Ajax 调用和会话范围对象



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

目前我们有一个解决方案,但并不总是真正运作良好。

MVC 控制器获取 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 方法来询问进度的状态。

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)显示进度状态时,一个好的解决方案是什么样子的。提前谢谢你。

我使用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
}
});
}
}

您还需要更改控制器方法来检索 ajax 请求,如下所示:

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

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

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

最新更新