============整合全局异常===========

1.整合web访问的全局异常

  如果不做全局异常处理直接访问如果报错,页面会报错500错误,对于界面的显示非常不友好,因此需要做处理。

全局异常处理的类:

package cn.qlq.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView; @ControllerAdvice
public class WebExceptionHandler {
public static final String ERROR_VIEW = "error"; @ExceptionHandler(value = Exception.class)
public Object errorHandler(HttpServletRequest reqest, HttpServletResponse response, Exception e) throws Exception {
e.printStackTrace();
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", reqest.getRequestURL());
mav.setViewName(ERROR_VIEW);
return mav;
}
}

拦截到异常之后会跳转到error页面error.html:

目录结构:

内容如下:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title>捕获全局异常</title>
</head>
<body>
<h1 style="color: red">发生错误:</h1>
<div th:text="${url}"></div>
<div th:text="${exception.message}"></div>
</body>
</html>

测试:

2.整合ajax全局异常处理

  ajax异常处理就是捕捉到异常之后返回一个封装的JSON实体,ajax请求根据返回的状态判断是否请求成功。

封装的工具类:

package cn.qlq.utils;

import java.io.Serializable;

public class JSONResultUtil<T> implements Serializable {

    private static final long serialVersionUID = 3637122497350396679L;

    private boolean success;
private T data;
private String msg; public boolean isSuccess() {
return success;
} public void setSuccess(boolean success) {
this.success = success;
} public T getData() {
return data;
} public void setData(T data) {
this.data = data;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} public JSONResultUtil(boolean success) {
this.success = success;
} public JSONResultUtil(boolean success, String msg) {
super();
this.success = success;
this.msg = msg;
} public JSONResultUtil(boolean success, T data, String msg) {
super();
this.success = success;
this.data = data;
this.msg = msg;
} /**
* 返回正确结果不带数据
*
* @return
*/
public static JSONResultUtil ok() {
return new JSONResultUtil(true);
} /**
* 返回错误的结果带错误信息
*
* @param msg
* @return
*/
public static JSONResultUtil error(String msg) {
return new JSONResultUtil(false, msg);
} }

Ajax请求的错误处理器:

package cn.qlq.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import cn.qlq.utils.JSONResultUtil; @RestControllerAdvice
public class AjaxExceptionHandler {
@ExceptionHandler(value = Exception.class)
public JSONResultUtil defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { e.printStackTrace();
return JSONResultUtil.error(e.getMessage());
}
}

测试:

前台JS:

$.ajax({
url: "/MySpringboot/err/getAjaxerror",
type: "POST",
async: false,
success: function(data) {
if(data.success) {
alert("success");
} else {
alert("发生异常:" + data.msg);
}
},
error: function (response, ajaxOptions, thrownError) {
alert("error");
}
});

后台制造除零异常:

    @RequestMapping("/getAjaxerror")
@ResponseBody
public JSONResultUtil getAjaxerror() {
int a = 1 / 0;
return JSONResultUtil.ok();
}

结果:

3.一个通用的全局异常处理器

  不管是web请求还是ajax请求都可以用它处理。内部根据是否是ajax请求返回对应的数据

package cn.qlq.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView; import cn.qlq.utils.JSONResultUtil; @RestControllerAdvice
public class MyExceptionHandler {
public static final String ERROR_VIEW = "error"; @ExceptionHandler(value = Exception.class)
public Object errorHandler(HttpServletRequest reqest, HttpServletResponse response, Exception e) throws Exception { e.printStackTrace(); if (isAjax(reqest)) {
return JSONResultUtil.error(e.getMessage());
} else {
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", reqest.getRequestURL());
mav.setViewName(ERROR_VIEW);
return mav;
}
} /**
* 根据请求头是否携带X-Requested-With参数判断是否是ajax请求
*
* @param httpRequest
* @return
*/
public static boolean isAjax(HttpServletRequest httpRequest) {
return (httpRequest.getHeader("X-Requested-With") != null
&& "XMLHttpRequest".equals(httpRequest.getHeader("X-Requested-With").toString()));
}
}

