【问题标题】:Cant retrieve an images from the WEB-INF folder ussing classLoader.getResourceAsStream()无法使用 classLoader.getResourceAsStream() 从 WEB-INF 文件夹中检索图像
【发布时间】:2011-03-09 18:52:42
【问题描述】:

中午我试图让我的应用程序通过 javamail 发送 html+图像,我只设法发送 html,但图像我遇到了一些问题。我决定创建一个多部分消息,一切正常,但随后我使用类加载器从 WEB-INF/resources/images 中检索 .png 文件,我得到一个 NullPointerExcetion,我不知道这是为什么?

这是我的 EJB(3.0) 的样子。我很感激这个我对 ClassLoader 类没有太多经验的人(不太了解它)。

@Stateless(name = "ejbs/EmailServiceEJB")
public class EmailServiceEJB implements IEmailServiceEJB {

@Resource(name = "mail/myMailSession")
private Session mailSession;

public void sendAccountActivationLinkToBuyer(String destinationEmail,
        String name) {

    // Destination of the email
    String to = destinationEmail;
    String from = "dontreply2thismessage@gmail.com";

    try {
        Message message = new MimeMessage(mailSession);
        // From: is our service
        message.setFrom(new InternetAddress(from));
        // To: destination given
        message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse(to));
        message.setSubject("Uspijesna registracija");
        // How to found at http://www.rgagnon.com/javadetails/java-0321.html
        message.setContent(generateActivationLinkTemplate(), "text/html");

        Date timeStamp = new Date();
        message.setSentDate(timeStamp);

        // Prepare a multipart HTML
        Multipart multipart = new MimeMultipart();
        // Prepare the HTML
        BodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(generateActivationLinkTemplate(), "text/html");
        multipart.addBodyPart(htmlPart);
        // PREPARE THE IMAGE
        BodyPart imgPart = new MimeBodyPart();

        String fileName = "/WEB-INF/resources/images/logoemailtemplate.png";

        ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();
        if (classLoader == null) {
            classLoader = this.getClass().getClassLoader();
            if (classLoader == null) {
                System.out.println("IT IS NULL AGAIN!!!!");
            }
        }



        DataSource ds = new URLDataSource(classLoader.getResource(fileName));

        imgPart.setDataHandler(new DataHandler(ds));
        imgPart.setHeader("Content-ID", "the-img-1");
        multipart.addBodyPart(imgPart);
        // Set the message content!
        message.setContent(multipart);

        Transport.send(message);

    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }

}

我想提一下,我正在将 JEE6 与 glassfishV3 一起使用,我不知道我的方法是否与此应用程序服务器兼容。


更新 当我将上面的代码修改为

String fileName = "logoemailtemplate.png";

我收到一封电子邮件,它有效。

但现在我没有收到短信。 :) 有什么错误吗?

【问题讨论】:

  • 您的代码不明确。您实例化了一个流,但没有在数据源中使用它。
  • 你说得对,流不应该在那里,它属于我以前使用的旧代码。需要进行一些重构。感谢您的建议。

标签: java jakarta-ee glassfish ejb-3.0 jakarta-mail


【解决方案1】:

我认为您将 ClassLoader#getResourceAsStream()ServletContext#getResourceAsStream() 混淆了。前者仅从类路径加载资源,而后者仅从网络内容加载资源(您的 /WEB-INF 文件夹也在那里)。

您需要将这些资源放在类路径中。如果您使用的是 IDE,那么最直接的方法是将它们放在 Java 源文件夹中的任何包中。它会在构建后以 /WEB-INF/classes 结束,这是类路径的一部分。

假设您有一个包com.example.resources.images,并且您已将logoemailtemplate.png 文件放入其中,那么您可以通过以下fileName 加载它。

String fileName = "/com/example/resources/images/logoemailtemplate.png";

另一种方法是将/WEB-INF/resources 文件夹添加到类路径中。在像 Eclipse 这样的 IDE 中,您可以通过在项目的构建路径中将其添加为 Source 文件夹 来实现。然后就可以通过下面的fileName加载了。

String fileName = "/images/logoemailtemplate.png";

然而,这不是常见的做法。

【讨论】:

  • 我开始明白了,我很困惑,因为我在这个博客中看到了:mkyong.com/jsf2/resources-library-in-jsf-2-0 我以为我必须将所有图像放在资源文件夹中。但无论如何,我现在正在尝试将它添加到 src 中的包中,然后只需转到文件名变量中的那个包。我会试试的。
  • 本教程涉及将在公共网络上显示的图像,它们可以通过 URL 和/或ExternalContext#getResource() 或类似的ServletContext#getResource() 访问。您的问题涉及要包含在邮件中的图像 - 这不是公共网络的一部分。此外,因为在 EJB 中导入 javax.servletjavax.faces 是一种不好的做法,所以最好的选择是类路径。你已经在正确的轨道上,文件只是在错误的位置:)
  • 我现在做到了,它在类路径中并且可以正常工作。谢谢你。我收到了一封电子邮件,但没有文字,只有图像,我想我的代码中仍然缺少一些东西。但主要问题已解决。
【解决方案2】:

据我所知,classLoader 只能访问 WEB-INF/classes 和 WEB-INF/lib,但不能访问 WEB-INF/resources。尝试将文件放在 classes 子文件夹中。

【讨论】:

  • 是的,但现在变量文件名应该如下所示: String fileName = "logoemailtemplate.png";
【解决方案3】:

您必须使用ServletContext.getResourceAsStream() 从战争中加载文件。 ClassLoader.getResourceAsStream 从类路径加载一个类。

【讨论】:

  • EJB 不一定需要知道ServletContext
  • @BalusC:是的,但如果不是,我看不出它是如何访问它所属的 webapp 的 WEB-INF 文件夹的。这是一个设计问题:EJB 可能不是访问 WEB-INF 的正确位置。
猜你喜欢
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 2016-08-04
  • 2017-07-18
  • 2021-11-03
  • 2014-08-17
  • 1970-01-01
相关资源
最近更新 更多