美文网首页
通过spring实现javamail发送邮件功能

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

作者: 风间影月 | 来源:发表于2017-11-13 11:55 被阅读71次

    以前很早的时候大家都用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中加入就行,但是为了做更好的分层,还是分开较好

    image

    配置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>
    

    配置模板路径

    image

    填充模板内容

    <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";
        }
    

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

    image

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

    尚自习 | 程序员的进阶平台 itzixi.com

    微信公众号:BeJavaGod

    Java技术交流群

    相关文章

      网友评论

          本文标题:通过spring实现javamail发送邮件功能

          本文链接:https://www.haomeiwen.com/subject/eftzmxtx.html