vde*_*ris 17 email spring spring-boot spring-java-config
如何使用基于纯注释的方法(根据Java配置规则)发送Spring 4(和Spring Boot)的电子邮件?
geo*_*and 33
一个简单的解决方案(您将使用没有身份验证的SMTP服务器)来配置电子邮件服务
@Configuration
public class MailConfig {
@Value("${email.host}")
private String host;
@Value("${email.port}")
private Integer port;
@Bean
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(host);
javaMailSender.setPort(port);
javaMailSender.setJavaMailProperties(getMailProperties());
return javaMailSender;
}
private Properties getMailProperties() {
Properties properties = new Properties();
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", "false");
properties.setProperty("mail.smtp.starttls.enable", "false");
properties.setProperty("mail.debug", "false");
return properties;
}
}
Run Code Online (Sandbox Code Playgroud)
春天必须能够解决性能email.host
和email.port
通常的方式(在春季启动的情况下,最简单的就是把那么application.properties)
在任何需要JavaMailSender服务的类中,只需注入一种常用方法(例如@Autowired private JavaMailSender javaMailSender
)
UPDATE
请注意,从版本1.2.0.RC1 Spring Boot可以自动配置JavaMailSender
.查看本文档的这一部分.从文档中可以看出,启动和运行几乎不需要任何配置!
Nei*_*gan 10
在pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
在application.properties
:
spring.mail.host=...
spring.mail.port=...
Run Code Online (Sandbox Code Playgroud)
在Foo.java
:
@Component
public class Foo {
@Autowired
private JavaMailSender mailSender;
public void send() {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("foo@example.com");
message.setTo("bar@example.com");
message.setSubject("hello");
mailSender.send(message);
}
}
Run Code Online (Sandbox Code Playgroud)
就个人而言,我建议运行localhost MTA,并使用它转发到您真正的MTA(如Gmail或SES,或您自己的).这为您提供了"免费"异步队列,并集中配置.我喜欢OpenSMTP.
使用Spring-Boot,它几乎是微不足道的,smtp.office365.com邮件服务器需要进行一次调整 - 这是该公司正在使用的.
在进行此调整之前,对Office365 SMTP服务器的身份验证仍然失败,并且我们会收到以下错误:
org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:474)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:307)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:296)
Run Code Online (Sandbox Code Playgroud)
即使我们设置的是Spring的MailProperties类正确选择的用户名和密码.
事实证明Office365需要启用TLS身份验证,而Spring的当前JavaMail实现没有一种简单的方法来实现属性.解决方案是创建我们自己的javax.mail.Session实例并将其注册到Spring.
整个画面如下.
在pom.xml文件中,添加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>${spring-boot.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
其中spring-boot.version在别处定义(在本例中为父pom),在这种情况下的值为1.3.1.RELEASE
如果你在主应用程序中逐条列出它们,请确保包括包和/或自动配置类 - 如果使用默认的@SpringBootApplication,则不需要,但在我的情况下,我将MailSenderAutoConfiguration.class添加到@Import注释中课程列表.
我创建了一个简单的EmailSender类:
@SuppressWarnings("SpringJavaAutowiringInspection")
@Slf4j
@Service
@ConditionalOnClass(JavaMailSender.class)
public class EmailSender {
@Autowired
private EventBus mmEventBus;
@Autowired
private JavaMailSender mailSender;
@Autowired
private MessageConfig messageConfig;
@Subscribe
public void sendEmail(EmailMessageEvent eme) {
log.info("{}", eme);
SimpleMailMessage msg = new SimpleMailMessage(messageConfig.getMessageTemplate());
msg.setSubject(eme.getSubject());
msg.setText(eme.getMessage());
try {
mailSender.send(msg);
} catch (MailException ex) {
log.error("Error sending mail message: " + eme.toString(), ex);
}
}
@PostConstruct
public void start() throws MessagingException {
mmEventBus.register(this);
}
}
Run Code Online (Sandbox Code Playgroud)
@ Slf4j是一个lombok注释,而@Subscribe是用于Guava的EventBus,这个应用程序让EmailSender知道有一条消息要发送.我使用了一个简单的EmailMessageEvent POJO,它有一个主题和消息文本 - 足以满足这个应用程序的需要.
MessageConfig类只是简单地设置消息默认值以及应用程序配置的其余部分,并且它具有使用Office365 SMTP服务器,自定义javax.mail.Session所需的一个特殊功能.实例注册为Spring Bean:
@Data
@Component
@ConfigurationProperties(prefix = "spring.message", ignoreUnknownFields = false)
@Slf4j
public class MessageConfig {
@SuppressWarnings("SpringJavaAutowiringInspection")
@Autowired
private MailProperties mailProperties;
private String from;
private String subject;
private String[] recipients;
private SimpleMailMessage messageTemplate;
public void setRecipients(String... r) {
this.recipients = r;
}
@PostConstruct
public void createTemplate() {
messageTemplate = new SimpleMailMessage();
messageTemplate.setFrom(from);
messageTemplate.setSubject(subject);
messageTemplate.setTo(recipients);
log.debug("Email Message Template defaults: {}", messageTemplate);
}
@Bean
public SimpleMailMessage getMessageTemplate() {
return messageTemplate;
}
@Bean
public Session getSession() {
log.debug("Creating javax.mail.Session with TLS enabled.");
// We could be more flexible and have auth based on whether there's a username and starttls based on a property.
Properties p = new Properties();
p.setProperty("mail.smtp.auth", "true");
p.setProperty("mail.smtp.starttls.enable", "true");
p.setProperty("mail.smtp.host", mailProperties.getHost());
p.setProperty("mail.smtp.port", mailProperties.getPort().toString());
return Session.getDefaultInstance(p, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(mailProperties.getUsername(), mailProperties.getPassword());
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
@Data再次是一个Lombok注释 - 自动添加mutator和accessor方法,toString(),equals()和hashCode()等.
Spring的JavaMailSender(JavaMailSenderImpl)的限制是它的Session不能直接配置,特别是没有办法通过属性启用TLS身份验证.但是,如果在上下文中注册了javax.mail.Session Bean,则会将其注入(有条件地自动装入)到MailSenderAutoConfiguration中,然后用于构造JavaMailSenderImpl实例.
所以我们通过getSession()方法注册这样一个Bean.为了更好地衡量,我们将我们在此构造的Session作为JVM的默认值 - 如果您不想要这种行为,请将其更改为调用getInstance().
添加此Session @Bean后一切正常.
归档时间: |
|
查看次数: |
33686 次 |
最近记录: |