如何配置使用JavaMail的环境?

发布于 2024-08-15 20:53:18 字数 2752 浏览 4 评论 0 原文

我需要使用 JavaMail 发送简单的 html 消息。当我试图在互联网上找到一些带有解释的好例子时,接下来的每个例子都让我更加愤怒和愤怒。

所有这些愚蠢的示例都包含复制和粘贴的 Java 代码,这些代码的不同之处仅在于注释和一个很好的免责声明,即首先您应该配置您的 smtp 和 pop3 服务器。

我知道没有人愿意为某些具体产品做广告,但配置服务器是最难的部分。那么,任何人都可以给我一些关于配置具体服务器(例如 Kerio 或任何其他服务器)的真正有用的信息(没有 java 代码)吗?

我现在遇到的是下一个例外:

250 2.0.0 Reset state
javax.mail.SendFailedException: Invalid Addresses;
  nested exception is:
    com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Relaying to <[email protected]> denied (authentication required)

UPD。前面所有文字的简单重构是:想象一下您有 Windows、jdk,除此之外什么都没有。你想编写java程序并在你的机器上运行它。这个程序应该发送“Hello world!”到您的 Gmail 帐户。列出你的步骤。

UPD2。这是代码:

Properties props = new Properties ();
props.setProperty ("mail.transport.protocol", "smtp");
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty ("mail.user", "[email protected]");
props.setProperty ("mail.password", "password_from_email_above"); 

Session mailSession = Session.getDefaultInstance (props, null);
mailSession.setDebug (true);
Transport transport = mailSession.getTransport ();

MimeMessage message = new MimeMessage (mailSession);
message.setSubject ("HTML  mail with images");
message.setFrom (new InternetAddress ("[email protected]"));
message.setContent ("<h1>Hello world</h1>", "text/html");
message.addRecipient (Message.RecipientType.TO,
        new InternetAddress ("[email protected]"));

transport.connect ();
transport.sendMessage (message,
        message.getRecipients (Message.RecipientType.TO));

例外是:

