写点什么

SpringBoot 基于异常处理 exception 发送邮件消息提醒

作者:宁在春
  • 2022 年 7 月 28 日
  • 本文字数:4730 字

    阅读完需:约 16 分钟

SpringBoot基于异常处理exception发送邮件消息提醒

在项目常常会出现一些意料之外的错误,不能及时处理,大家都懂的哈。😁当然现在有很多监控服务,我这点能力是不够写的哈。☺

就有了这么一个小小的思路,用邮件服务来提醒出现异常啦。👩‍💻

(狗头保命)👩‍💻

很喜欢一句话:”八小时内谋生活,八小时外谋发展“我们:"待别日相见时,都已有所成”😁


一、前言

SpringBoot异步实现发送邮件服务

1)异常处理概述:

异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。通过异常处理,我们可以对用户在程序中的非法输入进行控制和提示,以防程序崩溃。以返回正确的信息给前台。

2)异常处理:

SpringBoot 中的异常处理分为局部处理异常和全局处理异常。方式稍稍有些差异。


2.1、局部异常处理


  • 是在当前类中进行处理,复用性太低,不推荐使用,所以只是简单举个例子哈。

  • @ExceptionHandler 注解处理局部异常


例如:


@Controllerpublic class ExceptionController {    private static final Logger log = LoggerFactory.getLogger(ExceptionController.class);    @RequestMapping("/exceptionMethod")  public String exceptionMethod(Model model) throws Exception {    model.addAttribute("msg", "没有抛出异常");    int num = 1/0;    log.info(String.valueOf(num));    return "home";  }    /**   * 描述:捕获 ExceptionController 中的 ArithmeticException 异常   * @param model 将Model对象注入到方法中   * @param e 将产生异常对象注入到方法中   * @return 指定错误页面   */  @ExceptionHandler(value = {ArithmeticException.class})  public String arithmeticExceptionHandle(Model model, Exception e) {    model.addAttribute("msg", "@ExceptionHandler" + e.getMessage());    log.info(e.getMessage());    return "error";  }}
复制代码


2.2、全局异常处理


  • 使用 @ControllerAdvice + @ExceptionHandler 注解能够处理全局异常,这种方式推荐使用,可以根据不同的异常对不同的异常进行处理。


这种稍后会在案例中讲解。


全局处理还有一种方式:配置 SimpleMappingExceptionResolver 类处理异常


因为现在使用 SpringBoot 更多的是使用前后端分离的方式,这种和视图的关联就不怎么合适,所以也归入不推荐的方式中啦。