============整合定时任务Task===========

  在springmvc使用的时候使用到的定时任务一般是quartz,也研究过使用过SpringTask。SpringBoot整合Task非常简单。

(1)@EnableScheduling开启task

package cn.qlq.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling; @Configuration // 通过该注解来表明该类是一个Spring的配置,相当于一个xml文件
@EnableScheduling
public class SpringTask { }

(2)通过注解的方式使用task即可。

package cn.qlq.task;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; @Component
public class FirstAnnotationJob {
private static int count; @Scheduled(fixedRate = 10000)
public void cron() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.err.println("InterruptedException " + e);
}
System.out.println("spring anno task execute times " + count++);
}
}

结果:

spring anno task execute times 0
spring anno task execute times 1
spring anno task execute times 2

....

关于springTask的使用参考:https://www.cnblogs.com/qlqwjy/p/9960706.html

============整合异步任务===========

  开启异步任务的方式比较简单 。异步任务的使用场景是:发布消息、发送短信等一些异步任务上,当然异步可以用线程池实现,发送消息可以用MQ框架实现。

(1)@EnableAsync声明开启异步任务

package cn.qlq.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling; @Configuration // 通过该注解来表明该类是一个Spring的配置,相当于一个xml文件
//开启Task
@EnableScheduling
//开启异步调用方法
@EnableAsync
public class SpringTask { }

(2)编写异步任务,@Component注入spring,异步的方法加上@Async注解即可

package cn.qlq.task;

import java.util.concurrent.Future;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component; @Component
public class AsyncTask { @Async
public Future<Boolean> doTask11() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(1000);
long end = System.currentTimeMillis();
System.out.println("任务1耗时:" + (end - start) + "毫秒,线程名字:" + Thread.currentThread().getName());
return new AsyncResult<>(true);
} @Async
public Future<Boolean> doTask22() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(700);
long end = System.currentTimeMillis();
System.out.println("任务2耗时:" + (end - start) + "毫秒,线程名字:" + Thread.currentThread().getName());
return new AsyncResult<>(true);
} @Async
public Future<Boolean> doTask33() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(600);
long end = System.currentTimeMillis();
System.out.println("任务3耗时:" + (end - start) + "毫秒,线程名字:" + Thread.currentThread().getName());
return new AsyncResult<>(true);
}
}

(3)Controller层调用异步方法:

package cn.qlq.action;

import java.util.concurrent.Future;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import cn.qlq.task.AsyncTask; @RestController
@RequestMapping("tasks")
public class AsyncTaskController { @Autowired
private AsyncTask asyncTask; @RequestMapping("test1")
public String test1() throws Exception { long start = System.currentTimeMillis(); Future<Boolean> a = asyncTask.doTask11();
Future<Boolean> b = asyncTask.doTask22();
Future<Boolean> c = asyncTask.doTask33(); while (!a.isDone() || !b.isDone() || !c.isDone()) {
if (a.isDone() && b.isDone() && c.isDone()) {
break;
}
} long end = System.currentTimeMillis(); String times = "任务全部完成,总耗时:" + (end - start) + "毫秒";
System.out.println(times); return times;
}
}

  上面执行asyncTask.doTaskXX的时候是异步执行的,相当于三个方法异步执行,下面的while循环直到三个方法都执行完毕。

测试:

前台访问:

后台控制台:(发现是通过多线程执行)

如果去掉上面三个异步方法的@Async注解查看结果:

前台:

后台:(单条线程执行)