RSET
250 2.1.5 Flushed 3sm23455365fge.10
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. 3sm23455365fge.10
    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1829)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1368)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:886)
    at com.teamdev.imgmail.MailSender.main(MailSender.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...

I need to send simple html-message with JavaMail. And when I tried to find some nice examples with explanations in the Internet, each next example made me more angry and angry.

All those silly examples contain copied and pasted Java code which differs only in comments and a nice disclaimer that first you should config your smtp and pop3 server.

I understand that nobody wants to make an advertise for some concrete products but configuring the server is imho the hardest part. So, can anyone give me some really useful information (without java code) about configuring concrete server (Kerio, for example, or any other one)?

What I have now is the next exception:

250 2.0.0 Reset state
javax.mail.SendFailedException: Invalid Addresses;
  nested exception is:
    com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 Relaying to <[email protected]> denied (authentication required)

UPD. Simple reformulation of all previous text is: imagine that you have Windows, jdk, and nothing else. And you want to make java program and run it on your machine. And this program should send "Hello world!" to your gmail account. List your steps.

UPD2. Here is the code:

Properties props = new Properties ();
props.setProperty ("mail.transport.protocol", "smtp");
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty ("mail.user", "[email protected]");
props.setProperty ("mail.password", "password_from_email_above"); 

Session mailSession = Session.getDefaultInstance (props, null);
mailSession.setDebug (true);
Transport transport = mailSession.getTransport ();

MimeMessage message = new MimeMessage (mailSession);
message.setSubject ("HTML  mail with images");
message.setFrom (new InternetAddress ("[email protected]"));
message.setContent ("<h1>Hello world</h1>", "text/html");
message.addRecipient (Message.RecipientType.TO,
        new InternetAddress ("[email protected]"));

transport.connect ();
transport.sendMessage (message,
        message.getRecipients (Message.RecipientType.TO));

And exception is:

RSET
250 2.1.5 Flushed 3sm23455365fge.10
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. 3sm23455365fge.10
    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1829)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1368)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:886)
    at com.teamdev.imgmail.MailSender.main(MailSender.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

将军与妓 2024-08-22 20:53:18

如果您正在寻找配置 SMTP 服务器的教程,那么您不应该寻找 JavaMail。只需在您选择的服务器上查找教程(Kerio,例如...或EximSendMail Apache JamesPostfix)或在 Serverfault 上询问。任何符合 SMTP 的服务器都可以与 JavaMail 很好地配合。

或者,您甚至可以使用任何“标准”邮件提供商的基础设施。例如,我使用 Google Apps 帐户以及 Google 的 SMTP 基础架构从我们的 Java 应用程序发送邮件。无论如何,使用 Gmail 帐户 是一个不错的起点(如果您不想这样做)设置您自己的 SMTP 服务器以便简单地测试 JavaMail。

作为最后一个选择,您甚至可以查找域的 MX 记录并直接发送邮件到收件人的 SMTP 服务器。有一些常见的问题可以解决困难。

最后一点,您必须研究如何避免您的邮件被过滤为垃圾邮件 - 这本身就是一个很大的主题。在这里,依赖标准提供商会有所帮助,这些提供商将处理您在托管自己的服务器时可能遇到的一些问题。

顺便说一句:关于您发布的错误消息:SMTP 服务器拒绝中继消息。这是如果您的 SMTP 服务器(认为它)在 example.com 上运行,并且您以 [电子邮件受保护][电子邮件受保护] ,您要求 SMTP 服务器充当中继。几年前,这种做法很常见,直到——你猜对了——被垃圾邮件发送者滥用。从那时起,邮政局长就被鼓励拒绝转发。您有两种选择:在发送邮件之前进行身份验证或仅发送到您服务器上托管的帐户(即在 example.com 上,例如 [电子邮件受保护])。

编辑:

这里有一些代码可以帮助您开始使用身份验证(适用于 Gmail 帐户,但也应该适用于您自己的服务器)

private Session createSmtpSession() {
  final Properties props = new Properties();
  props.setProperty("mail.smtp.host", "smtp.gmail.com");
  props.setProperty("mail.smtp.auth", "true");
  props.setProperty("mail.smtp.port", "" + 587);
  props.setProperty("mail.smtp.starttls.enable", "true");
  // props.setProperty("mail.debug", "true");

  return Session.getDefaultInstance(props, new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication("[email protected]", "mypassword");
    }
  });
}

If you're looking for a tutorial to configure an SMTP server, you shouldn't be looking for JavaMail. Simply look for a tutorial on your server of choice (Kerio, for example ... or Exim, SendMail, Apache James, Postfix) or ask on Serverfault. Any SMTP-compliant server will play nicely with JavaMail.

Alternatively, you may even use any "standard" mail provider's infrastructure. For example, I use a Google Apps account along with Google's SMTP infrastructure to send mail from our Java applications. Using a Gmail account is a good starting point anyway if you don't want to setup your own SMTP server in order to simply testdrive JavaMail.

As a last option, you might even lookup the MX Records for a domain and deliver your mails directly to the SMTP server of the recipient. There are some common gotchas to workaround tough.

As a last point, you'll have to look into how to avoid that your mails be filtered as spam - which is a huge topic itself. Here it helps to rely on standard providers that will deal with some of the issues you might encounter when hosting your own server.

Btw: Regarding the error message you posted: the SMTP server is denying relaying of messages. This is if your SMTP server (thinks that it) is running on example.com and you're sending as [email protected] to [email protected], you're asking the SMTP server to act as a relay. This was common practice several years ago, until it was - you guessed it - abused by spammers. Since those days, postmasters are encouraged to deny relaying. You have two choices: authenticate before sending mail or send to accounts hosted at your server only (i.e. on example.com, e.g. [email protected]).

Edit:

Here is some code to get you started with authenticationg (works with Gmail accounts but should do for your own server as well)

private Session createSmtpSession() {
  final Properties props = new Properties();
  props.setProperty("mail.smtp.host", "smtp.gmail.com");
  props.setProperty("mail.smtp.auth", "true");
  props.setProperty("mail.smtp.port", "" + 587);
  props.setProperty("mail.smtp.starttls.enable", "true");
  // props.setProperty("mail.debug", "true");

  return Session.getDefaultInstance(props, new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication("[email protected]", "mypassword");
    }
  });
}
平安喜乐 2024-08-22 20:53:18

