首页 > 其他 > 详细

SSM项目下的邮件发送

时间:2021-06-13 19:05:16      阅读:30      评论:0      收藏:0      [点我收藏+]

Java发送邮件

  Java发送邮件有两种发送方式

  1、单独发送(不和任何框架整合)=》代码多,不容易记忆,使用时可以百度。

  2、和Spring整合

  发送邮件的支持包

  1、javax-mail(过时了,但是可以使用)

  2、sun公司的mail组件

  本文案例依托于上一篇SSM整合环境搭建

1、发送简单邮件

1.1、设置邮箱的SMTP和POP3服务

1.2、导入相关jar包

activation-1.1.1
javax.mail-1.6.2

spring-context-support-5.1.9.RELEASE

1.3、配置外部配置文件

mail.host=smtp.qq.com
mail.username=xxxxxx8@qq.com
mail.password=kybtqndfzeslgidg
mail.defaultEncoding=utf-8

 

1.4、配置springmvc配置文件

<!--    加载外部配置文件-->
    <context:property-placeholder location="classpath:mail.properties"/>
<!--    配置JavaMailSender 邮件-->
    <bean class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${mail.host}"/>
        <property name="username" value="${mail.username}"/>
        <property name="password" value="${mail.password}"/>
        <property name="defaultEncoding" value="${mail.defaultEncoding}"/>
    </bean>

 

1.5、编写Controller类

@Controller
public class MailController {
    
    @Autowired
    private JavaMailSender javaMailSender;

    @GetMapping("sendMail")
    @ResponseBody
    public String sendLoginCodeMail(String to, String code) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        //邮件发送者
        simpleMailMessage.setFrom("发件人昵称<xxxxxx@qq.com>");
        //邮件接受者
        simpleMailMessage.setTo(to);
        //邮件主题
        simpleMailMessage.setSubject("验证码");
        //邮件内容
        simpleMailMessage.setText("你的登录验证码为 :" + code + "两分钟内有效");
        //回复邮件
        //simpleMailMessage.setReplyTo();
        //表示抄送邮件
        //simpleMailMessage.setCc();
        //表示密送
        //simpleMailMessage.setBcc();
        //设置发送日期
        //simpleMailMessage.setSentDate();
        javaMailSender.send(simpleMailMessage);
        return "success";
    }
}

 

