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>
SpringBoot开发案例之异常处理并邮件通知的更多相关文章
- SpringBoot开发案例从0到1构建分布式秒杀系统
前言 最近,被推送了不少秒杀架构的文章,忙里偷闲自己也总结了一下互联网平台秒杀架构设计,当然也借鉴了不少同学的思路.俗话说,脱离案例讲架构都是耍流氓,最终使用SpringBoot模拟实现了部分秒杀场 ...
- SpringBoot开发案例之多任务并行+线程池处理
前言 前几篇文章着重介绍了后端服务数据库和多线程并行处理优化,并示例了改造前后的伪代码逻辑.当然了,优化是无止境的,前人栽树后人乘凉.作为我们开发者来说,既然站在了巨人的肩膀上,就要写出更加优化的程序 ...
- SpringBoot开发案例之打造私有云网盘
前言 最近在做工作流的事情,正好有个需求,要添加一个附件上传的功能,曾找过不少上传插件,都不是特别满意.无意中发现一个很好用的开源web文件管理器插件 elfinder,功能比较完善,社区也很活跃,还 ...
- SpringBoot开发案例之整合Activiti工作流引擎
前言 JBPM是目前市场上主流开源工作引擎之一,在创建者Tom Baeyens离开JBoss后,JBPM的下一个版本jBPM5完全放弃了jBPM4的基础代码,基于Drools Flow重头来过,目前官 ...
- SpringBoot开发案例之整合Dubbo分布式服务
前言 在 SpringBoot 很火热的时候,阿里巴巴的分布式框架 Dubbo 不知是处于什么考虑,在停更N年之后终于进行维护了.在之前的微服务中,使用的是当当维护的版本 Dubbox,整合方式也是使 ...
- SpringBoot开发案例之整合Kafka实现消息队列
前言 最近在做一款秒杀的案例,涉及到了同步锁.数据库锁.分布式锁.进程内队列以及分布式消息队列,这里对SpringBoot集成Kafka实现消息队列做一个简单的记录. Kafka简介 Kafka是由A ...
- SpringBoot开发案例之分布式集群共享Session
前言 在分布式系统中,为了提升系统性能,通常会对单体项目进行拆分,分解成多个基于功能的微服务,如果有条件,可能还会对单个微服务进行水平扩展,保证服务高可用. 那么问题来了,如果使用传统管理 Sessi ...
- SpringBoot开发案例Nacos配置管理中心
前言 在开发过程中,通常我们会配置一些参数来实现某些功能,比如是否开启某项服务,告警邮件配置等等.一般会通过硬编码.配置文件或者数据库的形式实现. 那么问题来了,如何更加优雅的实现?欢迎来到 Naco ...
- 转载-SpringBoot开发案例之整合日志管理
转载:https://cloud.tencent.com/developer/article/1097579 有一种力量无人能抵挡,它永不言败生来倔强.有一种理想照亮了迷茫,在那写满荣耀的地方. 00 ...
随机推荐
- Java实现 LeetCode 321 拼接最大数
321. 拼接最大数 给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字.现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要 ...
- Java实现 LeetCode 222 完全二叉树的节点个数
222. 完全二叉树的节点个数 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集 ...
- java实现第六届蓝桥杯灾后重建
灾后重建 题目描述 Pear市一共有N(<=50000)个居民点,居民点之间有M(<=200000)条双向道路相连.这些居民点两两之间都可以通过双向道路到达.这种情况一直持续到最近,一次严 ...
- linux 删除文件后 df 查看磁盘空间并没有释放
1.错误现象 Linux 磁盘空间总是报警,查到到大文件,删除之后,df看到磁盘空间并没有释放. 用du -sh ./* | sort -nr (查看当前目录下文件的大小)通过查找了下发现文件被mys ...
- Spring新注解
@Configuration作用:指定当前类为一个配置类@ComponentScan作用:用于通过注释指定Spring在创建容器时要扫描的包 当配置类作为AnnotationCon ...
- HTML的简介和历史发展过程
HTML的简介和历史发展过程 前言 这次写一篇对于HTML以及CSS的简介,平常我们大家都知道的编程语言有很多种,比如Java.C++.Python等等,每种编程语言都有其独具的特色,不论是语法格式还 ...
- @bzoj - 2658@ [Zjoi2012]小蓝的好友(mrx)
目录 @description@ @solution@ @accepted code@ @details@ @description@ 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事 ...
- Vugen使用技巧
调整各种选项的超时时间
- 网页中为什么常用AT替换@(repost from https://zhidao.baidu.com/question/122291.html)
经常在个人主页上看到别人的邮箱地址中@被AT符号替代,很是迷惑,这样替代有什么好处呢?还是说html原有的原因使界面中不能出现@,查阅资料后解答如下: 写成AT [at],是为了防止被一些邮件扫描器搜 ...
- Eplan PLC连接点模块为什么不显示“路径功能文本”,已解决
Eplan PLC连接点模块为什么不显示“路径功能文本”,已解决 如果“路径功能文本”的文字开头的位置没有对准PLC模块的中心,PLC连接点模块就不会显示.