我可以看到你的部分问题。错误消息中对此进行了充分解释。

您将邮件发送到的 SMTP 服务器(即您在 JavaMail 配置中配置的地址之一)拒绝将邮件转发到 [电子邮件受保护]。看起来像是您的 SMTP 服务器中的配置问题。正如 sfussenegger 所指出的,它与 javamail 无关。

因此,您不会同时在所有方面进行调试,尝试从已知工作的 SMTP 客户端寻址您的 SMTP 服务器可能是个好主意。例如,雷鸟就可以做得很好。如果您可以从 Thunderbird 通过它发送邮件,那么 JavaMail 应该不会有什么问题。


更新

Google SMTP 服务器的正确地址是:smtp.gmail.com 。这是您在 JavaMail 中配置的服务器吗?您能给我们显示匹配的错误消息吗?

I can see part of your problem. It's adequately explained in the error message.

The SMTP server you are sending your mail to (i.e. one of the addresses you've configured in your JavaMail configuration) is refusing to forward mail to [email protected]. Looks like a configuration issue in your SMTP server. As sfussenegger indicated, it has nothing to do with javamail.

So you're not debugging on all fronts at the same time, it might be a good idea to try addressing your SMTP server from a known working SMTP client. Thunderbird would do fine, for example. If you can send mail through it from Thunderbird, there should be little problem from JavaMail.


Update:

The correct address for Google's SMTP server is: smtp.gmail.com . Is this the server you have configured in JavaMail? Can you show us the matching error message?

各空 2024-08-22 20:53:18

结合上述答案的工作示例,使用 activation-1.1.jarma​​il-1.4.1.jar ,并且 SMTP 主机是 Gmail

  1. 替换 [电子邮件受保护]user_pwreturn new PasswordAuthentication("[email] protected]", "user_pw");

  2. 此外,您还想替换 [email protected] 为您希望接收电子邮件的电子邮件地址.

    package com.test.sendEmail;
    导入java.util.Properties;
    导入 javax.mail.*;
    导入 javax.mail.internet.*;
    
    公共类发送电子邮件测试{
    
    /**
     * @参数参数
     */
    公共静态无效主(字符串[] args){
        // TODO 自动生成的方法存根
        sendEmailTest 电子邮件发送器 = new sendEmailTest();
        //这些电子邮件地址的域应该是有效的,
        //否则示例将失败:
        emailer.sendEmail();
    }
    
    /**
      * 发送一封电子邮件。
      */
    公共无效发送电子邮件(){
    会话 mailSession = createSmtpSession();
    mailSession.setDebug(true);
    
    尝试 {
        Transport Transport = mailSession.getTransport();
    
        MimeMessage 消息 = new MimeMessage(mailSession);
    
        message.setSubject("带图像的 HTML 邮件");
        message.setFrom (new InternetAddress ("[电子邮件受保护]"));
        message.setContent("

    Hello world

    ", "text/html"); message.addRecipient (Message.RecipientType.TO, new InternetAddress ("[电子邮件]受保护]")); 运输.连接(); Transport.sendMessage(消息, message.getRecipients(Message.RecipientType.TO)); } 捕获 (MessagingException e) { System.err.println("无法发送电子邮件"); e.printStackTrace(); } } 私有会话 createSmtpSession() { 最终属性 props = new Properties(); props.setProperty("mail.host","smtp.gmail.com"); props.setProperty("mail.smtp.auth", "true"); props.setProperty("mail.smtp.port", "" + 587); props.setProperty("mail.smtp.starttls.enable", "true"); props.setProperty("mail.transport.protocol","smtp"); // props.setProperty("mail.debug", "true"); 返回 Session.getDefaultInstance(props, new javax.mail.Authenticator() { 受保护的密码验证 getPasswordAuthentication() { 返回新的PasswordAuthentication("[电子邮件受保护]", "user_pw"); } }); } }

A working example combining the above answers, using activation-1.1.jar and mail-1.4.1.jar and the SMTP host is Gmail.

  1. Replace [email protected] and user_pw in line return new PasswordAuthentication("[email protected]", "user_pw");

  2. Also, you want to replace [email protected] by the email address where you want to receive the email.

    package com.test.sendEmail;
    import java.util.Properties;
    import javax.mail.*;
    import javax.mail.internet.*;
    
    public class sendEmailTest {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        sendEmailTest emailer = new sendEmailTest();
        //the domains of these email addresses should be valid,
        //or the example will fail:
        emailer.sendEmail();
    }
    
    /**
      * Send a single email.
      */
    public void sendEmail(){
    Session mailSession = createSmtpSession();
    mailSession.setDebug (true);
    
    try {
        Transport transport = mailSession.getTransport ();
    
        MimeMessage message = new MimeMessage (mailSession);
    
        message.setSubject ("HTML  mail with images");
        message.setFrom (new InternetAddress ("[email protected]"));
        message.setContent ("<h1>Hello world</h1>", "text/html");
        message.addRecipient (Message.RecipientType.TO, new InternetAddress ("[email protected]"));
    
        transport.connect ();
        transport.sendMessage (message, message.getRecipients (Message.RecipientType.TO));  
    }
    catch (MessagingException e) {
        System.err.println("Cannot Send email");
        e.printStackTrace();
    }
    }
    
    private Session createSmtpSession() {
    final Properties props = new Properties();
    props.setProperty ("mail.host", "smtp.gmail.com");
    props.setProperty("mail.smtp.auth", "true");
    props.setProperty("mail.smtp.port", "" + 587);
    props.setProperty("mail.smtp.starttls.enable", "true");
    props.setProperty ("mail.transport.protocol", "smtp");
    // props.setProperty("mail.debug", "true");
    
    return Session.getDefaultInstance(props, new javax.mail.Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("[email protected]", "user_pw");
      }
    });
    }
    
    }
    
蒗幽 2024-08-22 20:53:18

这应该可行:

import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Emailer {

    public static void main(String[] args) {

        String hostname = args[0];
        final String userName = args[1];
        final String passWord = args[2];
        String toEmail = args[3];
        String fromEmail = args[4];
        String subject = args[5];
        String body = "";
        // add rest of args as one body text for convenience
        for (int i = 6; i < args.length; i++) {
            body += args[i] + " ";
        }

        Properties props = System.getProperties();
        props.put("mail.smtp.host", hostname);

        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, passWord);
            }
        });

        MimeMessage message = new MimeMessage(session);
        try {
            message.setFrom(new InternetAddress(fromEmail));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
            message.setSubject(subject);
            message.setText(body);
            Transport.send(message);

        } catch (MessagingException e) {
            System.out.println("Cannot send email " + e);
        }
    }
}

您需要将 JavaMail mail.jar 放在 javax.mail 依赖项的类路径中。
我不确定 Google 是否允许您按照自己的意愿发送电子邮件。尝试其他电子邮件提供商(例如您的 ISP)怎么样?

This should work:

import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Emailer {

    public static void main(String[] args) {

        String hostname = args[0];
        final String userName = args[1];
        final String passWord = args[2];
        String toEmail = args[3];
        String fromEmail = args[4];
        String subject = args[5];
        String body = "";
        // add rest of args as one body text for convenience
        for (int i = 6; i < args.length; i++) {
            body += args[i] + " ";
        }

        Properties props = System.getProperties();
        props.put("mail.smtp.host", hostname);

        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, passWord);
            }
        });

        MimeMessage message = new MimeMessage(session);
        try {
            message.setFrom(new InternetAddress(fromEmail));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
            message.setSubject(subject);
            message.setText(body);
            Transport.send(message);

        } catch (MessagingException e) {
            System.out.println("Cannot send email " + e);
        }
    }
}

You need to put the JavaMail mail.jar on your classpath for the javax.mail dependencies.
I'm not sure if Google lets you send email like you want to. How about trying another email provider, like your ISP's?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文