@Configurationpublic class GlobalException {  @Bean  public SimpleMappingExceptionResolver    getSimpleMappingExceptionResolver(){    SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();    Properties mappings = new Properties();    /*     * 参数一:异常的类型,注意必须是异常类型的全名     * 参数二:视图名称     */    mappings.put("java.lang.ArithmeticException", "errors");        //设置异常与视图映射信息的    resolver.setExceptionMappings(mappings);    return resolver;  }}
复制代码

二、环境准备

案例


我这里只是简单模拟了一个最简单的异常来测试哈。就是请求方法出错HttpRequestMethodNotSupportedException,然后发送邮件哈。


项目结构



下面来看具体的代码:

2.1、导入依赖

<parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>2.5.2</version>    <relativePath/> <!-- lookup parent from repository --></parent><dependencies>    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <scope>test</scope>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter</artifactId>    </dependency>    <dependency>        <groupId>org.projectlombok</groupId>        <artifactId>lombok</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-mail</artifactId>    </dependency></dependencies>
复制代码

2.2、yml 配置文件

server:  port: 8092spring:  application:    name: springboot-exception-email  mail:    # 配置 SMTP 服务器地址    host: smtp.qq.com    # 发送者邮箱    username:     # 配置密码,注意不是真正的密码,而是刚刚申请到的授权码    password:    # 端口号465或587    port: 587    # 默认的邮件编码为UTF-8    default-encoding: UTF-8    # 配置SSL 加密工厂    properties:      mail:        smtp:          socketFactoryClass: javax.net.ssl.SSLSocketFactory        #表示开启 DEBUG 模式,这样,邮件发送过程的日志会在控制台打印出来,方便排查错误        debug: true
复制代码

2.3、一些公共的类

ThreadPoolTaskExecutorConfig :线程池配置类


/** * 异步线程池ThreadPoolExecutor 配置类 * @author cuberxp * @since 1.0.0 * Create time 2020/4/2 23:23 */@Configuration@EnableAsyncpublic class ThreadPoolTaskExecutorConfig {
@Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //设置核心线程数 executor.setCorePoolSize(10); //设置最大线程数 executor.setMaxPoolSize(20); //缓冲队列200:用来缓冲执行任务的队列 executor.setQueueCapacity(200); //线程活路时间 60 秒 executor.setKeepAliveSeconds(60); //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池 executor.setThreadNamePrefix("taskExecutor-"); //设置拒绝策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.setWaitForTasksToCompleteOnShutdown(true); return executor; }}
复制代码


ResponseDto:统一返回给前端的数据


/** * @author crush */@Data@NoArgsConstructorpublic class ResponseDto<T> {    /** * 错误码*/    private Integer code;    /** * 提示信息*/    private String msg;    /** * 具体的内容*/    private T data;
public ResponseDto(Integer code, String msg) { this.code = code; this.msg = msg; this.data = null; } public static ResponseDto success(Object object){ ResponseDto result = new ResponseDto(); result.setCode(200); result.setMsg("操作成功"); result.setData(object); return result; }}
复制代码


一些基础环境就准备好了,剩下就是最简单的编码啦哈。

2.4、全局异常处理

/** * @author crush * @ControllerAdvice * @ResponseBody //表示返回的对象,Spring会自动把该对象进行json转化,最后写入到Response中。 */@ControllerAdvice@ResponseBody@Componentpublic class GlobalExceptionHandler {
@Autowired EmailService emailService; /** * //表示让Spring捕获到所有抛出的SignException异常,并交由这个被注解的方法处理。 * //表示设置状态码 * @return */ @ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) ResponseDto handleException(HttpRequestMethodNotSupportedException exception){ LogEmail email = new LogEmail() .setToEmail("951930136@qq.com") .setSubject("异常报告") .setContext(exception.getMessage()); emailService.senderEmail(email); return new ResponseDto(405,exception.getMessage()); }}
复制代码

三、业务代码

3.1、entity

@Data@Accessors(chain = true)public class LogEmail {    private String toEmail;    private String fromEmail;    private String subject;    private String context;}
复制代码

3.2、Service

public interface EmailService {    /*** 出现异常 发送短信*/    void senderEmail(LogEmail logEmail);}
@Slf4j@Servicepublic class EmailServiceImpl implements EmailService {
@Autowired private JavaMailSender javaMailSender;
@Value("${spring.mail.username}") private String fromEmail;
@Async("taskExecutor") @Override public void senderEmail(LogEmail logEmail) { log.info(Thread.currentThread().getName()); //一个复杂的邮件 MimeMessage message = this.javaMailSender.createMimeMessage(); try { //组装 MimeMessageHelper helper = new MimeMessageHelper(message, true); //正文 //主题 helper.setSubject(logEmail.getSubject()); //开启html模式 helper.setText("<h1>"+logEmail.getContext()+"</h1>" ,true); //附件 helper.addAttachment("1.jpg", new File("C:\\Users\\ASUS\\Desktop\\杂七杂八\\杂图\\2.gif")); helper.setTo(logEmail.getToEmail()); helper.setFrom(fromEmail); javaMailSender.send(message); } catch (MessagingException e) { e.printStackTrace(); } }}
复制代码

3.3、Controller

@RestControllerpublic class DemoController {    @GetMapping("/test")    public ResponseDto test(){![在这里插入图片描述](https://img-blog.csdnimg.cn/d5ba2fdfee864dec834cac791c09ef65.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTgyMTgxMQ==,size_16,color_FFFFFF,t_70#pic_center)
return ResponseDto.success("我喜欢你!!!"); }}
复制代码


业务代码就这些了,不过记得要补充一个主启动类哈,这个我就不贴啦哈。

四、测试

测试特别简单,先看正常的哈。


我们用正确的GET方式发送请求是完全没有问题的,返回也是正确的数据。



接下来我们用POST方式来请求,看能不能正确的调用邮件方法发送邮件啊😁



证明我们确实已经抓住了这个异常,并且也成功发送了邮件。


这里只是一个小小的 Demo,处理的异常也比较简单,如果真正要去用的话,肯定是不会放在这样的异常上面的,而是一些更加重要的异常上面,细节也会更加的完善。邮件可以一次性提醒很多人,方便应用程序的及时维护。

五、自言自语


我知道咱们掘金的大佬,讲话又好听,长的又帅,女朋友随便 new,给小弟一个赞👍,这肯定的吧。😁


你好,如果你正巧看到这篇文章,并且觉得对你有益的话,就给个赞吧,让我感受一下分享的喜悦吧,蟹蟹。🤗


如若有写的有误的地方,也请大家不啬赐教!!


同样如若有存在疑惑的地方,请留言或私信,定会在第一时间回复你。


持续更新中

发布于: 4 小时前阅读数: 9
用户头像

宁在春

关注

一个喜欢文艺风的程序员 2022.07.01 加入

他日凌云,万事胜意

评论

发布
暂无评论
SpringBoot基于异常处理exception发送邮件消息提醒_springboot_宁在春_InfoQ写作社区