技术标签: SpringBoot
参考资料
- springboot继承AbstractErrorController实现全局的异常处理
https://blog.csdn.net/qq_29684305/article/details/82286469- spring boot 原生错误处理ErrorController
https://blog.csdn.net/shenyunsese/article/details/53390116- @ControllerAdvice 拦截异常并统一处理
https://my.oschina.net/langwanghuangshifu/blog/2246890
在springboot项目中当我们访问一个不存在的url时经常会出现以下页面
在postman访问时则是以下情况
image
对于上面的情况究竟是什么原因造成呢,实际上当springboot项目出现异常时,默认会跳转到/error,而/error则是由BasicErrorController进行处理,其代码如下
@Controller
@RequestMapping({
"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {
private final ErrorProperties errorProperties;
public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
this(errorAttributes, errorProperties, Collections.emptyList());
}
public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, errorViewResolvers);
Assert.notNull(errorProperties, "ErrorProperties must not be null");
this.errorProperties = errorProperties;
}
public String getErrorPath() {
return this.errorProperties.getPath();
}
@RequestMapping(
produces = {
"text/html"}
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = this.getStatus(request);
Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
return modelAndView == null ? new ModelAndView("error", model) : modelAndView;
}
@RequestMapping
@ResponseBody
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = this.getStatus(request);
return new ResponseEntity(body, status);
}
protected boolean isIncludeStackTrace(HttpServletRequest request, MediaType produces) {
IncludeStacktrace include = this.getErrorProperties().getIncludeStacktrace();
if (include == IncludeStacktrace.ALWAYS) {
return true;
} else {
return include == IncludeStacktrace.ON_TRACE_PARAM ? this.getTraceParameter(request) : false;
}
}
protected ErrorProperties getErrorProperties() {
return this.errorProperties;
}
}
下面是自己写的一个ErrorController
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.xuecheng.framework.model.response.ErrorCode;
import com.xuecheng.framework.model.response.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* web错误 全局处理
* @author jiangwf
*
*/
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
@Controller
public class InterfaceErrorController implements ErrorController {
private static final String ERROR_PATH="/error";
private ErrorAttributes errorAttributes;
@Override
public String getErrorPath() {
return ERROR_PATH;
}
@Autowired
public InterfaceErrorController(ErrorAttributes errorAttributes) {
this.errorAttributes=errorAttributes;
}
/**
* web页面错误处理
*/
@RequestMapping(value=ERROR_PATH,produces="text/html")
@ResponseBody
public String errorPageHandler(HttpServletRequest request,HttpServletResponse response) {
ServletWebRequest requestAttributes = new ServletWebRequest(request);
Map<String, Object> attr = this.errorAttributes.getErrorAttributes(requestAttributes, false);
JSONObject jsonObject = new JSONObject();
ErrorCode errorCode = new ErrorCode(false, (int) attr.get("status"), (String) attr.get("message"));
return JSONObject.toJSONString(errorCode);
}
/**
* 除web页面外的错误处理,比如json/xml等
*/
@RequestMapping(value=ERROR_PATH)
@ResponseBody
public ResultCode errorApiHander(HttpServletRequest request) {
ServletWebRequest requestAttributes = new ServletWebRequest(request);
Map<String, Object> attr=this.errorAttributes.getErrorAttributes(requestAttributes, false);
return new ErrorCode(false, (int)attr.get("status"), (String) attr.get("message"));
}
}
image
image
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
@ToString
@Data
@AllArgsConstructor
public class ErrorCode implements ResultCode{
private boolean success;
private int code;
private String message;
@Override
public boolean success() {
return false;
}
@Override
public int code() {
return 0;
}
@Override
public String message() {
return null;
}
}
public interface ResultCode {
//操作是否成功,true为成功,false操作失败
boolean success();
//操作代码
int code();
//提示信息
String message();
}
问题:
解决方法:
异常处理流程
系统对异常的处理使用统一的异常处理流程:
异常抛出及处理流程
image
下面就开始我们的异常处理编程
一、可预知异常
import com.xuecheng.framework.model.response.ResultCode;
import jdk.nashorn.internal.objects.annotations.Getter;
/**
* @Author: jiangweifan
* @Date: 2019/3/4 20:06
* @Description:
*/
public class CustomException extends RuntimeException {
private ResultCode resultCode;
public CustomException(ResultCode resultCode) {
super("错误代码:" + resultCode.code()+" 错误信息:" + resultCode.message());
this.resultCode = resultCode;
}
public ResultCode getResultCode() {
return resultCode;
}
}
import com.xuecheng.framework.model.response.ResultCode;
/**
* @Author: jiangweifan
* @Date: 2019/3/4 20:09
* @Description:
*/
public class ExceptionCast {
public static void cast(ResultCode resultCode, boolean condition) {
if (condition) {
throw new CustomException(resultCode);
}
}
}
import com.google.common.collect.ImmutableMap;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.framework.model.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.net.SocketTimeoutException;
/**
* @Author: jiangweifan
* @Date: 2019/3/4 20:13
* @Description:
*/
@ControllerAdvice
@Slf4j
public class ExceptionCatch {
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult customException(CustomException e) {
log.error("catch exception : {} \r\nexception", e.getMessage(), e);
ResponseResult responseResult = new ResponseResult(e.getResultCode());
return responseResult;
}
}
4.1 定义响应数据格式
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @Author: mrt.
* @Description:
* @Date:Created in 2018/1/24 18:33.
* @Modified By:
*/
@Data
@ToString
@NoArgsConstructor
public class ResponseResult implements Response {
//操作是否成功
boolean success = SUCCESS;
//操作代码
int code = SUCCESS_CODE;
//提示信息
String message;
public ResponseResult(ResultCode resultCode){
this.success = resultCode.success();
this.code = resultCode.code();
this.message = resultCode.message();
}
public static ResponseResult SUCCESS(){
return new ResponseResult(CommonCode.SUCCESS);
}
public static ResponseResult FAIL(){
return new ResponseResult(CommonCode.FAIL);
}
}
其中Response代码如下
public interface Response {
public static final boolean SUCCESS = true;
public static final int SUCCESS_CODE = 10000;
}
4.2 定义错误代码(ResultCode上文已给出)
import com.xuecheng.framework.model.response.ResultCode;
import lombok.ToString;
/**
* Created by mrt on 2018/3/5.
*/
@ToString
public enum CmsCode implements ResultCode {
CMS_ADDPAGE_EXISTSNAME(false,24001,"页面名称已存在!"),
CMS_GENERATEHTML_DATAURLISNULL(false,24002,"从页面信息中找不到获取数据的url!"),
CMS_GENERATEHTML_DATAISNULL(false,24003,"根据页面的数据url获取不到数据!"),
CMS_GENERATEHTML_TEMPLATEISNULL(false,24004,"页面模板为空!"),
CMS_GENERATEHTML_HTMLISNULL(false,24005,"生成的静态html为空!"),
CMS_GENERATEHTML_SAVEHTMLERROR(false,24005,"保存静态html出错!"),
CMS_COURSE_PERVIEWISNULL(false,24007,"预览页面为空!"),
CMS_TEMPLATEFILE_ERROR(false,24008,"模板文件需要.ftl后缀!"),
CMS_TEMPLATEFILE_NULL(false,24009,"模板文件为空!"),
CMS_TEMPLATEFILE_EXCEPTION(false,24010,"解析模板文件异常!"),
CMS_TEMPLATEFILE_FAIL(false,24011,"模板文件存储失败!"),
CMS_TEMPLATEFILE_DELETE_ERROR(false,24012,"模板文件删除失败!"),
CMS_Config_NOTEXISTS(false,24013,"不存在该数据模型!"),
CMS_PAGE_NULL(false,24014,"不存在该页面数据!"),
CMS_GENERATEHTML_CONTENT_FAIL(false,24014,"获取页面模板失败!");
//操作代码
boolean success;
//操作代码
int code;
//提示信息
String message;
private CmsCode(boolean success, int code, String message){
this.success = success;
this.code = code;
this.message = message;
}
@Override
public boolean success() {
return success;
}
@Override
public int code() {
return code;
}
@Override
public String message() {
return message;
}
}
@GetMapping("/list/{page}/{size}")
public QueryResponseResult findList(@PathVariable("page") int page, @PathVariable("size")int size, QueryPageRequest queryPageRequest) {
ExceptionCast.cast(CmsCode.CMS_COURSE_PERVIEWISNULL, queryPageRequest == null);
return pageService.findList(page,size,queryPageRequest);
}
最终方法得到以下结果
image
二、不可预知异常处理
import com.google.common.collect.ImmutableMap;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.framework.model.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.net.SocketTimeoutException;
/**
* @Author: jiangweifan
* @Date: 2019/3/4 20:13
* @Description:
*/
@ControllerAdvice
@Slf4j
public class ExceptionCatch {
//使用EXCEPTIOS存放异常类型 和错误代码的映射,ImmutableMap的特点是已创建就不可变,并且线程安全
private static ImmutableMap<Class<? extends Throwable>, ResultCode> EXCEPTIOS;
//是由builder来构建一个异常类型和错误代码的映射
private static ImmutableMap.Builder<Class<? extends Throwable>, ResultCode> builder =
ImmutableMap.builder();
static {
//初始化基础类型异常与错误代码的映射
builder.put(NullPointerException.class, CommonCode.NULL);
builder.put(SocketTimeoutException.class, CommonCode.NULL);
}
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult customException(CustomException e) {
log.error("catch exception : {} \r\nexception", e.getMessage(), e);
ResponseResult responseResult = new ResponseResult(e.getResultCode());
return responseResult;
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception e) {
log.error("catch exception : {} \r\nexception", e.getMessage(), e);
if (EXCEPTIOS == null) {
EXCEPTIOS = builder.build();
}
final ResultCode resultCode = EXCEPTIOS.get(e.getClass());
if (resultCode != null) {
return new ResponseResult(resultCode);
} else {
return new ResponseResult(CommonCode.SERVER_ERROR);
}
}
}
import lombok.ToString;
/**
* @Author: mrt.
* @Description:
* @Date:Created in 2018/1/24 18:33.
* @Modified By:
*/
@ToString
public enum CommonCode implements ResultCode{
SUCCESS(true,10000,"操作成功!"),
FAIL(false,19999,"操作失败!"),
UNAUTHENTICATED(false,10001,"此操作需要登陆系统!"),
UNAUTHORISE(false,10002,"权限不足,无权操作!"),
NULL(false,10003,"空值异常!"),
TIMEOUT(false, 10004, "服务器连接超时!"),
SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!");
// private static ImmutableMap<Integer, CommonCode> codes ;
//操作是否成功
boolean success;
//操作代码
int code;
//提示信息
String message;
private CommonCode(boolean success,int code, String message){
this.success = success;
this.code = code;
this.message = message;
}
@Override
public boolean success() {
return success;
}
@Override
public int code() {
return code;
}
@Override
public String message() {
return message;
}
}
@GetMapping("/list/{page}/{size}")
public QueryResponseResult findList(@PathVariable("page") int page, @PathVariable("size")int size, QueryPageRequest queryPageRequest) {
int a= 1/0;
return pageService.findList(page,size,queryPageRequest);
}
浏览器访问结果如下:
image
至此我们完成了对全局异常的处理
欢迎关注公众号,后续文章更新通知,一起讨论技术问题 。
用于产生从某个数到另外一个数之间的所有整数例一:seq 1 10结果是1 2 3 4 5 6 7 8 9 10例二:#!/bin/bashfor i in seq 1 10;doecho $i;done或者用for i in $(seq 1 10)也可以seq-f, --format=FORMAT use printf style floating-point...
redis集群搭建请自行百度已有redis 集群如下图:先连接某个实例,设置key,执行如下命令,key中带了hash tag[[email protected] src]# ./redis-cli -c -p 6388127.0.0.1:6388> set {a}.foo 9编写lua脚本:local s = redis.
下载安装包:https://dev.mysql.com/downloads/mysql/下载好后,解压,我这里把mysql-5.7.23-el7-x86_64.tar 改名成了mysql5.7.23.tar.gz解压后有两个解压包,只管mysql-5.7.23-el7-x86_64.tar.gz这个包,另一个是测试包不用管[[email protected] /]# ls /bin b...
CentOS 7.5 快速搭建 ELK 日志分析平台环境:CentOS 7.5 Java jdk :1.8.0_212 软件版本 :7.1.1注:ELK 平台的搭建各软件一定要使用相同版本1、安装 elasticsearch首先下载软件包,我是直接用 wget 命令从官网下载(官网地址:https://www.elastic.co/cn/),这里默认下载的是最新版的 7.1...
关键词: 几个重要的概念、网际协议IP、IP的格式、ARP、ICMP、IGMP、分类IP地址、无分类编址CIDR、一、问题描述电路交换与虚电路的相同之处和不同答:虚电路表示这只是一条逻辑上的连接,分组都沿着这条逻辑连接按照存储转发方式传送,而并不是真正建立了一条物理连接。请注意,电路交换的电话通信是先建立了一条真正的连接。通常与网际层的IP协议配套使用的协议有那三个?答:地址解析协议ARP(Address Resolution Protocol)、网际控制报文协议ICMP(Interne
顾名思义,就是写一段代码,显示指定文件的结构图,包括其所有子目录,子目录的子目录和非目录文件。1、以缩进的形式打印出指定文件的目录结构。这个缩进是以两个空格表示的。即文件每延后一级,打印的时候就在前面多加两个空格。采用递归方法设计的思考要点(详情请参见递归(1)),具体步骤为:(1)在main方法里,a,给定文件(file=File(String pathName));b,列出目录并打印。(2
推荐一个程序员开发、学习的好网站,www.it123.top欢迎大家转发收藏。一、Android:(红色方法为主调函数,输入原始经纬度,输出纠偏后的经纬度)final static double pi = 3.14159265358979324;final static double a = 6378245.0;final static double ee = 0.0066934216229659...
场景一 解决了一次性渲染大量数据问题业务场景是后台一次返回10万多条数据需要在下拉框中展示,直接渲染会导致页面卡顿且需要很长时间等待,用户体验极差,所以我把这个改造了一下,直接上代码, 里面注释写的很清楚了就不解释了.<template> <div class="content"> <el-select v-model="choose" size="small" v-el-select-loadmore:rangeNumber="loadMore
首先你得知道单位根是个什么东西。。。这篇文章假设你已经知道单位根与原根的性质。这里有一个关于单位根的很神奇的真值函数式子:[n∣k]=1n∑i=0n−1wnik[n\mid k]=\frac{1}{n}\sum\limits_{i=0}^{n-1}w_{n}^{ik}[n∣k]=n1i=0∑n−1wnik分情况讨论,证明过程如下:(1) n∣k,wnik=wnik mod n=wn0=1⇒1n∑i=0n−1wnik=1(2) n∤k,∑i=0n−1wnik=wn0(1−wn
一、分布式事务的概念1,什么是事务事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。2,本地事务数据库事务的四大特性 ACID:A(Atomic): 原子性 ,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失败的情况。 C(Consistency): 一致性 ,在事务执行前后,数据库的一致性约束没有被破坏。比如:张三向李四转100元,转账前和转账后的数据是正确状态这叫一致性,如果出现张三转出100元,李四账户没有增加100
文章目录Jaccard相似度介绍Jaccard相似度计算推荐结果代码及实现基本介绍Jaccard相似度计算代码协同过滤推荐代码实现Jaccard相似度介绍两个集合的交集元素个数在并集中所占的比例, 非常适用于布尔向量表示分子是两个布尔向量做点积计算, 得到的就是交集元素的个数分母是两个布尔向量做或运算, 再求元素和杰卡德相似度适用于隐式反馈数据(0,1布尔值),主要应用于是否收藏,是否点击,是否加购物车。简单地来说就是交集/并集J(A,B)=|A∩B|/|A∪B|Jaccard相似度计算
1.Activity的概念介绍 Activity是Android组件中最基本也是最常用的一种组件,在一个Android应用中,一个Activity通常就是一个单独的屏幕。每一个Activity都被实现为一个独立的类,并且继承于Activity这个基类。activity类处于android.app包中,继承体系如下:1.java.lang.Object2.an