也许我没有以正确的方式提出问题,但这是另一次尝试,这次我会更加彻底。我做了一个超级简单的项目来举例说明我想要实现的目标。
我正在使用netbeans和struts 1.3。
我有这个非常简单的形式:
<html:form action="/firstUse.do" enctype="multipart/form-data" method="post">
<html:hidden property="anyname" value="whatevername" />
<input type="file" name="file" />
<input type="submit" value="Submit" />
</html:form>
我有我的ActionForm:
public class MyActionForm extends org.apache.struts.action.ActionForm {
private org.apache.struts.upload.FormFile file;
private String anyname;
public FormFile getFile() {
return file;
}
public void setFile(FormFile file) {
this.file = file;
}
public String getAnyname() {
return anyname;
}
public void setAnyname(String anyname) {
this.anyname = anyname;
}
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
int tamArchivo = file.getFileSize();
String nomArchivo = file.getFileName();
String extArchivo = nomArchivo.substring(nomArchivo.indexOf(".") + 1).toUpperCase();
if (tamArchivo <= 0) {
errors.add("", new ActionMessage("documentosEntregados.imagenVacia"));
} else if (tamArchivo >= 1048576) { // 1 Mega
errors.add("", new ActionMessage("documentosEntregados.imagenGrande"));
}
return errors;
}
}
我有我的行动:
public class FirstUse extends org.apache.struts.action.Action {
private static final String SUCCESS = "success";
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
MyActionForm myf = (MyActionForm) form;
String name;
String filename;
name = myf.getAnyname();
FormFile file = myf.getFile();
filename = file.getFileName();
System.out.println("FirstUse Action");
System.out.println(name);
System.out.println(filename);
return mapping.findForward(SUCCESS);
}
}
我有我的过滤器:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
Throwable problem = null;
try {
String strPath = ((HttpServletRequest) request).getServletPath();
if (strPath.endsWith("firstUse.do")) {
System.out.println("Entered filter first");
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(httpReq);
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = filterConfig.getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(reqWrapper);
Iterator<FileItem> iter = items.iterator();
if (!iter.hasNext()) {
System.out.println("iter super empty");
} else {
System.out.println("iter not super empty");
while (iter.hasNext()) {
FileItem item = iter.next();
if (item.isFormField()) {
System.out.println("Field name: " + item.getFieldName() + " Field value: " + item.getString());
} else {
System.out.println("File found");
}
}
}
System.out.println("Finished FirstUse, Now I want to do a second use");
chain.doFilter(reqWrapper, response);
}else{
chain.doFilter(request, response);
}
} catch (Throwable t) {
System.out.println("reqWrapper emtpy or not accessible");
problem = t;
t.printStackTrace();
}
if (problem != null) {
if (problem instanceof ServletException) {
throw (ServletException) problem;
}
if (problem instanceof IOException) {
throw (IOException) problem;
}
}
}
当我按下提交时,会调用过滤器,我在此处提交请求:
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(httpReq);
现在,关注下一个,这是我的问题。我要解释一下这种行为以及我想要实现的目标。
如果我先拨打下一行:
chain.doFilter(reqWrapper, response);
该操作正确执行,我开始系统记录我的数据:
FirstUse Action
whatevername
Elastix.jpg
Finished FirstUse, Now I want to do a second use
iter super empty
但是当我尝试用apache commons迭代请求时,在这里:
List<FileItem> items = upload.parseRequest(reqWrapper);
Iterator<FileItem> iter = items.iterator();
if (!iter.hasNext()) {
System.out.println("iter super empty");
}
POST数据不可访问,所以我得到一个空的迭代器,流被关闭,这就是抛出的apache常见的fileupload异常。
现在,如果我首先执行迭代,而不是调用chain.doFilter,迭代就完成了,我得到了我的结果:
iter not super empty
Field name: anyname
Field value: whatevername
File found
但当它到达chain.doFilter时,POST数据再次无法访问,所以当我尝试执行操作时,我得到空指针异常,它甚至在验证之前崩溃,如果验证表单打开,如表单值为null,后期数据消失。
所以,经过阅读了很多天和几个小时后,我才明白我在我的包装器中有效地保存了我的HttpServletRequest,但是当我再次尝试使用它时,当然客户端不发送因为它曾经给过一次iformation,所以这里的问题是:
我怎么能模仿这种行为?如何存储POST数据以便像我在我的过滤器中那样使用它。
答案 0 :(得分:0)
而不是这个: chain.doFilter(reqWrapper,response);
答案 1 :(得分:0)
如果有人遇到这个问题,或者由于某种原因试图实现这个问题,那么,我无法做到,但我找到了解决方法。 考虑到我的主要限制是不修改上传servlet(本例中的FirstUse.Action),我在这个问题中没有提到,我做了以下操作从表单中检索数据在我的行动已经执行之后。
首先,我将表单变量和方法更改为静态:
public class MyActionForm extends org.apache.struts.action.ActionForm {
private static org.apache.struts.upload.FormFile file;
private static String anyname;
public static FormFile getFile() {
return file;
}
public void setFile(FormFile file) {
this.file = file;
}
public static String getAnyname() {
return anyname;
}
public void setAnyname(String anyname) {
this.anyname = anyname;
}
然后,这样我就可以从我的过滤器中访问它们,只需调用表单方法:
String name = MyActionForm.getAnyname();
FormFile imagen = MyActionForm.getFile();
就是这样,我不再需要从客户端再次请求POST数据,我从表单中直接采取。非常简单的解决方案,但花了我很多天才明白,你不能指望客户端向你发送两次数据,并找出解决方法仍能获得两次数据。
希望这有帮助。