SpringBoot整合全局异常处理&SpringBoot整合定时任务Task&SpringBoot整合异步任务的更多相关文章

  1. 【springboot】全局异常处理

    转自: https://blog.csdn.net/cp026la/article/details/86495196 前言: 开发中异常的处理必不可少,常用的就是 throw 和 try catch, ...

  2. springmvc、 springboot 项目全局异常处理

    异常在项目中那是不可避免的,通常情况下,我们需要对全局异常进行处理,下面介绍两种比较常用的情况. 准备工作: 在捕获到异常的时候,我们通常需要返回给前端错误码,错误信息等,所以我们需要手动封装一个js ...

  3. 【转载】springboot四 全局异常处理

    http://tengj.top/2018/05/16/springboot13/ https://www.jb51.net/article/110533.htm

  4. springboot的全局异常处理类

    import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import or ...

  5. springboot 全局异常处理

    springboot 全局异常处理 研究了半天springboot的全局异常处理,虽然还是需要再多整理一下,但是对于常见的404和500足以可以区分开,能够根据这两个异常分别处理 首先配置视图解析路径 ...

  6. SpringBoot中的全局异常处理

    SpringBoot中的全局异常处理 本篇要点 介绍SpringBoot默认的异常处理机制. 如何定义错误页面. 如何自定义异常数据. 如何自定义视图解析. 介绍@ControllerAdvice注解 ...

  7. SpringBoot07 异常枚举、自定义异常、统一的全局异常处理

    1 异常编号和提示信息统一管理 利用枚举来实现异常的统一管理 package cn.xiangxu.springboottest.enums; import lombok.Getter; /** * ...

  8. 【全网最全】springboot整合JSR303参数校验与全局异常处理

    一.前言 我们在日常开发中,避不开的就是参数校验,有人说前端不是会在表单中进行校验的吗?在后端中,我们可以直接不管前端怎么样判断过滤,我们后端都需要进行再次判断,为了安全.因为前端很容易拜托,当测试使 ...

  9. springboot实现定时任务,异步操作,统一结果返回,全局异常处理,拦截器及事务处理

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文都是springboot的常用和实用功能,话不多说开始吧 定时任务 1.启动类开启注解 @EnableScheduling //开启基于注解 ...

随机推荐

  1. (线性结构dp )POJ 1260 Pearls

    Pearls Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10558   Accepted: 5489 Descripti ...

  2. 微服务框架之微软Service Fabric

    常见的微服务架构用到的软件&组件: docker(成熟应用) spring boot % spring cloud(技术趋势) Service Fabric(属于后起之秀 背后是微软云的驱动) ...

  3. docker的使用 -- windows

    1. 下载docker desktop https://www.docker.com/products/docker-desktop 更多操作指令 ps: 值得注意的是,刚下载下来的docker只能在 ...

  4. 设计模式---状态变化模式之state状态模式(State)

    前提:状态变化模式 在组建构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化”模式为这一个问题提供了一种解决方案. 典型模式 状态模式:Stat ...

  5. linux查看IP

    1:输入 ifconfig,出现如下信息,找到eno16777736(网卡ip信息的配置文件名) 2:输入 cd /etc/sysconfig/network-scripts 找到网卡ip信息的配置文 ...

  6. SqlServer中的事务使用

    一.事务的概念和特点 事务(transaction)是恢复和并发控制的基本单位. 事务的特点 原子性:事务是一个工作单元,要都成功,要么的失败 例子:A付款给B,A余额-100,B余额+100,只能都 ...

  7. Eclipse复制web项目怎么改

    在学习中,做一个项目时 , 完成到了某一阶段 实现了部分功能,有必要保存这一项目, 1  在以后的学习中如果能顺利的完成后续部分,可以在需要特定功能时 复习这个项目,  (必要性) 2  如果在后续的 ...

  8. callback hell (回调地狱)

    callback hell (回调地狱) callback(回调) 如何修复 callback hell callback 回调只是存放一些即将要处理的代码. 回调的执行顺序不是从上到下的,而是根据事 ...

  9. jira7通过全局js给编辑区自定义快捷键【原】

    jira7编辑区自定义快捷键 本文主要描述了jira7如何通过添加全局js引用,给文本编辑区自定义快捷键用以快速填充模板内容. jira 3/4/5可参考官方api https://developer ...

  10. 阅读:ECMAScript 6 入门(4)

    参考 ECMAScript 6 入门 ES6新特性概览 ES6 全套教程 ECMAScript6 (原著:阮一峰) JavaScript 教程 重新介绍 JavaScript(JS 教程) 数组的扩展 ...