通过spring实现javamail发送邮件功能

简介: 以前很早的时候大家都用javamail实现发送邮件的功能,而且我们也一直沿用至今,代码拷过来用用就行了,现在我们改为用spring来实现,这样一来减少代码的复杂度,也能更好的契合spring理念首先spring的相关jar包都是要引入的,其次要引入mail.

以前很早的时候大家都用javamail实现发送邮件的功能,而且我们也一直沿用至今,代码拷过来用用就行了,现在我们改为用spring来实现,这样一来减少代码的复杂度,也能更好的契合spring理念

首先spring的相关jar包都是要引入的,其次要引入mail.jar

<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
            <dependency>
                <groupId>com.sun.mail</groupId>
                <artifactId>javax.mail</artifactId>
                <version>${javax.mail.version}</version>
            </dependency>

然后需要配置一个spring-mail.xml这样的文件,如果不新建,也可以在service中加入就行,但是为了做更好的分层,还是分开较好

配置spring的javamail发送器,这边配置了qq邮箱和qq企业邮箱的配置,需要注意的是host是不同的,另外如果是个人qq邮箱,需要使用授权码,授权码在qq邮箱中查看即可,而企业邮箱就是企业管理员分配的登录密码即可

    <!-- 使用qq邮箱 -->
    <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!--         <property name="host" value="smtp.qq.com"/> -->
        <property name="host" value="smtp.exmail.qq.com"/>
        <property name="port" value="587"/>
<!--         <property name="username" value="xxxxx@qq.com"/> -->
        <property name="username" value="xxxx@xxxxx.com"/>
        <!-- qq邮箱的授权码,如果是企业邮箱,则使用登录密码 -->
<!--         <property name="password" value="xxxxxxxxxxxxxxx"/> -->
        <property name="password" value="xxxxxxxxxxxxxxx"/>
        <property name="javaMailProperties">
            <props >
                <prop key="mail.smtp.auth">true</prop>
            </props>
        </property>
    </bean>

 

附带一提网易邮箱是多么的坑爹:

    <!-- 使用163邮箱 -->
<!--     <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> -->
<!--         <property name="host" value="smtp.163.com"/> -->
<!--         <property name="port" value="25"/> -->
<!--         <property name="username" value="xxxxxxxxx@163.com"/> -->
<!--         163邮箱的授权码,而不是登录密码 -->
<!--         <property name="password" value="xxxxxxxxxxxx"/> -->
<!--         <property name="javaMailProperties"> -->
<!--             <props > -->
<!--                 <prop key="mail.smtp.auth">true</prop> -->
<!--             </props> -->
<!--         </property> -->
<!--     </bean> -->

使用网易邮箱会莫名报554的错误,也是就是说认定你的邮件是垃圾邮件,重复发送同一份邮件,内容一致,或者带有相关关键字,都会被列为垃圾邮件,然后会禁止30分钟左右,非常不人性化,所以不建议使用163作为发送器

配置邮箱的发送者以及标题,这个不写也可以,可以在发送的时候直接配置都行

    <bean id="simpleMailMessage" class="org.springframework.mail.SimpleMailMessage">
        <property name="from" value="xxxxx@xxxx.com" />
<!--         <property name="from" value="xxxxx@qq.com" /> -->
        <property name="subject" value="xxxx" />
    </bean>

最后的配置是freemarker模板,为何要模板,因为我们平时发送邮件会有很多不同的分类,分类配置在枚举中,根据不同的分类去选择不同的模板,一般来说注册码,密码重置,活动页面等等都需要作为一个单独的HTML来发送,而一个HTML我们不可能会以servlet的形式把标签都写在java代码中,所以采用模板来实现,是最好的方式:

<!--FreeMarker模板-->
    <bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="classpath:freemarker" />
        <property name="freemarkerSettings">
            <props>
                <prop key="locale">zh_CN</prop>
                <prop key="default_encoding">UTF-8</prop>
            </props>
        </property>
    </bean>

配置模板路径

填充模板内容

<h2><font color="green">${nickName},您好!</font></h2>
<p>注意:30分钟后链接将失效!</p>
<p>请点击以下链接完成密码重置操作:</p>
<p><a href="www.abc.com" target="_blank">www.abc.com/user/reset?userId=test10011</a></p>
<p>${content}</p>

编写邮件发送器,一方面从freemarker中构建邮件内容,一方面再执行mail发送操作

@Component
public class PwdMailSender {
    
    @Autowired
    private JavaMailSender javaMailSender;
    @Autowired
    private SimpleMailMessage simpleMailMessage;
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;
    
    /**
     * 
     * @Description: 从模板中构建邮件内容
     * @param nickName        用户昵称
     * @param content        邮件内容
     * @param email            接受邮件
     * 
     * @author leechenxiang
     * @date 2017年2月5日 下午1:22:00
     */
    public void send(String nickName, String content, String email) {
        String to = email;
        String text = "";
        Map<String, String> map = new HashMap<String, String>(1);
        map.put("nickName", nickName);
        map.put("content", content);
        try {
            // 根据模板内容,动态把map中的数据填充进去,生成HTML
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate("mail.ftl");
            // map中的key,对应模板中的${key}表达式
            text = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
        sendMail(to, null, text);
    }
    
    /**
     * 
     * @Description: 执行发送邮件
     * @param to            收件人邮箱
     * @param subject        邮件主题
     * @param content        邮件内容
     * 
     * @author leechenxiang
     * @date 2017年2月5日 下午1:22:34
     */
    public void sendMail(String to, String subject, String content) {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(message, true, "UTF-8");
            messageHelper.setFrom(simpleMailMessage.getFrom());
            if (subject != null) {
                messageHelper.setSubject(subject);
            } else {
                messageHelper.setSubject(simpleMailMessage.getSubject());
            }
            messageHelper.setTo(to);
            messageHelper.setText(content, true);
           javaMailSender.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

最后在需要调用的地方执行就行

@Autowired
    private PwdMailSender pwdMailSender;
    
    @RequestMapping("/mail")
    @ResponseBody
    public Object mail(){
        pwdMailSender.send("lee", "在这里填写你所需要的内容", "leechenxiang@163.com");
        return "success";
    }

然后收到的邮件内容就如下

 

需要注意的是,这么做发送邮件由于单线程操作是不可取的,可以参考之前的多线程,执行多线程操作,或者引入消息队列RMQ或者AMQ来发送邮件,异步操作优于同步操作。

 

相关文章
|
28天前
|
XML 安全 Java
|
1月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
63 0
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
61 4
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
52 0
|
6天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
123 62
|
28天前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
54 14
|
1月前
|
消息中间件 缓存 Java
手写模拟Spring Boot启动过程功能
【11月更文挑战第19天】Spring Boot自推出以来,因其简化了Spring应用的初始搭建和开发过程,迅速成为Java企业级应用开发的首选框架之一。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,帮助读者深入理解其工作机制。
47 3
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
107 2
|
2月前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。