h:如果h:form的enctype =“multipart / form-data”,commandButton不会触发操作。 [英] h:commandButton is not firing action if the h:form has enctype="multipart/form-data"

查看:177
本文介绍了h:如果h:form的enctype =“multipart / form-data”,commandButton不会触发操作。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JSF: 1.2



服务器: Weblogic b
$ b我试图实现多个文件上传。由于我需要支持IE7,所以我不能使用HTML5输入文件。所以我已经计划添加一个按钮,点击它将在页面中添加一个输入文件。


主要是我已经开始使用ADF Faces工作了。但是这没有奏效。这是表现出意想不到的方式。

我也尝试了Tomahawk的文件上传组件,但是问题出在这个组件上后,从后端添加一个新的文件上传创建的文件上传字段被清空;不是 UploadedFile 实例。但是这不符合我的要求。因为我需要显示文件上传器中的所有路径,直到点击最后的提交表单按钮。

然后我接受了apache commons fileupload的帮助。



我已经尝试过使用纯JSP和apaches fileupload,并且运行良好。



但是我想用JSF apaches fileupload,当我试图做到这一点,开始导致问题。



jspx页面如下:

 <?xml version ='1.0'encoding ='utf-8'?> 
xmlns:f =http://java.sun。 com / jsf / core
xmlns:h =http://java.sun.com/jsf/html>
< jsp:output omit-xml-declaration =truedoctype-root-element =HTML
doctype-system =http://www.w3.org/TR/html4/ loose.dtd
doctype-public = - // W3C // DTD HTML 4.01 Transitional // EN/>
< jsp:directive.page contentType =text / html; charset = utf-8/>
< f:view>
< html>
< head>
< meta http-equiv =Content-Type
content =text / html; charset = utf-8/>
< title>主页< / title>
< / head>
< body>
< h:form enctype =multipart / form-data>
< input type =filename =file/>
< h:commandButton value =Uploadaction =#{uploadBean.upload}/>
< / h:表格>
< / body>
< / html>
< / f:view>
< / jsp:root>

我创建了一个过滤器,因为我无法从 action 事件。



web.xml是:

 <?xml version ='1.0'encoding ='windows-1252'?> 
< web-app xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation =http://java.sun.com/xml / ns / javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
version =2.5xmlns =http://java.sun.com/xml/ NS / JavaEE的>
< context-param>
< param-name> javax.faces.STATE_SAVING_METHOD< / param-name>
< param-value>服务器< /参数值>
< / context-param>
< filter>
< filter-name> UploadFilter< / filter-name>
< filter-class> com.edfx.massupload.filter.UploadFilter< / filter-class>
< / filter>
< filter-mapping>
< filter-name> UploadFilter< / filter-name>
< servlet-name> Faces Servlet< / servlet-name>
< / filter-mapping>
< servlet>
< servlet-name> Faces Servlet< / servlet-name>
< servlet-class> javax.faces.webapp.FacesServlet< / servlet-class>
<加载启动> 1< /加载启动>
< / servlet>
< servlet-mapping>
< servlet-name> Faces Servlet< / servlet-name>
< url-pattern> / faces / *< / url-pattern>
< / servlet-mapping>
< welcome-file-list>
< welcome-file> /home.jspx< / welcome-file>
< / welcome-file-list>
< / web-app>

UploadFilter:

  import java.io.IOException; 

