【发布时间】:2010-11-01 21:18:39
【问题描述】:
我正在使用 Dojo ProgressBar 来使用 execAndWait 拦截器在 Struts2 中显示一个长时间运行的进程。 execAndWait 拦截器为每个返回等待结果的调用将操作放在值堆栈上。但是,当结果类型为 JSON 时,动作只有动作的默认值。
这是我的 struts 动作配置
(我尝试对结果名称进行通配符,但这不起作用)
注意:我必须将我的 JSON 包装在一个 textarea 中,因为 Dojo 的 iframe.send 期望它被包装在一个文本区域。
<action name="upload" class="ProcessFileAction" method="upload">
<interceptor-ref name="agfStack" />
<interceptor-ref name="execAndWait">
<param name="delay">1000</param>
<param name="delaySleepInterval">500</param>
</interceptor-ref>
<result name="wait" type="json">
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<param name="wrapPrefix"><![CDATA[<html><body><textarea>]]></param>
<param name="wrapSuffix"><![CDATA[</textarea></body></html>]]></param>
<param name="includeProperties">percentComplete,processMessage,running</param>
</result>
<result name="success" type="json">
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<param name="wrapPrefix"><![CDATA[<html><body><textarea>]]></param>
<param name="wrapSuffix"><![CDATA[</textarea></body></html>]]></param>
<param name="includeProperties">percentComplete,processMessage,running</param>
</result>
<result name="error" type="json">
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<param name="wrapPrefix"><![CDATA[<html><body><textarea>]]></param>
<param name="wrapSuffix"><![CDATA[</textarea></body></html>]]></param>
<param name="includeProperties">percentComplete,processMessage,running</param>
</result>
</action>
这是我的 JSP
注意:我必须使用 iFrame.send 操作,因为我正在上传文件。由于我的 struts 结果对于初始等待返回与每次连续调用的结果相同,因此我也必须将 iframe.send 用于 AJAX 调用(而不是 xhrGet)。那是因为 iframe.send 期望 JSON 被包裹在一个文本区域中,而 xhrGet 没有。
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<script type="text/javascript">
dojo.require("dojo.io.iframe");
dojo.require("dijit.ProgressBar");
dojo.require('dojox.timing');
var t = new dojox.timing.Timer(<tiles:getAsString name="refreshTime" />);
t.onTick = function() {
dojo.io.iframe.send({
url: '<s:url action="upload" namespace="/" />',
method: "POST",
handleAs: "json",
load: function(response, ioArgs){
if(response.running) {
var progressPercent = response.percentComplete + "%";
var reportText = response.processMessage;
var uploadProgesssBar = dijit.byId("uploadProgress");
if(uploadProgesssBar == null) {
return;
}
uploadProgesssBar.update({progress:progressPercent, report:function() {return reportText;}});
}
else {
showById("progressDialogButtonDiv");
t.stop();
}
},
error: function(response, ioArgs) {
t.stop();
var progressPercent = response.percentComplete + "%";
var reportText = response.processMessage;
var uploadProgesssBar = dijit.byId("uploadProgress");
if(uploadProgesssBar == null) {
return;
}
uploadProgesssBar.update({progress:progressPercent, report:function() {return reportText;}});
showById("progressOkButton");
}
});
};
function showProgressBar() {
hideById("uploadForm");
showById("progressBar");
}
function hideProgressBar() {
hideById("progressBar");
showById("uploadForm");
}
function submitAndShowProgress(submitForm) {
dojo.io.iframe.send({
form: submitForm,
handleAs: "json",
load: function(response, ioArgs) {
submitForm.reset();
var progressPercent = response.percentComplete + "%";
var reportText = response.processMessage;
if(response.running) {
showProgressBar();
var uploadProgesssBar = dijit.byId("uploadProgress");
if(uploadProgesssBar == null) {
return;
}
uploadProgesssBar.update({progress:progressPercent, report:function() {return reportText;}});
t.start();
}
else {
createAndShowAlertDialog(reportText, "");
}
return response;
},
error: function(response, ioArgs) {
t.stop();
hideProgressBar();
createAndShowAlertDialog(response.processMessage, "An Error Occurred");
return response;
}
});
return false;
}
</script>
<div id="progressBar" class="hidden loading">
<div dojoType="dijit.ProgressBar" style="width:400px" jsId="uploadProgress" id="uploadProgress" annotate="true"></div>
<div class="hidden actionButtons" id="progressOkButton">
<button style="position: relative; left: 42px;" dojoType="dijit.form.Button" onClick="hideProgressBar(); return false;">Ok</button>
</div>
</div>
<s:form action="upload" namespace="/" enctype="multipart/form-data" id="uploadForm" method="post" onsubmit="return submitAndShowProgress(this);">
<s:file name="file" id="file" label="File" />
<s:submit id="submit" name="submit">Upload</s:submit>
</s:form>
这是我的操作:
(修剪)
public class ProcessFileAction implements LongRunning {
String processMessage = "Uploading...";
Integer percentComplete = 0;
Boolean running = true;
private FileProcessor fileProcessor;
private File file;
private String fileContentType;
private String fileFileName;
public String upload() throws Exception {
setProcessMessage("Processing File...");
setPercentComplete(10);
try {
if(!getFile().exists()) {
getFile().createNewFile();
}
File processedFile = getFileProcessor().process(getFile(), this);
} catch(Exception e) {
e.printStackTrace();
setProcessMessage("An error occurred while processing your file.");
setPercentComplete(100);
setRunning(false);
return ERROR;
}
setProcessMessage("Process Complete!");
setPercentComplete(100);
setRunning(false);
return SUCCESS;
}
...
}
public interface LongRunning {
public void setProcessMessage(String processMessage);
public String getProcessMessage();
public void setPercentComplete(Integer percentComplete);
public Integer getPercentComplete();
public void setRunning(boolean running);
public boolean isRunning();
}
我将查看 JSON 结果类型和 ExecAndWait 拦截器的代码以获取更多线索。
【问题讨论】:
标签: ajax json dojo struts2 progress-bar