Java:使用Oreilly MultipartRequest servlet发送带附件的电子邮件

时间:2016-12-15 09:31:45

标签: java apache servlets file-upload

我使用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对象中。

2 个答案:

答案 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会在其构造函数中接受FileString。因此直接传递File对象只是解决了问题。就这样:

    File fileItem = (File)it.next();
    DataSource source = new FileDataSource(fileItem);