2、发送带附件的邮件

  注意:此后的案例都是在发送简单邮件的基础上编写,重复部分不在复写,并且不在写注解、返回类型及返回值

    /**
     * 发送带附件的邮件
     * 复杂的邮件消息
     */
    public void sendMailWithFile(ToEmail toEmail) {
        // MimeMessage发送复杂邮件的消息本身
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom("Lolita<xxxxxx@qq.com>");
            helper.setTo(toEmail.getTo());
            helper.setSubject(toEmail.getSubject());
            helper.setText(toEmail.getText());
            //携带的附件 第一个参数表示附件的名称,第二个参数表示文件的位置
            helper.addAttachment(toEmail.getSendLocalFile().get("fileName"), new File(toEmail.getSendLocalFile().get("filePath")));
            javaMailSender.send(mimeMessage);
            System.out.println("发送成功");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

 

3、文件上传的方式发送带附件的邮件

    /**
     * 发送带附件的邮件 以文件上传的方是上传附件
     */
    public void sendMailByUpload(ToEmail toEmail) {
        System.out.println(toEmail);
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom("Lolita<xxxxxx@qq.com>");
            helper.setTo(toEmail.getTo());
            helper.setSubject(toEmail.getSubject());
            helper.setText(toEmail.getText());

            InputStream inputStream = toEmail.getPart().getInputStream();

//            byte[] buffer = new byte[1024]; //1K  128m  240
//            int num=0;
//            List<Byte> list  ;
//            StringBuffer buffer1  = new StringBuffer();
//            ByteArrayInputStream arrayInputStream  = new ByteArrayInputStream();
//            arrayInputStream.re
//            while ((num = inputStream.read())!=-1){
//
//            }
//            byte[] bytes = buffer1.toString().getBytes();
//
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);

            helper.addAttachment(toEmail.getPart().getSubmittedFileName(),new ByteArrayResource(buffer));

            javaMailSender.send(mimeMessage);
            System.out.println("上传成功");
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

4、发送内联资源

    /**
     * 发送内联资源邮件
     */
    public void sendMailInlineResource(ToEmail toEmail) {
        System.out.println(toEmail);
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom("Lolita<xxxxx@qq.com>");
            helper.setTo(toEmail.getTo());
            helper.setSubject(toEmail.getSubject());
            //true 表示能识别HTML标签
            helper.setText(toEmail.getText(),true);
            //添加内联资源  参数一 表示内容的ID可以随便写  参数二 表示指定你要发的内敛资源
            helper.addInline("ftime",new File(toEmail.getSendLocalFile().get("filePath")));
            javaMailSender.send(mimeMessage);
            System.out.println("上传成功");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

 

5、freeMarker的简单使用

5.1、导入jar包

freemarker-2.3.23

5.2、准备模板(.flt文件)

在需要改动的地方使用${ }动态赋值

<html>
<head></head>
<body>
<table border="0" cellspacing="0" cellpadding="0" style="padding-bottom:20px;max-width:516px;min-width:220px">
    <tbody>
    <tr>
        <td width="8" style="width:8px"></td>
        <td>
            <div style="border-style:solid;border-width:thin;border-color:#dadce0;border-radius:8px;padding:40px 20px" align="center" class="m_8407418004312120846mdv2rw">
                <img src="https://ci5.googleusercontent.com/proxy/T_zJ7UbaC9x27OP4-ZCPfDipqYLSGum30AlaxEycVclfvxO8Cze0sZ0kCrXlx6a-MgvW2tswbIyiNVfczjDuGh9okorzC5SUJDfwkHr6-3j1KUu94HuAw5uxM_jaElQef3Sub84=s0-d-e1-ft#https://www.gstatic.com/images/branding/googlelogo/2x/googlelogo_color_74x24dp.png" width="74" height="24" aria-hidden="true" style="margin-bottom:16px" alt="Google" class="CToWUd" />
                <div style="font-family:‘Google Sans‘,Roboto,RobotoDraft,Helvetica,Arial,sans-serif;border-bottom:thin solid #dadce0;color:rgba(0,0,0,0.87);line-height:32px;padding-bottom:24px;text-align:center;word-break:break-word">
                    <div style="font-size:24px">
                        尊敬的 ${adminName} 你好 :
                    </div>
                    <table align="center" style="margin-top:8px">
                        <tbody>
                        <tr style="line-height:normal">
                            <td align="right" style="padding-right:8px"><img width="20" height="20" style="width:20px;height:20px;vertical-align:sub;border-radius:50%" src="https://lh4.googleusercontent.com/-Yw-z5rdKMhQ/AAAAAAAAAAI/AAAAAAAAAAA/AMZuuckjcNzqy44Cp14ASh48P7xI2_JM0w/s96/photo.jpg"  class="CToWUd" /></td>
                            <td><a style="font-family:‘Google Sans‘,Roboto,RobotoDraft,Helvetica,Arial,sans-serif;color:rgba(0,0,0,0.87);font-size:14px;line-height:20px">${adminEmail}</a></td>
                        </tr>
                        </tbody>
                    </table>
                </div>
                <div style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:14px;color:rgba(0,0,0,0.87);line-height:20px;padding-top:20px;text-align:center">
                    您想用 Google 邮箱激活????图书账号。因此,我们向您发送这封电子邮件,
                    <wbr />以确保该操作是您本人所为。你可以点击按钮进行激活。
                    <div style="padding-top:32px;text-align:center">
                        <a href="${activeUrl}"style="font-family:‘Google Sans‘,Roboto,RobotoDraft,Helvetica,Arial,sans-serif;line-height:16px;color:#ffffff;font-weight:400;text-decoration:none;font-size:14px;display:inline-block;padding:10px 24px;background-color:#4184f3;border-radius:5px;min-width:90px" target="_blank">点此激活</a>
                    </div>
                </div>
                <div style="padding-top:20px;font-size:12px;line-height:16px;color:#5f6368;letter-spacing:0.3px;text-align:center">
                    您也可以查看安全性活动
                    <br />
                    <a style="color:rgba(0,0,0,0.87);text-decoration:inherit">https://myaccount.google.com/<wbr />notifications</a>
                </div>
            </div>
            <div style="text-align:left">
                <div style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;color:rgba(0,0,0,0.54);font-size:11px;line-height:18px;padding-top:12px;text-align:center">
                    <div>
                        我们向您发送这封电子邮件,目的是让您了解关于您的 Google 帐号和服务的重大变化。
                    </div>
                    <div style="direction:ltr">
                        &copy; 2020 Google LLC,
                        <a class="m_8407418004312120846afal" style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;color:rgba(0,0,0,0.54);font-size:11px;line-height:18px;padding-top:12px;text-align:center">1600 Amphitheatre Parkway, Mountain View, CA 94043, USA</a>
                    </div>
                </div>
            </div></td>
        <td width="8" style="width:8px"></td>
    </tr>
    </tbody>
</table>
</body>
</html>

 

5.3、读取模板

1、在springmvc配置模板文件的位置

<!--    配置FreemarkerConfigure-->
    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/template/"/>
        <property name="defaultEncoding" value="utf-8"/>
    </bean>

2、读取模板并发送

@Controller
public class FreemarkerController {

    /*
     * 配置模板的位置
     * jsp也是一个模板引擎
     * freemarker
     *
     *
     * */

    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @GetMapping("readTemplate")
    @ResponseBody
    public String readTemplate() throws Exception {
        Configuration configuration = freeMarkerConfigurer.getConfiguration();
        //获取模板
        Template template = configuration.getTemplate("active.ftl", "utf-8");
        Map<String, String> map = new HashMap<>();
        map.put("adminName", "xxxxxxx马宝国");
        map.put("activeUrl", "http://www.baidu.com");
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("E:\\active.html"), "utf8");
        template.process(map, writer);
        writer.close();
        return "success";


    }
}

6、发送模板邮件

  实际工作中,会使用到很多的模板,不止一个,所以我们给读取模板抽出来,写一个方法获取模板的字符串数据

    
     @Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;

/** * 获取模板字符串 * @param templateName 模板名字 * @param data 模板中要添加的数据 * @return 模板的字符串 出异常(只会出获取模板异常)有返回空的字符串 */ public String getTemplateString(String templateName,Object data){ try { Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateName, "utf-8"); StringWriter stringWriter = new StringWriter(); //写入 template.process(data, stringWriter); //刷新 stringWriter.flush(); //生成字符串 String string = stringWriter.toString(); return string; } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } return ""; } /** * 发送模板邮件 * @param */ public void sendActiveEmail(String templateString,String email) { try { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8"); helper.setFrom("Lolita<1454711778@qq.com>"); helper.setTo(email); helper.setSubject("邮箱激活"); helper.setText(templateString, true); javaMailSender.send(mimeMessage); } catch (MessagingException e) { e.printStackTrace(); } }

 

7、异步线程池的编写

  因为发送邮件是一个耗时的操作,有可能会阻塞程序,所以我们把发送邮件这个操作放到子线程中操作

1、创建线程池

package top.ftime.wk.pool;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author: JAVASM
 * @className: Asyncmanager
 * @description:
 * @date: 2021/6/8 15:50
 * @version: 0.1
 * @since: jdk1.8
 * 单例模式设计线程池
 */
public class AsyncManager {

    private static ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;

    private static AsyncManager asyncManager;

    private AsyncManager() {
        scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(50);
    }

    /**
     * 创建单例对象
     * @return
     */
    public static AsyncManager getInstance() {
        if (asyncManager == null) {
            return new AsyncManager();
        }
        return asyncManager;
    }

    /**
     * 使用线程池执行内容
     * 这种执行没有延迟时间
     *
     * @param runnable
     */
    public void execute(Runnable runnable) {
        scheduledThreadPoolExecutor.execute(runnable);
    }

    /**
     * 使用线程池执行内容
     * 这种执行可以延迟一段时间后执行Runnable中的代码
     * @param runnable
     * @param seconds 表示延迟的时间
     */
    public void schedule(Runnable runnable, long seconds) {
        scheduledThreadPoolExecutor.schedule(runnable, seconds, TimeUnit.SECONDS);
    }

    /**
     * 关闭线程池
     */
    public void release(){
        scheduledThreadPoolExecutor.shutdownNow();
    }
}

2、获取不在容器中的对象

package top.ftime.wk.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author: JAVASM
 * @className: StringUtils
 * @description:
 * @date: 2021/6/8 16:14
 * @version: 0.1
 * @since: jdk1.8
 * 获取容器中的对象
 */
@Component
public class SpringUtils implements ApplicationContextAware{

    /**
     * 获取容器中的对象
     * 1、在容器中如何获取
     *      A在容器中,B也在容器中
     *      A想获取B 只需要在成员变量上添加@Autowired注解
     * 2、不在容器中的类,如何获取容器中的对象
     *      ApplicationContext.getBean("")
     *      当项目启动时,这个方法就会走,会把系统的ApplicationContext传入这个函数中
     *      前提是这个类要在容器中
     */
    private static ApplicationContext applicationContext1;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContext1 = applicationContext;
    }

    /**
     * 获得Bean
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz){
        T bean = applicationContext1.getBean(clazz);
        return bean;
    }
}

 

3、设计工厂发送邮件

package top.ftime.wk.factory;

import com.alibaba.druid.support.spring.stat.SpringStatUtils;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import top.ftime.wk.utils.SpringUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

/**
 * @author: JAVASM
 * @className: AsyncFactory
 * @description:
 * @date: 2021/6/8 16:07
 * @version: 0.1
 * @since: jdk1.8
 * 工厂模式创建发送邮件的工厂
 */
public class AsyncFactory {

    /**
     * 发送验证码邮件
     * @param toUser
     * @param code
     * @return
     */
    public static Runnable sendLoginCodeMail(String toUser,String code){
        //获取容器中的对象
        JavaMailSender bean = SpringUtils.getBean(JavaMailSender.class);
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        //邮件发送者
        simpleMailMessage.setFrom("Flower-time<1454711778@qq.com>");
        //邮件接受者
        simpleMailMessage.setTo(toUser);
        //邮件主题
        simpleMailMessage.setSubject("验证码");
        //邮件内容
        simpleMailMessage.setText("你的登录验证码为 :" + code + "两分钟内有效");
        Runnable runnable = ()->{
            //当前线程名
            System.out.println("当前线程为:"+Thread.currentThread().getName());
            bean.send(simpleMailMessage);
        };
        return runnable;
    }

    /**
     * 发送激活邮件
     * @param templateString
     * @param toUser
     * @return
     */
    public static Runnable sendActiveEmail(String templateString,String toUser){
        try {
            JavaMailSender bean = SpringUtils.getBean(JavaMailSender.class);
            MimeMessage mimeMessage = bean.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8");
            helper.setFrom("Lolita<1454711778@qq.com>");
            helper.setTo(toUser);
            helper.setSubject("邮箱激活");
            helper.setText(templateString, true);
            Runnable runnable = ()->{
                //当前线程名
                System.out.println("当前线程为:"+Thread.currentThread().getName());
                bean.send(mimeMessage);
            };
            return runnable;
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return ()->{};
    }
}

 4、使用

@Controller
public class CommonController {

    @Autowired
    private AdminService adminService;

    private Jedis jedis = JedisUtil.getJedis();

    /**
     * 登录验证
     * 邮箱是否存在
     * 用户是否激活
     * 验证码邮件发送,保存在Redis中
     * 耗时操作,放到子线程中操作
     *
     * @param email
     * @return
     */
    @GetMapping("getCode")
    @ResponseBody
    public AjaxResult loginGetCode(String email) {
        System.out.println("前端值" + email);
        //查询邮箱是否存在数据库
        Admin adminByEmail = adminService.findAdminByEmail(email);
        System.out.println("查询值" + adminByEmail);
        if (null == adminByEmail) {
            //没有,返回邮箱不存在
            System.out.println("不存在");
            System.out.println(AjaxResult.error(AjaxStatus.EMAIL_NOT_FOUND));
            return AjaxResult.error(AjaxStatus.EMAIL_NOT_FOUND);
        } else {
            //有,发送验证码
            // 是否激活
            if (adminByEmail.getActive()) {
                //激活,发送
                String code = RandomCodeUtil.strCode();
                //redis 缓存
                jedis.set(email, code);
                //两分钟后自动删除
                jedis.expire(email, 120);
                //邮件发送是一个耗时的操作 所以放到了子线程中,并使用工厂模式获取Runnable
                AsyncManager.getInstance().execute(AsyncFactory.sendLoginCodeMail(email,code));
                return AjaxResult.success();
            } else {
                //未激活,激活
                return AjaxResult.error(AjaxStatus.ADMIN_NOT_ACTIVE);
            }
        }
    }
}

 

 

SSM项目下的邮件发送

原文:https://www.cnblogs.com/mini9264/p/14880371.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!