我想解决以下问题。我有一个带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)显示进度状态时,一个好的解决方案是怎样的。先感谢您。
答案 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
});