专栏首页IT笔记SpringBoot开发案例之异常处理并邮件通知

SpringBoot开发案例之异常处理并邮件通知

前言

在项目开发中,对于异常处理我们通常有多种处理方式,比如:控制层手动捕获异常,拦截器统一处理异常。今天跟大家分享一种注解的方式,统一拦截异常并处理。

异常处理

在spring 3.2中,新增了@RestControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。

创建 RRExceptionHandler,并添加 @RestControllerAdvice注解,来这样就可以拦截所有控制层上抛出来的异常。

/**
 * 异常处理器
 * 创建时间    2017年11月20日
 */
@RestControllerAdvice
public class RRExceptionHandler {

    @Autowired
    private IMailService mailService;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${alarm.email}")
    private String[] email;

    /**
     * 自定义异常
     */
    @ExceptionHandler(RRException.class)
    public Result handleRRException(RRException e){
        Result r = new Result();
        r.put("code", e.getCode());
        r.put("msg", e.getMessage());
        return r;
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public Result handleDuplicateKeyException(DuplicateKeyException e){
        logger.error(e.getMessage(), e);
        return Result.error("数据库中已存在该记录");
    }

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e){
        StringWriter stringWriter = new StringWriter();
        e.printStackTrace(new PrintWriter(stringWriter));
        Email mail = new Email();
        mail.setEmail(email);
        mail.setSubject("工作流系统告警");
        mail.setContent(stringWriter.toString());
        //mailService.send(mail);
        mailService.sendFreemarker(mail);
        logger.error(e.getMessage(), e);
        return Result.error();
    }
}

自定义异常 RRException:

/**
 * 自定义异常
 * 创建时间    2017年11月20日
 */
public class RRException extends RuntimeException {
    
    private static final long serialVersionUID = 1L;
    
    private String msg;
    
    private int code = 500;
    
    public RRException(String msg) {
        super(msg);
        this.msg = msg;
    }
    
    public RRException(String msg, Throwable e) {
        super(msg, e);
        this.msg = msg;
    }
    
    public RRException(String msg, int code) {
        super(msg);
        this.msg = msg;
        this.code = code;
    }
    
    public RRException(String msg, int code, Throwable e) {
        super(msg, e);
        this.msg = msg;
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

邮件通知

邮件通知,需要引入以下配置:

<!-- email -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- freemarker 模版 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

配置模板邮件参数:

# freemarker
spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.enabled=true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.allow-request-override=false
spring.freemarker.check-template-location=true
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false

# 邮件配置
spring.mail.host=smtp.163.com
spring.mail.username=13105423559@163.com
spring.mail.password=123456
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

# 告警通知 多个以逗号分隔
alarm.email = 345849402@qq.com

定义Email封装类:

/**
 * Email封装类
 */
public class Email implements Serializable {
    private static final long serialVersionUID = 1L;
    // 必填参数
    private String[] email;// 接收方邮件
    private String subject;// 主题
    private String content;// 邮件内容
    // 选填
    private String template;// 模板
    private HashMap<String, String> kvMap;// 自定义参数

    public Email() {
        super();
    }

    public Email(String[] email, String subject, String content, String template, HashMap<String, String> kvMap) {
        super();
        this.email = email;
        this.subject = subject;
        this.content = content;
        this.template = template;
        this.kvMap = kvMap;
    }

    public String[] getEmail() {
        return email;
    }

    public void setEmail(String[] email) {
        this.email = email;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTemplate() {
        return template;
    }

    public void setTemplate(String template) {
        this.template = template;
    }

    public HashMap<String, String> getKvMap() {
        return kvMap;
    }

    public void setKvMap(HashMap<String, String> kvMap) {
        this.kvMap = kvMap;
    }
}

发送接口:

public interface IMailService {
    /**
     * 纯文本
     * @param mail
     * @throws Exception
     */
     public void send(Email mail);
    /**
     * 模版发送 freemarker
     * @param mail
     * @throws Exception
     */
     public void sendFreemarker(Email mail);
    
}

发送实现:

@Service
public class MailServiceImpl implements IMailService {
    private static final Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);
    @Autowired
    private JavaMailSender mailSender;//执行者
    @Autowired
    public Configuration configuration;//freemarker
    @Value("${spring.mail.username}")
    public String USER_NAME;//发送者
    @Value("${server.path}")
    public String PATH;//邮件服务地址,用于显示图片
    
    //文本分割
    static {
         System.setProperty("mail.mime.splitlongparameters","false");
    }

    @Override
    public void send(Email mail) {
        try {
            logger.info("发送邮件:{}",mail.getContent());
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(USER_NAME);
            message.setTo(mail.getEmail());
            message.setSubject(mail.getSubject());
            message.setText(mail.getContent());
            mailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void sendFreemarker(Email mail) {
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //这里可以自定义发信名称比如:工作流
            helper.setFrom(USER_NAME,"工作流");
            helper.setTo(mail.getEmail());
            helper.setSubject(mail.getSubject());
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("mail", mail);
            model.put("path", PATH);
            Template template = configuration.getTemplate(mail.getTemplate());
            String text = FreeMarkerTemplateUtils.processTemplateIntoString(
                    template, model);
            helper.setText(text, true);
            mailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

定义发送模板 notify.ftl :

<!doctype html>
<html lang="zh-cmn-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="renderer" content="webkit" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Document</title>
</head>
<body>
   您好:${mail.content} 
</body>
</html>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringBoot开发案例之邮件多实例发送

    最近在做邮件发送的服务,正常来说 SpringBoot 整合mail还是很方便的,然而来了新的需求:A请求使用邮箱C发送,B请求使用邮箱D发送,也就是说我们需要...

    小柒2012
  • SpringBoot开发案例之邮件多实例发送

    最近在做邮件发送的服务,正常来说 SpringBoot 整合mail还是很方便的,然而来了新的需求:A请求使用邮箱C发送,B请求使用邮箱D发送,也就是说我们需要...

    小柒2012
  • SpringBoot开发案例之邮件发不出去了

    纯粹为了记录,如果,恰巧与你遇到的是一个问题,可以通过以下方法解决你的问题,那么对于你我来说都是一件非常开心的事情。

    小柒2012
  • Spring Boot 发送邮件实战全解析

    欢迎阅读 Spring Boot 2 实战系列[1] 电子邮件虽然近几年有点“退火”,但是在开发中依然有举足轻重的地位。在比较正式的场合我们依然通过电子邮件来传...

    码农小胖哥
  • Spring Boot 发送邮件实战全解析

    欢迎阅读 Spring Boot 2 实战系列[1] 电子邮件虽然近几年有点“退火”,但是在开发中依然有举足轻重的地位。在比较正式的场合我们依然通过电子邮件来传...

    用户4172423
  • python3实现邮件的发送

    使用的email和smtplib模块,这里简单介绍下smtplib.SMTP()类

    dogfei
  • python 通过qq邮箱发送磁盘监控告警

    葫芦
  • java使用策略模式代替if/else

    平时在开发中避免不了使用大量的if else语句,但过多层的if else对于性能有很大的开销,类似如下代码

    HUC思梦
  • 利用php发信组件实现表单提交邮件发送功能

    V站CEO-西顾
  • 使用开源phpmailer发送邮件

    网上也有几篇教程,不过我是为了给自己的服务可以发送邮件给自己用,所以只是用phpmailer的base功能,不需要使用smtp。

    libo1106

扫码关注云+社区

领取腾讯云代金券