JSF2.0简单的文件输入 [英] JSF2.0 simple file input

查看:126
本文介绍了JSF2.0简单的文件输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图添加一个非常简单的文件输入到我的webapp,我正在使用JSF2.0和RichFaces 3.3.3,事情是我真的不喜欢richfaces fileInput组件,我正在寻找更简单的东西(根据用途和外观),到目前为止我发现:


  • tomahawk的fileInput - 但是tomahawk只支持JSF1.2 li>
  • trinidad fileInput - 但是JSF2.0的trinidad在alpha阶段

  • primefaces,但是当然它们不能用于RichFaces 3.3.3 4.0 beta版)



还有其他的选择吗?我需要一些非常简单的东西,比如一个普通的html文件输入组件。 你基本上需要做两件事:


$ b


  1. 创建一个过滤器,将 multipart / form-data 并用它替换原来的请求参数映射,这样正常的 request.getParameter()进程就可以继续工作。

  2. 创建一个呈现输入类型=文件的JSF 2.0自定义组件,它知道这个自定义地图,并可以从中获取上传的文件。

@taher已经提供了一个链接,您可以在其中找到见解和代码片段。 JSF 2.0片段应该是可重用的。您还必须修改 MultipartMap 以使用良好的'ol Apache Commons FileUpload API而不是Servlet 3.0 API。



如果我有时间的话,我会在一天结束的时候重写它,并把它发布到这里。
$ b

更新:我差点忘了你,我做了一个快速的更新,用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> {

//常量-------------------------------------- --------------------------------------------

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

私有字符串编码;
私人字符串位置;

//构造函数--------------------------------------- ----------------------------------------

/ * *
*根据给定的多部分请求和文件上传位置构建多部分映射。当在给定的请求中未指定
*编码时,它将默认为< tt> UTF-8< / tt> ;.
* @param multipartRequest构造多部分映射的多部分请求。
* @param location保存上传文件的位置。
* @throws ServletException如果在Servlet级别失败。
* @throws IOException如果在I / O级别失败。
* /
@SuppressWarnings(unchecked)// ServletFileUpload#parseRequest()没有参数化。
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;

尝试{
列表< FileItem> parts = new ServletFileUpload(new DiskFileItemFactory())。parseRequest(multipartRequest);
for(FileItem part:parts){
if(part.isFormField()){
processFormField(part);
} else if(!part.getName()。isEmpty()){
processFileField(part);

$ b} catch(FileUploadException e){
throw new ServletException(Parsing multipart / form-data request failed,,e);
}
}

//操作----------------------------- -------------------------------------------------- -----

@Override
public Object get(Object key){
Object value = super.get(key);
if(value instanceof String []){
String [] values =(String [])value;
返回values.length == 1?值[0]:Arrays.asList(values);
} else {
返回值; //可以是File或null。


$ b $ ** b $ b * @see ServletRequest#getParameter(String)
* @throws IllegalArgumentException如果这个字段实际上是一个File域。
* /
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;
返回值!= null?值[0]:null;

$ b $ ** b $ b * @see ServletRequest#getParameterValues(String)
* @throws IllegalArgumentException如果这个字段实际上是一个File字段。
* /
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;

$ b / **
* @see ServletRequest#getParameterNames()
* /
public Enumeration< String> getParameterNames(){
返回Collections.enumeration(keySet());

$ b / **
* @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;
}

/ **
*返回与给定请求参数名称相关的上传文件。
* @param name请求参数名称以返回相关的上传文件。
* @return与给定的请求参数名称关联的上传文件。
* @throws IllegalArgumentException如果这个字段实际上是一个文本字段。
* /
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;
}

//助手---------------------------------- --------------------------------------------------

/ **
*给出部分为文本部分的过程。
* /
private void processFormField(FileItem part){
String name = part.getFieldName();
String [] values =(String [])super.get(name);

if(values == null){
//尚未在参数映射中,所以添加为新值。
put(name,new String [] {part.getString()});
} else {
//多个字段值,所以给现有的数组添加新的值。
int length = values.length;
String [] newValues = new String [length + 1];
System.arraycopy(值,0,newValues,0,length);
newValues [length] = part.getString();
put(name,newValues);


$ b $ **
*给定部分为文件部分的过程,将被保存在具有给定文件名的临时目录中。
* /
private void processFileField(FileItem part)throws IOException {

//获取文件名前缀(实际名称)和后缀(扩展名)。
String filename = FilenameUtils.getName(part.getName());
字符串前缀=文件名;
字符串后缀=;
if(filename.contains(。)){
prefix = filename.substring(0,filename.lastIndexOf('。'));
suffix = filename.substring(filename.lastIndexOf('。'));
}

//写上传的文件。
档案档案= File.createTempFile(前缀+_,后缀,新档案(位置));
InputStream input = null;
OutputStream output = null;
尝试{
input = new BufferedInputStream(part.getInputStream(),DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(new FileOutputStream(file),DEFAULT_BUFFER_SIZE);
IOUtils.copy(输入,输出);
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}

put(part.getFieldName(),file);
part.delete(); //清理临时存储





你仍然需要 MultipartFilter MultipartRequest 类,如这篇文章。您只需要移除 @WebFilter 注释,并在 url-pattern 上映射过滤器> / * 以及< init-param> location 上传文件的绝对路径。您可以按照这篇文章不变。


I'm trying to add a very simple file input to my webapp which I'm doing using JSF2.0 and RichFaces 3.3.3, the thing is I really dislike the richfaces fileInput component and I'm looking for something simpler (in terms of use and looks), so far I've found:

  • tomahawk's fileInput - but tomahawk only supports JSF1.2
  • trinidad fileInput - but trinidad for JSF2.0 is in alpha stage
  • primefaces - but of course they won't work with RichFaces 3.3.3 (only 4.0 which are in beta)

Are there any other options? I need something really simple like a normal html file input component.

解决方案

You basically need to do two things:

  1. Create a Filter which puts the multipart/form-data items in a custom map and replace the original request parameter map with it so that the normal request.getParameter() process keeps working.

  2. Create a JSF 2.0 custom component which renders a input type="file" and which is aware of this custom map and can obtain the uploaded files from it.

@taher has already given a link where you could find insights and code snippets. The JSF 2.0 snippets should be reuseable. You yet have to modify the MultipartMap to use the good 'ol Apache Commons FileUpload API instead of the Servlet 3.0 API.

If I have time, I will by end of day rewrite it and post it here.


Update: I almost forgot you, I did a quick update to replace Servlet 3.0 API by Commons FileUpload API, it should work:

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.
    }

}

You still need both the MultipartFilter and MultipartRequest classes as described in this article. You only need to remove the @WebFilter annotation and map the filter on an url-pattern of /* along with an <init-param> of location wherein you specify the absolute path where the uploaded files are to be stored. You can use the JSF 2.0 custom file upload component as described in this article unchanged.

这篇关于JSF2.0简单的文件输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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