JSF2.0简单文件输入
我正在尝试向我的Web应用程序添加一个非常简单的文件输入,我正在使用JSF2.0和RichFaces 3.3.3,问题是我真的不喜欢RichFaces fileInput组件,我正在寻找更简单的东西(在使用和外观方面),到目前为止,我发现:JSF2.0简单文件输入,jsf,file-upload,jsf-2,Jsf,File Upload,Jsf 2,我正在尝试向我的Web应用程序添加一个非常简单的文件输入,我正在使用JSF2.0和RichFaces 3.3.3,问题是我真的不喜欢RichFaces fileInput组件,我正在寻找更简单的东西(在使用和外观方面),到目前为止,我发现: tomahawk的fileInput——但tomahawk只支持JSF1.2 trinidad fileInput-但是trinidad for JSF2.0处于alpha阶段 primefaces——但当然,它们不会与RichFaces 3.3.3(仅4
- tomahawk的fileInput——但tomahawk只支持JSF1.2
- trinidad fileInput-但是trinidad for JSF2.0处于alpha阶段
- primefaces——但当然,它们不会与RichFaces 3.3.3(仅4.0版测试版)一起使用
还有其他选择吗?我需要一些非常简单的东西,比如一个普通的html文件输入组件。亲爱的,要么你必须使用rich:uploadFile,要么通过以下步骤在JSF中创建自定义组件。你基本上需要做两件事:
multipart/form data
项放入自定义映射中,并用它替换原始的请求参数映射,以便正常的request.getParameter()
过程继续工作input type=“file”
,它知道这个自定义映射,并可以从中获取上传的文件MultipartMap
,以使用良好的OLAPI而不是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.
}
}
package net.balusc.http.multipart;
导入java.io.BufferedInputStream;
导入java.io.BufferedOutputStream;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.util.array;
导入java.util.Collections;
导入java.util.Enumeration;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Map.Entry;
导入javax.servlet.ServletException;
导入javax.servlet.ServletRequest;
导入javax.servlet.http.HttpServletRequest;
导入org.apache.commons.fileupload.FileItem;
导入org.apache.commons.fileupload.FileUploadException;
导入org.apache.commons.fileupload.disk.DiskFileItemFactory;
导入org.apache.commons.fileupload.servlet.ServletFileUpload;
导入org.apache.commons.io.FilenameUtils;
导入org.apache.commons.io.IOUtils;
公共类MultipartMap扩展了HashMap{
//常数----------------------------------------------------------------------------------
私有静态最终字符串属性\u NAME=“parts”;
私有静态最终字符串默认值_ENCODING=“UTF-8”;
私有静态final int DEFAULT\u BUFFER\u SIZE=10240;//10KB。
//瓦尔斯---------------------------------------------------------------------------------------
私有字符串编码;
私有字符串位置;
//建设者-------------------------------------------------------------------------------
/**
*根据给定的多部分请求和文件上载位置构造多部分映射。何时
*在给定的请求中没有指定编码,那么它将默认为UTF-8。
*@param multipartRequest构造的多部分映射的多部分请求。
*@param location保存上载文件的位置。
*@在Servlet级别出现故障时抛出ServletException。
*@在I/O级别出现故障时抛出IOException。
*/
@SuppressWarnings(“未选中”)//ServletFileUpload#parseRequest()未参数化。
公共MultipartMap(HttpServletRequest multipartRequest,字符串位置)
抛出ServletException、IOException
{
setAttribute(属性名称,this);
this.encoding=multipartRequest.getCharacterEncoding();
if(this.encoding==null){
multipartRequest.setCharacterEncoding(this.encoding=默认\u编码);
}
这个位置=位置;
试一试{
List parts=new ServletFileUpload(new DiskFileItemFactory()).parseRequest(multipartRequest);
对于(文件项部分:部分){
if(part.isFormField()){
processFormField(部分);
}如果(!part.getName().isEmpty())为else,则为{
processFileField(部分);
}
}
}捕获(文件上载异常){
抛出新的ServletException(“解析多部分/表单数据请求失败。”,e);
}
}
//行动------------------------------------------------------------------------------------
@凌驾
公共对象获取(对象密钥){
对象值=super.get(键);
if(字符串[]的值instanceof){
字符串[]值=(字符串[])值;
返回值.length==1?值[0]:数组.asList(值);
}否则{
返回值;//可以是File或null。
}
}
/**
*@请参阅ServletRequest#getParameter(字符串)
*@如果此字段实际上是文件字段,则会引发IllegalArgumentException。
*/
公共字符串getParameter(字符串名称){
对象值=super.get(名称);
if(文件实例的值){
抛出新的IllegalArgumentException(“这是一个文件字段,请改用#getFile()”);
}
字符串[]值=(字符串[])值;
返回值!=null?值[0]:null;
}
/**
*@请参阅ServletRequest#getParameterValues(字符串)
*@如果此字段实际上是文件字段,则会引发IllegalArgumentException。
*/
公共字符串[]getParameterValues(字符串名称){
对象值=super.get(名称);
if(文件实例的值){
抛出新的IllegalArgumentException(“这是一个文件字段,请改用#getFile()”);
}
返回(字符串[])值;
}
/**
*
<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>
You can used rich faces 3.3.3 file upload.
<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>
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);
}