Spring 整合微软 EWS:Java 邮件发送从环境搭建到落地实战
·
Spring 整合微软 EWS:Java 邮件发送实战指南
1. 环境搭建
1.1 依赖配置 (Maven)
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- EWS Java API -->
<dependency>
<groupId>com.microsoft.ews-java-api</groupId>
<artifactId>ews-java-api</artifactId>
<version>2.0</version>
</dependency>
<!-- 邮件支持 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
1.2 Exchange 服务器配置
- 获取 Exchange 服务器地址:
https://outlook.office365.com/EWS/Exchange.asmx - 准备服务账号:
service-account@yourdomain.com - 开启 EWS 访问权限(Exchange Admin Center)
2. 核心组件实现
2.1 EWS 连接配置类
@Configuration
public class EwsConfig {
@Value("${ews.username}")
private String username;
@Value("${ews.password}")
private String password;
@Bean
public ExchangeService exchangeService() throws Exception {
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.setCredentials(new WebCredentials(username, password));
service.setUrl(new URI("https://outlook.office365.com/EWS/Exchange.asmx"));
return service;
}
}
2.2 邮件发送服务
@Service
public class EwsEmailService {
@Autowired
private ExchangeService exchangeService;
public void sendEmail(String recipient, String subject, String body) throws Exception {
EmailMessage msg = new EmailMessage(exchangeService);
msg.setSubject(subject);
msg.setBody(MessageBody.getMessageBodyFromText(body));
msg.getToRecipients().add(recipient);
msg.send();
}
public void sendEmailWithAttachment(String recipient, String filePath) throws Exception {
EmailMessage msg = new EmailMessage(exchangeService);
msg.setSubject("带附件邮件");
msg.setBody(MessageBody.getMessageBodyFromText("请查收附件"));
msg.getToRecipients().add(recipient);
// 添加附件
FileAttachment attachment = msg.getAttachments().addFileAttachment(filePath);
attachment.setContentType("application/octet-stream");
attachment.setName("document.pdf");
msg.send();
}
}
3. 进阶功能实现
3.1 HTML 格式邮件
public void sendHtmlEmail(String recipient, String htmlContent) throws Exception {
EmailMessage msg = new EmailMessage(exchangeService);
msg.setSubject("HTML格式邮件");
msg.setBody(MessageBody.getMessageBodyFromHtml(htmlContent));
msg.getToRecipients().add(recipient);
msg.send();
}
3.2 邮件发送结果回调
public void sendWithCallback(String recipient) throws Exception {
EmailMessage msg = new EmailMessage(exchangeService);
msg.setSubject("带回调的邮件");
msg.getToRecipients().add(recipient);
// 设置发送状态回调
msg.send(new ITraceListener() {
@Override
public void trace(String traceType, String traceMessage) {
System.out.println("TRACE: " + traceType + " | " + traceMessage);
}
});
}
4. 应用层调用
@RestController
@RequestMapping("/email")
public class EmailController {
@Autowired
private EwsEmailService emailService;
@PostMapping("/send")
public ResponseEntity<String> sendEmail(@RequestBody EmailRequest request) {
try {
emailService.sendEmail(
request.getRecipient(),
request.getSubject(),
request.getBody()
);
return ResponseEntity.ok("邮件发送成功");
} catch (Exception e) {
return ResponseEntity.status(500).body("发送失败: " + e.getMessage());
}
}
}
5. 常见问题解决方案
5.1 认证失败处理
// 在配置类中添加重试逻辑
service.setTraceEnabled(true); // 启用详细日志
service.setPreAuthenticate(true); // 强制预认证
// 使用OAuth2认证(推荐)
service.setCredentials(new OAuthCredentials(
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
));
5.2 连接超时配置
ExchangeService service = new ExchangeService();
service.setTimeout(10000); // 10秒超时
service.setRequestId(UUID.randomUUID().toString()); // 唯一请求ID
5.3 附件大小限制
// 分块上传大附件(>10MB)
AttachmentCollection attachments = msg.getAttachments();
attachments.addFileAttachment("largefile.zip", new FileInputStream(file), 1024*1024*20); // 20MB分块
6. 最佳实践
- 连接池管理:使用
ExchangeServiceFactory创建可复用的连接实例 - 异步发送:配合
@Async实现非阻塞发送@Async public CompletableFuture<Void> asyncSend(String recipient) { ... } - 模板引擎整合:集成Thymeleaf生成动态邮件内容
- 监控指标:通过Micrometer暴露发送成功率/延迟指标
- 安全加固:
- 使用Azure Key Vault存储凭据
- 启用TLS 1.2+:
System.setProperty("https.protocols", "TLSv1.2");
关键公式:邮件发送成功率计算
$$ \text{成功率} = \frac{\text{成功发送数}}{\text{总发送数}} \times 100% $$
7. 测试用例示例
@SpringBootTest
public class EmailServiceTest {
@Autowired
private EwsEmailService emailService;
@Test
void testSendEmail() {
assertDoesNotThrow(() ->
emailService.sendEmail(
"test@example.com",
"测试邮件",
"Spring EWS集成测试内容"
)
);
}
@Test
void testAttachmentSending() {
File tempFile = File.createTempFile("test", ".txt");
Files.write(tempFile.toPath(), "测试附件内容".getBytes());
assertDoesNotThrow(() ->
emailService.sendEmailWithAttachment(
"test@example.com",
tempFile.getAbsolutePath()
)
);
}
}
通过以上步骤,可实现从环境搭建到生产落地的完整邮件发送解决方案,支持基础邮件、HTML内容、大附件等企业级需求。
更多推荐
所有评论(0)