我使用Oreilly MultipartRequest servlet解析表单multipart / form-data请求,如下所示:
String path = getServletContext().getRealPath("/tmp");
List uploadFiles = new ArrayList();
MultipartRequest multi = new MultipartRequest(request, path, 50 * 1024 * 1024, "UTF-8");
Enumeration<String> params = multi.getParameterNames();
Enumeration<String> files = multi.getFileNames();
//retrieve text parameters
String param;
while(params .hasMoreElements()){
param = params .nextElement();
for(String occurence : multi.getParameterValues(param)){
pageContext.setAttribute(param, occurence);
}
}
//get files
String fileParam;
while(files.hasMoreElements()){
fileParam = files.nextElement();
uploadFiles.add(multi.getFile(fileParam));
}
我能够获取所有数据,但就文件而言,我希望将它们作为附件发送,通常这样做(通过解析request
)
ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory());
try {
List fileItemsList = servletFileUpload.parseRequest(request);
Iterator it = fileItemsList.iterator();
while (it.hasNext()){
FileItem fileItem = (FileItem)it.next();
if (fileItem.isFormField()){
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(fileItem.getString());
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(fileItem.getFieldName());
multipart.addBodyPart(messageBodyPart);
}
}
} catch(Exception e) {
out.println(e.toString());
}
相反,我正在创建要上传的所有文件uploadFiles
的列表。问题是附件使用FileItem接口,它允许我使用getString()
将文件项的内容作为String获取,而Oreilly MultipartRequest
仅将文件作为File
返回宾语。如何以类似方式使用File
对象的内容,或者将其投射到FileItem
对象中。
答案 0 :(得分:1)
根据文档,FileItem.getString()以“String”的形式返回“文件项的内容”。但FileDataSource(String)“从指定的路径名创建一个FileDataSource”。因此,在您的第二个代码片段中,您将文件内容作为String(谁知道将对二进制文件做什么)而不是文件名传递。并且getFieldName()将返回表单字段的名称,而不是上传文件的名称(这是您想要的)。
如果您使用MultipartRequest处理上传,那么从MultipartRequest返回的File对象中实例化DataHandler所需的FileDataSource是微不足道的。
如果您使用ServletFileUpload处理上传,那么最好是创建自己的DataSource接口自定义实现,它允许构造函数中的FileItem
public class FileItemDataSource implements DataSource {
private FileItem item;
public FileItemDataSource(FileItem item) {
this.item = item;
}
@Override
public String getContentType() {
return item.getContentType() ;
}
@Override
public InputStream getInputStream() throws IOException {
return item.getInputStream();
}
@Override
public String getName() {
return item.getName();
}
@Override
public OutputStream getOutputStream() throws IOException {
return item.getOutputStream();
}
}
你可以用这样的课程
DataSource source = new FileItemDataSource(fileItem);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(fileItem.getName());
multipart.addBodyPart(messageBodyPart);
答案 1 :(得分:0)
显然,课程FileDataSource
会在其构造函数中接受File
或String
。因此直接传递File对象只是解决了问题。就这样:
File fileItem = (File)it.next();
DataSource source = new FileDataSource(fileItem);