zoukankan      html  css  js  c++  java
  • springboot mail+Thymeleaf模板

    compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
    compile 'io.ratpack:ratpack-thymeleaf:1.4.2'
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.mail.javamail.MimeMessagePreparator;
    import org.springframework.stereotype.Service;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.WebContext;
    import ratpack.thymeleaf.internal.ThymeleafHttpServletRequestAdapter;
    import ratpack.thymeleaf.internal.ThymeleafHttpServletResponseAdapter;
    import ratpack.thymeleaf.internal.ThymeleafServletContextAdapter;
    
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Method;
    import java.util.*;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    
    /**
     * Created by hujunzheng on 17/9/8.
     */
    @Service
    public class MailService {
    
        @Autowired
        private MailProperties mailProperties;
    
        @Autowired
        private JavaMailSender javaMailSender;
    
        @Autowired
        private TemplateEngine templateEngine;
    
        private static final Log log = LogFactory.getLog(MailService.class);
        /**
         * 发送邮件
         * @param userEmail
         * @param templateId
         */
        public void sendMail(String userEmail, Map<String, Object> params, int templateId) {
            sendMailMultiParams(new String[] {userEmail}, params, templateId);
        }
    
        public void sendMail(String userEmail, Object obj, int templateId) {
            Map<String, Object> params = objectToMap(obj);
            sendMailMultiParams(new String[] {userEmail}, params, templateId);
        }
    
        public void sendMail(String userEmail, String  message, String subject) {
            sendSampleMail(new String[] {userEmail}, message, subject);
        }
    
        public void sendMail(String[] userEmails, Map<String, Object> params, int templateId) {
            sendMailMultiParams(userEmails, params, templateId);
        }
    
        public void sendMail(String[] userEmails, Object obj, int templateId) {
            Map<String, Object> params = objectToMap(obj);
            sendMailMultiParams(userEmails, params, templateId);
        }
    
        public void sendMail(String[] userEmails, String  message, String subject) {
            sendSampleMail(userEmails, message, subject);
        }
    
        private Map<String, Object> objectToMap(Object obj) {
            PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(obj.getClass());
            Map<String, Object> params = new HashMap<>();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (key.compareToIgnoreCase("class") == 0) {
                    continue;
                }
                Optional<Method> getter = Optional.ofNullable(property.getReadMethod());
                try {
                    Object value = getter.isPresent() ? getter.get().invoke(obj) : null;
                    params.put(key, value);
                } catch (ReflectiveOperationException e) {
                    e.printStackTrace();
                }
            }
            return params;
        }
    
        /**
         * 异步 分别发送 发送邮件
        * */
        public List<String> asynSendMails(List<ApiPortalOperator> apiPortalOperators, Object bodyParams) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            List<FutureTask<String>> futureTasks = new ArrayList<>();
            for (ApiPortalOperator apiPortalOperator : apiPortalOperators) {
                FutureTask<String> futureTask = new FutureTask(() -> {
                    try {
                        this.sendMail(apiPortalOperator.getEmail(), bodyParams, 1);
                    } catch (Exception e) {
                        return "邮件to " + apiPortalOperator.getEmail() + " 发送异常:" + e.getMessage();
                    }
                    return "邮件to " + apiPortalOperator.getEmail() + " 发送成功";
                });
                futureTasks.add(futureTask);
                executorService.submit(futureTask);
            }
    
            List<String> result = new ArrayList<>();
            for (int i=0; i<futureTasks.size(); ++i) {
                FutureTask futureTask = futureTasks.get(i);
                try {
                    result.add((String) futureTask.get());
                } catch (Exception e) {
                    result.add("to " + apiPortalOperators.get(i).getEmail() + " 发送失败:" + e.getMessage());
                }
            }
    
            return result;
        }
    
        /**
         * 异步 多个收件人一起 发送邮件
         * */
        public String asynSendMail(List<ApiPortalOperator> apiPortalOperators, Object bodyParams) {
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            String[] userEmails = apiPortalOperators.stream().map(ApiPortalOperator::getEmail).toArray(String[]::new);
            FutureTask<String> futureTask = new FutureTask(() -> {
                try {
    
                    this.sendMail(userEmails, bodyParams, 1);
                } catch (Exception e) {
                    return "邮件to " + StringUtils.join(userEmails, ',') + " 发送异常:" + e.getMessage();
                }
                return "邮件to " + StringUtils.join(userEmails, ',') + " 发送成功";
            });
            executorService.submit(futureTask);
            try {
                return futureTask.get();
            } catch (Exception e) {
                e.printStackTrace();
                return "邮件to " + StringUtils.join(userEmails, ',') + " 发送异常:" + e.getMessage();
            }
        }
    
        private void sendSampleMail(String[] userEmail, String msg, String subject) {
            MimeMessagePreparator preparator = new MimeMessagePreparator() {
                @Override
                public void prepare(MimeMessage mimeMessage) throws Exception {
                    MimeMessageHelper message = new MimeMessageHelper(mimeMessage, "utf-8");
                    message.setTo(userEmail);
                    message.setFrom(new InternetAddress(mailProperties.getFrom()));
                    message.setSubject(subject);
                    message.setText(msg);
                }
            };
            try {
                this.javaMailSender.send(preparator);
            } catch (Exception ex) {
                log.error("Mailing Exception! user email is: {}", userEmail, ex);
            }
            log.info("Mail sent successfully, user email is: {}", userEmail);
        }
    
        private String buildTemplateMessage(String templateName, Map<String, Object> messages) {
            HttpServletRequest request = new ThymeleafHttpServletRequestAdapter();
            HttpServletResponse response = new ThymeleafHttpServletResponseAdapter();
            ServletContext servletContext = new ThymeleafServletContextAdapter();
            WebContext context = new WebContext(request, response, servletContext);
            context.setVariables(messages);
            return templateEngine.process(templateName, context);
        }
    
        /**
         * 当发邮件时有多个不定参数时
         * @param userEmail 用户邮箱
         * @param params 发邮件的参数
         * @param templateId
         */
        private void sendMailMultiParams(String[] userEmail, Map<String, Object> params, Integer templateId) {
    
            String templateName = MailTemplate.getTemplateName(templateId);
    
            MimeMessagePreparator preparator = new MimeMessagePreparator() {
                @Override
                public void prepare(MimeMessage mimeMessage) throws Exception {
                    MimeMessageHelper message = new MimeMessageHelper(mimeMessage, "utf-8");
                    message.setTo(userEmail);
                    message.setFrom(new InternetAddress(mailProperties.getFrom()));
                    message.setSubject(MailTemplate.getTemplateSubject(templateId));
    
                    String content = buildTemplateMessage(templateName, params);
                    System.out.println(content);
                    message.setText(content, true);
                }
            };
            try {
                this.javaMailSender.send(preparator);
            } catch (Exception ex) {
                log.error("Mailing Exception! user email is: {}, template params are: {}, template_id is: {}", userEmail, params.toString(), templateId, ex);
            }
            log.info("Mail sent successfully, user email is: {}, template params: {}, template_id is: {}", userEmail, params.toString(), templateId);
        }
    }

    Thymeleaf 中有 plain context (不支持对url参数的解析)和 web context(支持对url参数的解析)

    We'll have to change our code to create a web context, instead of a plain context. Change will be here: 
    
    参考:https://github.com/ratpack/ratpack/blob/master/ratpack-thymeleaf/src/main/java/ratpack/thymeleaf/Template.java#L69-69
    
    The IWebContext interface seems coupled to the servlet API, but after quick look at the code I don't think this will be a problem. I think we can just provide null values for things like request/session etc. that we can't provide. If that turns out to be a problem… we can look at providing implementations of those Servlet API type in so far makes sense.

    最后附上一份简单的邮件模板文件

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>邮件提醒</title>
    </head>
    <body style="margin: 0; padding: 0;">
    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="padding: 20px; font-size: 14px;">
        <tbody>
        <tr>
            <td><p style="margin: 0; margin-bottom: 20px;">Hi,</p></td>
        </tr>
        <tr>
            <td><p style="margin: 0; margin-bottom: 20px;">项目<span th:text="${project}"/>的API已设计完成,请到<a href="#" th:href="@{ ${apiUrl} }">API Portal</a>上review。</p></td>
        </tr>
        <tr th:each="link,status : ${links}">
            <td><p style="margin: 0;"><span th:text="${status.count}"/>. <span th:text="${link.method}"/>&nbsp;<span th:text="${link.path}"/>&nbsp;<span th:text="${link.description}"/>&nbsp;<a href="#" th:href="@{ ${link.url} }">点击查看</a></p></td>
        </tr>
        <tr>
            <td><p style="margin: 0; margin-top: 20px;">Thanks</p></td>
        </tr>
        <tr>
            <td><p style="margin: 0;"><span th:text="${user}"/></p></td>
        </tr>
        </tbody>
    </table>
    </body>
    </html>
  • 相关阅读:
    关于 JAVA 中使用 Preferences 读写注册表时要注意的地方
    VS2010编译以前版本工程时 ERROR CVT1100:duplicate resource,type:MANIFEST解决办法
    在博客园安家了,同时献上刚汉化的 Code Snippet 插件!
    安装mariadb
    路飞学城部署方法
    配置supervisor工具
    使用uwsgi启动django项目
    nginx访问日志和压测命令
    nginx学习
    虚拟环境之virtualenvwrapper
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/7562805.html
Copyright © 2011-2022 走看看