如何在Spring+AngularJS的Maven项目中使用Gmail发送邮件?
解决AngularJS + Spring Maven项目使用Gmail发送邮件的问题
Hey,我明白你现在的困扰——搜了一堆旧教程却不管用,主要是因为Gmail的安全政策更新了,加上前端直接发邮件本身就不是正确的做法。咱们一步步来搞定这个问题:
核心认知:前端不能直接发邮件
首先得纠正一个误区:AngularJS前端绝对不能直接发送邮件。一来会暴露你的Gmail账号凭证,存在严重安全风险;二来浏览器的同源策略和安全限制也会阻止这种操作。正确的流程是:前端收集邮件数据,调用后端Spring接口,由后端服务完成Gmail的邮件发送。
第一步:后端Spring配置(重点,旧教程失效的核心原因)
Gmail现在已经不再允许普通账号密码直接登录第三方应用了,除非你开启“不太安全的应用访问”(极度不推荐)。所以咱们用更安全的App Password方式(需要开启两步验证)。
1. 生成Gmail的App Password
- 先确保你的Gmail账号开启了两步验证(2FA)
- 登录Google账号后,进入「管理你的Google账号」→「安全」→ 找到「应用密码」选项(开启2FA后才会显示)
- 生成一个16位的应用密码,保存好,这个密码只会显示一次!
2. 配置Spring项目的Maven依赖
在pom.xml里添加Spring Mail的依赖:
<!-- 如果是Spring Boot项目,用这个 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- 如果是传统Spring项目,用这两个 --> <!-- <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.6.2</version> </dependency> -->
3. 配置SMTP参数
在application.properties(或application.yml)里添加Gmail的SMTP配置:
# Gmail SMTP核心配置 spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=你的Gmail邮箱地址@gmail.com spring.mail.password=刚才生成的16位应用密码 # 开启认证和TLS加密 spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true # 超时配置 spring.mail.properties.mail.smtp.connectiontimeout=5000 spring.mail.properties.mail.smtp.timeout=5000 spring.mail.properties.mail.smtp.writetimeout=5000
4. 编写邮件服务类
创建一个处理邮件发送的Service:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Service; @Service public class EmailService { @Autowired private JavaMailSender mailSender; // 发送简单文本邮件 public void sendSimpleEmail(String to, String subject, String text) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("你的Gmail邮箱地址@gmail.com"); // 必须和配置的username一致 message.setTo(to); message.setSubject(subject); message.setText(text); mailSender.send(message); } // 如果需要发送HTML邮件或带附件,用MimeMessageHelper即可,这里先给基础版本 }
5. 编写接收前端请求的Controller
创建一个Controller来接收前端的邮件请求:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class EmailController { @Autowired private EmailService emailService; // 前端调用的接口地址 @PostMapping("/api/send-email") public ResponseEntity<String> sendEmail(@RequestBody EmailRequest emailRequest) { try { emailService.sendSimpleEmail( emailRequest.getTo(), emailRequest.getSubject(), emailRequest.getText() ); return ResponseEntity.ok("邮件发送成功"); } catch (Exception e) { e.printStackTrace(); return ResponseEntity.badRequest().body("邮件发送失败:" + e.getMessage()); } } // 定义接收前端参数的DTO类 public static class EmailRequest { private String to; private String subject; private String text; // Getter和Setter方法 public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getText() { return text; } public void setText(String text) { this.text = text; } } }
第二步:调整AngularJS前端代码
修改你的sendEmail函数,让它调用后端的接口,而不是尝试在前端处理发送逻辑:
$scope.sendEmail = function(){ // 填充邮件数据(这里可以根据你的业务逻辑调整,比如从表单获取) $scope.emailData = { to: "to@gmail.com", subject: "Forgot Password", text: "请点击以下链接重置你的密码:xxx" // 替换成实际内容 }; // 发送POST请求到后端接口 $http.post('/api/send-email', $scope.emailData) .then(function(response) { console.log("邮件发送成功!", response.data); // 这里可以添加成功提示,比如alert或者页面弹窗 }, function(error) { console.error("邮件发送失败:", error); // 错误提示,比如告知用户重试 }); };
第三步:解决跨域问题(如果前后端端口不同)
如果你的AngularJS前端和Spring后端运行在不同的端口(比如前端8080,后端8081),需要在Spring后端配置跨域:
方式1:在Controller上添加注解
@CrossOrigin(origins = "http://localhost:8080") // 替换成你的前端地址 @RestController public class EmailController { // 代码不变 }
方式2:全局跨域配置(推荐,适合多个接口)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 匹配所有api接口 .allowedOrigins("http://localhost:8080") // 允许的前端地址 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*"); } }; } }
常见问题排查
- 应用密码无效:确认已经开启两步验证,应用密码是刚生成的,没有输入错误(16位无空格)
- SMTP连接失败:检查端口是否正确(587用TLS,465用SSL),服务器防火墙是否允许出站连接到
smtp.gmail.com - 邮件被标记为垃圾邮件:确保发件人地址和配置的
username一致,邮件内容避免敏感词汇 - 跨域错误:确认后端的跨域配置中,
allowedOrigins和你的前端地址完全匹配(包括端口)
内容的提问来源于stack exchange,提问作者Mark




