【问题标题】:Java: Send email with attachment using Oreilly MultipartRequest servletJava:使用 Oreilly MultipartRequest servlet 发送带附件的电子邮件
【发布时间】:2016-12-15 09:31:44
【问题描述】:

我正在使用Oreilly MultipartRequest servlet 来解析表单多部分/表单数据请求:

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() 将文件项的内容作为字符串获取,而Oreilly MultipartRequest 仅将文件作为File 对象返回。如何类似地使用File 对象的内容,或者将其转换为FileItem 对象。

【问题讨论】:

标签: java apache servlets file-upload


【解决方案1】:

根据文档,FileItem.getString() 返回“文件项的内容作为字符串”。但是 FileDataSource(String) “从指定的路径名​​创建一个 FileDataSource”。因此,在您的第二个代码片段中,您将文件内容作为字符串(谁知道二进制文件会做什么)而不是文件名传递。 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);

【讨论】:

    【解决方案2】:

    显然FileDataSource 类在其构造函数中接受FileString。所以直接传递 File 对象就简单的解决了这个问题。因此:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 2011-06-18
      • 2016-10-23
      • 2012-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多