你基本上需要做两件事:
-
创建一个过滤器,将
multipart/form-data
项,并用它替换原始请求参数映射,以便
request.getParameter()
-
创建一个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> {
private static final String ATTRIBUTE_NAME = "parts";
private static final String DEFAULT_ENCODING = "UTF-8";
private static final int DEFAULT_BUFFER_SIZE = 10240;
private String encoding;
private String location;
@SuppressWarnings("unchecked")
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);
}
}
@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;
}
}
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;
}
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;
}
public Enumeration<String> getParameterNames() {
return Collections.enumeration(keySet());
}
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;
}
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(values, 0, newValues, 0, length);
newValues[length] = part.getString();
put(name, newValues);
}
}
private void processFileField(FileItem part) throws IOException {
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('.'));
}
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();
}
}
MultipartFilter
和
MultipartRequest
this article
. 你只需要移除
@WebFilter
注释并将过滤器映射到
url-pattern
/*
还有一个
<init-param>
属于
location
其中,指定存储上载文件的绝对路径。您可以使用jsf2.0自定义文件上载组件,如中所述
this article
不变。