[英]Maintain Conversation After Exception (Handled in Pages.xml)
我正在一个我最初没有开始的项目中工作,所以有很多工件和约定我需要付出大量努力才能更改。 无论如何,这就是问题所在。 我需要将多个文件上传(在“主”父页面上正在编辑的实体的“孩子”)上传到服务器上,以便在用户提交时将其发送到其他地方。 上载的文件还包括用户输入的元数据。 我想做到这一点的最好方法是渲染一个“对话”,该对话具有一个iframe进行上传并具有元数据的输入。 然后,我创建了Seam的多部分过滤器的覆盖(使用安装优先级),该过滤器使用Apache文件上传jar和自定义请求包装器,该包装器将我的信息携带到服务器上的操作调用中。 除非我将异常从过滤器中抛出,否则一切都会顺利进行,例如,如果请求大小太大。 异常是由pages.xml声明捕获并处理的。
<exception class="org.jboss.seam.web.FileUploadException">
<redirect view-id="#{facesContext.externalContext.requestServletPath}">
<message severity='ERROR'>#{org.jboss.seam.handledException.message}</message>
</redirect>
</exception>
当我通常在对话框框架中提交表单时,框架中的对话(根据我的意愿)仍然存在,当捕获到异常时,我得到了一个新对话(如我所愿)。 我希望通过框架的全局消息区域中显示的异常传递的错误消息,但是我需要保持与以前相同的对话,因为在对话框中添加的“孩子”是“父”实体的孩子在主页上。 这是框架代码中的表格。 我尝试了s:button(不提交表单),尝试过的参数以及尝试了带有对话ID的隐藏输入。
<h:form id="attachmentModalForm" enctype="multipart/form-data" autocomplete="off" style="background-color: #FFFFFF;">
<ui:include src="layout/messages.xhtml" />
<div id="attachmentModalMain" class="modalMain">
<s:decorate id="attachmentDescriptionDecoration" template="layout/edit.xhtml" styleClass="twoCol">
<ui:define name="label">#{messages['contents.attachmentDialog.label.description']}<s:span styleClass="required">*</s:span></ui:define>
<h:inputText id="attachmentDescription" value="#{attachmentAction.description}" styleClass="textbox" />
</s:decorate>
<s:decorate id="attachmentFileDecoration" template="layout/edit.xhtml" styleClass="twoCol">
<ui:define name="label">#{messages['contents.attachmentDialog.label.file']}<s:span styleClass="required">*</s:span></ui:define>
<input id="attachmentFile" name="attachmentFile" type="file" />
</s:decorate>
</div>
<div id="attachmentModalSubmit" class="modalSubmit">
<h:commandButton id="attachmentSubmitButton" value="#{messages['action.text.submit']}" action="#{attachmentAction.addAttachment()}" onclick="attachmentSubmit();" />
<button id="attachmentCancelButton" type="button" value="#{messages['action.text.cancel']}" onclick="window.parent.hideAttachmentModal();">#{messages['action.text.cancel']}</button>
</div>
<input type="hidden" name="cid" value="#{conversation.id}" />
</h:form>
这是覆盖Seam多部分过滤器的过滤器。
package XXXXXXXXXXXXX.attachment;
import java.io.File;
import java.io.IOException;
import java.rmi.server.UID;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.annotations.web.Filter;
import org.jboss.seam.web.AbstractFilter;
/**
* This filter is used to override Seam's multipart filter so that we
* can have multiple temporary files on the server cued and ready to
* go to XXXXXXXXX. It uses the Apache Commons FileUpload objects to
* handle the parsing of the request and the temporary files.
*
*/
@Scope(ScopeType.APPLICATION)
@Name("org.jboss.seam.web.multipartFilter")
@Install(precedence = Install.APPLICATION)
@BypassInterceptors
@Filter(within={"org.jboss.seam.web.ajax4jsfFilter", "org.jboss.seam.web.exceptionFilter"})
public class MEDWareMultipartFilter extends AbstractFilter {
// This is unused, we always want temp files since we are caching before upload to XXXXXXXXX.
// Leaving it in to mirror Seam's multipart filter, in case it gets set from the components.xml.
@SuppressWarnings("unused") private boolean createTempFiles = true;
private int maxRequestSize = -1;
private String acceptedFileExtensions = "txt,pdf,doc,docx,xls,xlsx";
public void setCreateTempFiles(boolean createTempFiles) { }
public void setMaxRequestSize(int maxFileSize) {
this.maxRequestSize = maxFileSize;
}
public String getAcceptedFileExtensions() {
return acceptedFileExtensions;
}
public void setAcceptedFileExtensions(String acceptedFileExtensions) {
this.acceptedFileExtensions = acceptedFileExtensions;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!(response instanceof HttpServletResponse)) {
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (ServletFileUpload.isMultipartContent(httpRequest)) {
File repository = (File) this.getServletContext().getAttribute("javax.servlet.context.tempdir");
DiskFileItemFactory factory = new DiskFileItemFactory(0, repository);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(maxRequestSize);
List<FileItem> formItems = null;
try {
formItems = upload.parseRequest(httpRequest);
} catch (SizeLimitExceededException slee) {
throw new org.jboss.seam.web.FileUploadException("File size excededs maximum allowed.", slee);
} catch (FileUploadException fue) {
throw new org.jboss.seam.web.FileUploadException("Error uploading file.", fue);
}
Map<String, String> parameters = new HashMap<String, String>();
Map<String, File> fileParameters = new HashMap<String, File>();
if (formItems != null && formItems.size() > 0) {
for (FileItem item : formItems) {
if (item.isFormField()) {
parameters.put(item.getFieldName(), item.getString());
} else {
String fileName = item.getName();
// This is for IE7 (and Safari?) which sends the whole path.
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
if (!MyMultipartRequestUtils.isValidFileType(acceptedFileExtensions, fileName)) {
throw new org.jboss.seam.web.FileUploadException("The file type is not an accepted file type.");
}
File tempFile = null;
try {
tempFile = File.createTempFile(new UID().toString().replace(":", "-"), ".upload");
tempFile.deleteOnExit();
item.write(tempFile);
} catch (Exception e) {
throw new org.jboss.seam.web.FileUploadException("Error uploading file. Could not write file to server.");
}
fileParameters.put(fileName, tempFile);
}
}
}
MyMultipartRequestWrapper requestWrapper = new MyMultipartRequestWrapper(httpRequest, parameters, fileParameters);
chain.doFilter(requestWrapper, response);
} else {
chain.doFilter(request, response);
}
}
}
因此,重申一下,如果我使用框架上传文件,那么一切正常,框架继续进行相同的对话,将每个孩子添加到父级,如果我上传的文件太大,则会在全局消息中得到正确的消息框的最大面积,但是对话会增加,然后显然会将子级添加到新对话中的新父实体中。 任何帮助将不胜感激。
我刚刚在自定义请求包装器中添加了一个字段,以携带要处理的所有异常,然后在
#{attachmentAction.addAttachment()}
动作调用进一步拉高了请求链。 现在一切正常,我只是从那里添加我的面孔消息,并且对话没有像我成功上传一样增加。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.