import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class UploadFilter implements Filter {
private FilterConfig _filterConfig = null;

public void init(FilterConfig filterConfig)throws ServletException {
_filterConfig = filterConfig;
}

public void destroy(){
_filterConfig = null;

$ b $ public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException {
System.out.println(Filter);
if(!(request instanceof HttpServletRequest)){
chain.doFilter(request,response);
return;
}

HttpServletRequest httpRequest =(HttpServletRequest)请求;

boolean isMultipartContent = ServletFileUpload.isMultipartContent(httpRequest);

if(!isMultipartContent){
chain.doFilter(request,response);
return;
}

long maxFileSize =(1024 * 1024 * 1024);
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding(UTF-8);
upload.setSizeMax(maxFileSize);
upload.setFileSizeMax(maxFileSize);

尝试{
列表< FileItem> items = upload.parseRequest(httpRequest);
System.out.println(items.size());
列表< FileItem> files = new ArrayList< FileItem>(); (FileItem item:items){
if(!item.isFormField()){
files.add(item);
}
}

httpRequest.setAttribute(files,files);
} catch(FileUploadException ex){
ex.printStackTrace();
}

chain.doFilter(request,response);


$ / code $ / pre
$ b $最后是托管bean: b
$ b

  import javax.faces.context.FacesContext; 

import javax.servlet.http.HttpServletRequest;

public class UploadBean {
public UploadBean(){
super();


public String upload(){
System.out.println(==== JYM);
HttpServletRequest httpRequest =(HttpServletRequest)FacesContext.getCurrentInstance()。getExternalContext()。getRequest();
System.out.println(httpRequest.getAttribute(files));
return;




$ b我的目标是动态地添加输入文件字段JavaScript或jQuery,在JSP中运行良好,我想在JSF中获得。
$ b 如果我删除 enctype =multipart / form-数据来自 h:form ,那么action方法正在执行,否则不会执行。


解决方案

在这里,

(FileItem item:items){
if(!item.isFormField()){
files.add(item);


$ / code $ / pre

你忽略了所有的表单字段,比如按钮本身。当继续这样的请求时,JSF将不知道一个按钮被调用,因此根本不排队任何操作。



您需要添加一个 else 来收集 Map< String,String []> 中的所有表单域,并用 HttpServletRequestWrapper ,它将所有的 getParameterXxx()调用映射到该映射上,最后继续使用包装请求过滤链。这样JSF会发现按钮被调用,然后排队到适当的动作。


JSF: 1.2

Server: Weblogic

I am trying to implement multiple file upload. As I need to give support for IE7 so I cannot use HTML5 input file. So I have planned to add a button, on clicking it will add a input file in the page.

Primarily I have started my work with ADF Faces. But that didn't worked. That was behaving in unexpected way.

I have also tried Tomahawk's file upload component, but the problem was with this component that after adding a new file upload from the backend the previously created file upload fields were get empty; not the UploadedFile instance. But this will not meet my requirement. As I need to show all the path in the file uploaders until the final Submit form button has been clicked.

Then I took help of apache commons fileupload.

I have tried this with pure JSP and apaches fileupload and that worked well.

But I want to implement it with JSF with apaches fileupload, and when I tried to do this it started causing issues.

The jspx page is given below:

<?xml version='1.0' encoding='utf-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html">
  <jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
              doctype-system="http://www.w3.org/TR/html4/loose.dtd"
              doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
  <jsp:directive.page contentType="text/html;charset=utf-8"/>
  <f:view>
    <html>
      <head>
        <meta http-equiv="Content-Type"
              content="text/html; charset=utf-8"/>
        <title>home</title>
      </head>
      <body>
        <h:form enctype="multipart/form-data">
            <input type="file" name="file"/>
            <h:commandButton value="Upload" action="#{uploadBean.upload}" />
        </h:form>
      </body>
    </html>
  </f:view>
</jsp:root>

I have created a filter as I cannot get the proper multipart request from the action event.

The web.xml is:

<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
  </context-param>
  <filter>
    <filter-name>UploadFilter</filter-name>
    <filter-class>com.edfx.massupload.filter.UploadFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>UploadFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>/home.jspx</welcome-file>
  </welcome-file-list>
</web-app>

The UploadFilter:

import java.io.IOException;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class UploadFilter implements Filter {
    private FilterConfig _filterConfig = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        _filterConfig = filterConfig;
    }

    public void destroy() {
        _filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("Filter");
        if (!(request instanceof HttpServletRequest)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest)request;

        boolean isMultipartContent = ServletFileUpload.isMultipartContent(httpRequest);

        if (!isMultipartContent) {
            chain.doFilter(request, response);
            return;
        }

        long maxFileSize = (1024 * 1024 * 1024);
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("UTF-8");
        upload.setSizeMax(maxFileSize);
        upload.setFileSizeMax(maxFileSize);

        try {
            List<FileItem> items = upload.parseRequest(httpRequest);
            System.out.println(items.size());
            List<FileItem> files = new ArrayList<FileItem>();            
            for (FileItem item : items) {
                if (!item.isFormField()) {
                    files.add(item);
                }
            }

            httpRequest.setAttribute("files", files);
        } catch (FileUploadException ex) {
            ex.printStackTrace();
        }        

        chain.doFilter(request, response);
    }
}

And lastly the managed bean:

import javax.faces.context.FacesContext;

import javax.servlet.http.HttpServletRequest;

public class UploadBean {
    public UploadBean() {
        super();
    }

    public String upload() {
        System.out.println("====JYM");
        HttpServletRequest httpRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
        System.out.println(httpRequest.getAttribute("files"));
        return "";
    }
}

My aim is to add the input file field dynamically by JavaScript or jQuery, which works well in JSP, I want to get that in JSF.

If I remove the enctype="multipart/form-data" from the h:form then the action method is executing, otherwise not.

Any suggestion would be very helpful to me.

解决方案

Here,

for (FileItem item : items) {
    if (!item.isFormField()) {
        files.add(item);
    }
}

you're ignoring all form fields, such as the button itself. When continuing such a request, JSF will have no clue that a button was been invoked and thus not queue any action at all.

You need to add an else to collect all form fields in a Map<String, String[]> and wrap the request with a HttpServletRequestWrapper which delegates to that map on all getParameterXxx() calls and finally continue the filter chain with the wrapped request. This way JSF will find out that the button was invoked and then queue to the proper action.

这篇关于h:如果h:form的enctype =“multipart / form-data”,commandButton不会触发操作。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