保存表单中的 HTTP POST 数据以便在 Java 中多次使用它,可能吗?
Save HTTP POST Data from Form to use it more than once with Java, possible?
也许我没有以正确的方式提出问题,但这是另一种尝试,这次我会更彻底。我做了一个超级简单的项目来举例说明我想要实现的目标。
我正在使用 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常见文件上传异常。
现在,如果我先执行迭代,而不是调用 chain.doFilter,迭代就完成了,我得到了我的结果:
iter not super empty
Field name: anyname
Field value: whatevername
File found
但是当它到达 chain.doFilter 时,再次无法访问 POST 数据,所以当我尝试执行该操作时,我得到空指针异常,它甚至在验证之前崩溃如果打开验证表单,因为表单值为空,post 数据将消失。
所以,在阅读了许多天和许多小时之后,我开始明白我在我的包装器中有效地保存了我的 HttpServletRequest,但是,当我再次尝试使用它时,客户端当然不会'不再发送信息,因为已经发送过一次了,所以这里的问题是:
我如何模拟这种行为?我如何存储 POST 数据以像我在过滤器中尝试做的那样使用它两次。
你试过这个吗:
chain.doFilter(请求,响应);
而不是这个:
chain.doFilter(reqWrapper, 响应);
如果有人遇到此问题,或出于某种原因尝试实施此问题,那么,我做不到,但我找到了解决方法。 考虑到我的主要限制是不修改上传 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 数据,我直接从表单中获取数据。非常简单的解决方案,但我花了很多天才明白,您不能指望客户端向您发送两次数据,然后想出一个变通方法来仍然获取两次数据。
希望对您有所帮助。
也许我没有以正确的方式提出问题,但这是另一种尝试,这次我会更彻底。我做了一个超级简单的项目来举例说明我想要实现的目标。
我正在使用 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常见文件上传异常。
现在,如果我先执行迭代,而不是调用 chain.doFilter,迭代就完成了,我得到了我的结果:
iter not super empty
Field name: anyname
Field value: whatevername
File found
但是当它到达 chain.doFilter 时,再次无法访问 POST 数据,所以当我尝试执行该操作时,我得到空指针异常,它甚至在验证之前崩溃如果打开验证表单,因为表单值为空,post 数据将消失。
所以,在阅读了许多天和许多小时之后,我开始明白我在我的包装器中有效地保存了我的 HttpServletRequest,但是,当我再次尝试使用它时,客户端当然不会'不再发送信息,因为已经发送过一次了,所以这里的问题是:
我如何模拟这种行为?我如何存储 POST 数据以像我在过滤器中尝试做的那样使用它两次。
你试过这个吗: chain.doFilter(请求,响应);
而不是这个: chain.doFilter(reqWrapper, 响应);
如果有人遇到此问题,或出于某种原因尝试实施此问题,那么,我做不到,但我找到了解决方法。 考虑到我的主要限制是不修改上传 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 数据,我直接从表单中获取数据。非常简单的解决方案,但我花了很多天才明白,您不能指望客户端向您发送两次数据,然后想出一个变通方法来仍然获取两次数据。
希望对您有所帮助。