2

JSF: 1.2

サーバー: Weblogic

複数のファイルのアップロードを実装しようとしています。IE7をサポートする必要があるため、HTML5入力ファイルを使用できません。そのため、ボタンを追加する予定です。ボタンをクリックすると、ページに入力ファイルが追加されます。

主に私はADFFacesで仕事を始めました。しかし、それはうまくいきませんでした。それは予想外の振る舞いでした。

Tomahawkのファイルアップロードコンポーネントも試しましたが、このコンポーネントに問題があり、バックエンドから新しいファイルアップロードを追加した後、以前に作成したファイルアップロードフィールドが空になりました。UploadedFileインスタンスではありません。しかし、これは私の要件を満たしていません。最後の[フォームの送信]ボタンがクリックされるまで、ファイルアップローダーにすべてのパスを表示する必要があるため。

それから私はapachecommonsfileuploadの助けを借りました。

私はこれを純粋なJSPとapachesfileuploadで試しましたが、うまくいきました。

しかし、apaches fileuploadを使用してJSFで実装したいのですが、これを実行しようとすると、問題が発生し始めました。

jspxページを以下に示します。

<?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>

イベントから適切なマルチパートリクエストを取得できないため、フィルターを作成しました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.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>

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);
    }
}

そして最後に、マネージド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 "";
    }
}

私の目的は、JavaScriptまたはjQueryによって動的に入力ファイルフィールドを追加することです。これはJSPでうまく機能しますが、JSFで取得したいと思います。

を削除するとenctype="multipart/form-data"h:formアクションメソッドが実行されます。それ以外の場合は実行されません。

どんな提案も私にとって非常に役に立ちます。

4

2 に答える 2

3

ここ、

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

ボタン自体など、すべてのフォーム フィールドを無視しています。このようなリクエストを続行すると、JSF はボタンが呼び出されたことを認識できないため、アクションをまったくキューに入れません。

elseですべてのフォーム フィールドを収集し、すべての呼び出しでそのマップにデリゲートする でMap<String, String[]>リクエストをラップし、最後にラップされたリクエストでフィルタ チェーンを継続するには、 を追加する必要があります。このようにして、JSF はボタンが呼び出されたことを認識し、適切なアクションのキューに入れます。HttpServletRequestWrappergetParameterXxx()

于 2013-01-09T18:04:20.067 に答える
0

@ BalusCが指示したように:

import java.io.IOException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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 javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.fileupload.FileItem;
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 {
        this.filterConfig = filterConfig;
    }

    public void destroy() {
        this.filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        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;
        }        

        try {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            upload.setSizeMax(-1);

            List<FileItem> items = upload.parseRequest(httpRequest);
            final Map<String, String[]> parameterMap = new HashMap<String, String[]>();

            for (FileItem item : items) {
                if (item.isFormField()) {
                    processFormField(item, parameterMap);
                } else {
                    processFileField(item, httpRequest);
                }
            }

            chain.doFilter(new HttpServletRequestWrapper(httpRequest) {

                    public Map<String, String[]> getParameterMap() {
                        return parameterMap;
                    }

                    public String[] getParameterValues(String name) {
                        return (String[])parameterMap.get(name);
                    }

                    public String getParameter(String name) {
                        String[] params = getParameterValues(name);
                        if (params == null) {
                            return null;
                        }
                        return params[0];
                    }

                    public Enumeration<String> getParameterNames() {
                        return Collections.enumeration(parameterMap.keySet());
                    }
                }, response);
        } catch (Exception ex) {
            ServletException servletException = new ServletException();
            servletException.initCause(ex);
            throw servletException;
        }
    }

    private void processFormField(FileItem formField, Map<String, String[]> parameterMap) {
        String name = formField.getFieldName();
        String value = formField.getString();
        String[] values = parameterMap.get(name);

        if (values == null) {
            parameterMap.put(name, new String[] { value });
        } else {
            int length = values.length;
            String[] newValues = new String[length + 1];
            System.arraycopy(values, 0, newValues, 0, length);
            newValues[length] = value;
            parameterMap.put(name, newValues);
        }
    }

    private void processFileField(FileItem fileField, HttpServletRequest request) {
        if (request.getAttribute(fileField.getFieldName()) == null) {
            List<FileItem> fileFields = new ArrayList<FileItem>(0);
            fileFields.add(fileField);
            request.setAttribute(fileField.getFieldName(), fileFields);
        } else {
            List<FileItem> fileFields = (List<FileItem>)request.getAttribute(fileField.getFieldName());
            fileFields.add(fileField);
        }
    }
}

複数の入力ファイル コンポーネントがあるため。そのためList、すべてのファイル フィールドをメソッドに保存しprocessFileFieldてから、request.

于 2013-01-09T21:56:36.110 に答える