代码之家  ›  专栏  ›  技术社区  ›  Mateusz Dymczyk

JSF2.0简单文件输入

  •  2
  • Mateusz Dymczyk  · 技术社区  · 14 年前

    • tomahawk的fileInput—但是tomahawk只支持JSF1.2
    • primefaces—但是当然它们不能与RichFaces3.3.3(只有4.0版本的测试版)一起使用

    4 回复  |  直到 14 年前
        1
  •  1
  •   BalusC    14 年前

    你基本上需要做两件事:

    1. 创建一个过滤器,将 multipart/form-data 项,并用它替换原始请求参数映射,以便 request.getParameter()

    2. 创建一个JSF2.0自定义组件来呈现 input type="file" 它知道这个自定义地图,可以从中获取上传的文件。

    @taher已经提供了一个链接,您可以在其中找到见解和代码片段。jsf2.0代码片段应该是可重用的。您还需要修改 MultipartMap Apache Commons FileUpload API而不是Servlet3.0API。

    如果我有时间,我会在一天结束前把它重写并贴在这里。


    :我差点忘了你,我做了一个快速更新,用Commons FileUpload API替换Servlet 3.0 API,它应该可以工作:

    package net.balusc.http.multipart;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    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;
    import org.apache.commons.io.FilenameUtils;
    import org.apache.commons.io.IOUtils;
    
    public class MultipartMap extends HashMap<String, Object> {
    
        // Constants ----------------------------------------------------------------------------------
    
        private static final String ATTRIBUTE_NAME = "parts";
        private static final String DEFAULT_ENCODING = "UTF-8";
        private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
    
        // Vars ---------------------------------------------------------------------------------------
    
        private String encoding;
        private String location;
    
        // Constructors -------------------------------------------------------------------------------
    
        /**
         * Construct multipart map based on the given multipart request and file upload location. When
         * the encoding is not specified in the given request, then it will default to <tt>UTF-8</tt>.
         * @param multipartRequest The multipart request to construct the multipart map for.
         * @param location The location to save uploaded files in.
         * @throws ServletException If something fails at Servlet level.
         * @throws IOException If something fails at I/O level.
         */
        @SuppressWarnings("unchecked") // ServletFileUpload#parseRequest() isn't parameterized.
        public MultipartMap(HttpServletRequest multipartRequest, String location)
            throws ServletException, IOException
        {
            multipartRequest.setAttribute(ATTRIBUTE_NAME, this);
    
            this.encoding = multipartRequest.getCharacterEncoding();
            if (this.encoding == null) {
                multipartRequest.setCharacterEncoding(this.encoding = DEFAULT_ENCODING);
            }
            this.location = location;
    
            try {
                List<FileItem> parts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(multipartRequest);
                for (FileItem part : parts) {
                    if (part.isFormField()) {
                        processFormField(part);
                    } else if (!part.getName().isEmpty()) {
                        processFileField(part);
                    }
                }
            } catch (FileUploadException e) {
                throw new ServletException("Parsing multipart/form-data request failed.", e);
            }
        }
    
        // Actions ------------------------------------------------------------------------------------
    
        @Override
        public Object get(Object key) {
            Object value = super.get(key);
            if (value instanceof String[]) {
                String[] values = (String[]) value;
                return values.length == 1 ? values[0] : Arrays.asList(values);
            } else {
                return value; // Can be File or null.
            }
        }
    
        /**
         * @see ServletRequest#getParameter(String)
         * @throws IllegalArgumentException If this field is actually a File field.
         */
        public String getParameter(String name) {
            Object value = super.get(name);
            if (value instanceof File) {
                throw new IllegalArgumentException("This is a File field. Use #getFile() instead.");
            }
            String[] values = (String[]) value;
            return values != null ? values[0] : null;
        }
    
        /**
         * @see ServletRequest#getParameterValues(String)
         * @throws IllegalArgumentException If this field is actually a File field.
         */
        public String[] getParameterValues(String name) {
            Object value = super.get(name);
            if (value instanceof File) {
                throw new IllegalArgumentException("This is a File field. Use #getFile() instead.");
            }
            return (String[]) value;
        }
    
        /**
         * @see ServletRequest#getParameterNames()
         */
        public Enumeration<String> getParameterNames() {
            return Collections.enumeration(keySet());
        }
    
        /**
         * @see ServletRequest#getParameterMap()
         */
        public Map<String, String[]> getParameterMap() {
            Map<String, String[]> map = new HashMap<String, String[]>();
            for (Entry<String, Object> entry : entrySet()) {
                Object value = entry.getValue();
                if (value instanceof String[]) {
                    map.put(entry.getKey(), (String[]) value);
                } else {
                    map.put(entry.getKey(), new String[] { ((File) value).getName() });
                }
            }
            return map;
        }
    
        /**
         * Returns uploaded file associated with given request parameter name.
         * @param name Request parameter name to return the associated uploaded file for.
         * @return Uploaded file associated with given request parameter name.
         * @throws IllegalArgumentException If this field is actually a Text field.
         */
        public File getFile(String name) {
            Object value = super.get(name);
            if (value instanceof String[]) {
                throw new IllegalArgumentException("This is a Text field. Use #getParameter() instead.");
            }
            return (File) value;
        }
    
        // Helpers ------------------------------------------------------------------------------------
    
        /**
         * Process given part as Text part.
         */
        private void processFormField(FileItem part) {
            String name = part.getFieldName();
            String[] values = (String[]) super.get(name);
    
            if (values == null) {
                // Not in parameter map yet, so add as new value.
                put(name, new String[] { part.getString() });
            } else {
                // Multiple field values, so add new value to existing array.
                int length = values.length;
                String[] newValues = new String[length + 1];
                System.arraycopy(values, 0, newValues, 0, length);
                newValues[length] = part.getString();
                put(name, newValues);
            }
        }
    
        /**
         * Process given part as File part which is to be saved in temp dir with the given filename.
         */
        private void processFileField(FileItem part) throws IOException {
    
            // Get filename prefix (actual name) and suffix (extension).
            String filename = FilenameUtils.getName(part.getName());
            String prefix = filename;
            String suffix = "";
            if (filename.contains(".")) {
                prefix = filename.substring(0, filename.lastIndexOf('.'));
                suffix = filename.substring(filename.lastIndexOf('.'));
            }
    
            // Write uploaded file.
            File file = File.createTempFile(prefix + "_", suffix, new File(location));
            InputStream input = null;
            OutputStream output = null;
            try {
                input = new BufferedInputStream(part.getInputStream(), DEFAULT_BUFFER_SIZE);
                output = new BufferedOutputStream(new FileOutputStream(file), DEFAULT_BUFFER_SIZE);
                IOUtils.copy(input, output);
            } finally {
                IOUtils.closeQuietly(output);
                IOUtils.closeQuietly(input);
            }
    
            put(part.getFieldName(), file);
            part.delete(); // Cleanup temporary storage.
        }
    
    }
    

    MultipartFilter MultipartRequest this article . 你只需要移除 @WebFilter 注释并将过滤器映射到 url-pattern /* 还有一个 <init-param> 属于 location 其中,指定存储上载文件的绝对路径。您可以使用jsf2.0自定义文件上载组件,如中所述 this article 不变。

        2
  •  0
  •   TaherT    14 年前

    亲爱的,你必须使用rich:uploadFile or 通过以下步骤在JSF中创建自定义组件 http://balusc.blogspot.com/2009/12/uploading-files-with-jsf-20-and-servlet.html

        3
  •  0
  •   phse    13 年前

    在我也尝试过tomahawk之后,我提到它不适用于AJAX。所以我决定rich:fileUpload and 在a4j:command按钮上单击add按钮。代码如下:

    <a4j:form id="myForm">
      <a4j:commandButton id="myButton" value="Upload" title="Upload" styleClass="myButtonClass"
                         onclick="document.getElementById('myForm:myFileUpload:file').click()/>
    
      <rich:fileUpload id="myFileUpload" maxFilesQuantity="1" autoclear="true"
                       immediateUpload="true" styleClass="invisibleClass"
                       fileUploadListener="#{uploadBean.uploadListener}"/>
    </a4j:form>
    

    myForm:myFileUpload:file 是输入元素( type="file" display:none; . 与 style="display:none;"

        4
  •  0
  •   Pravin    11 年前
    You can used rich faces 3.3.3 file upload.
    

    步骤1:fileUpload.xhtml

    <rich:fileUpload id="fileupload" addControlLabel="Browse"
                                                    required="true" 
                                                    fileUploadListener="#{testForm.listener}"
                                                    acceptedTypes="xml"
                                                    ontyperejected="alert('Only xml files are accepted');"
                                                    maxFilesQuantity="1" listHeight="57px" listWidth="100%"
                                                    disabled="#{testForm..disabled}" >
                                                    <a4j:support event="onclear"
                                                        action="#{testForm..clearUploadData}"
                                                        reRender="fileupload" />
                                                </rich:fileUpload>
    

    步骤2:FileUpload.java

    public class FileUpload implements Serializable{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private String Name;
        private String mime;
        private long length;
        private byte [] file;
        private String absolutePath;
    
        public String getName() {
            return Name;
        }
    
        /**
         * @return the file
         */
        public byte[] getFile() {
            return file;
        }
    
        /**
         * @param file the file to set
         */
        public void setFile(byte[] file) {
            this.file = file;
        }
    
        /**
         * @param mime the mime to set
         */
        public void setMime(String mime) {
            this.mime = mime;
        }
        public void setName(String name) {
            Name = name;
            int extDot = name.lastIndexOf('.');
            if(extDot > 0){
                String extension = name.substring(extDot +1);
                if("txt".equals(extension)){
                    mime="txt";
                } else if("xml".equals(extension)){
                    mime="xml";
    
                } else {
                    mime = "unknown file";
                }
            }
        }
        public long getLength() {
            return length;
        }
        public void setLength(long length) {
            this.length = length;
        }
    
        public String getMime(){
            return mime;
        }
    
        /**
         * @return the absolutePath
         */
        public String getAbsolutePath() {
            return absolutePath;
        }
    
        /**
         * @param absolutePath the absolutePath to set
         */
        public void setAbsolutePath(String absolutePath) {
            this.absolutePath = absolutePath;
        }
    }
    

    /**
     * 
     * @param event
     * @throws Exception
     */
    public void listener(UploadEvent event) throws Exception{
            UploadItem item = event.getUploadItem();
            FileUpload file = new FileUpload();
            file.setLength(item.getData().length);
            file.setFile(item.getData());
            file.setName(item.getFileName());
            files.add(file);
    
     }