一、异常处理的原则

1、调用方法的时候返回布尔值来代替返回null,这样可以 NullPointerException。由于空指针是java异常里最恶心的异常。

2、 catch块里别不写代码。空catch块是异常处理里的错误事件,因为它只是捕获了异常,却没有任何处理或者提示。通常你起码要打印出异常信息,当然你最好根据需求对异常信息进行处理。

3、能抛受控异常(checked Exception)就尽量不抛受非控异常(unchecked Exception[Error或者RuntimeException的异常])。通过去掉重复的异常处理代码,可以提高代码的可读性。

4、 绝对不要让你的数据库相关异常显示到客户端。由于绝大多数数据库和SQLException异常都是受控异常,在Java中,你应该在DAO层把异常信息处理,然后返回处理过的能让用户看懂并根据异常提示信息改正操作的异常信息。

5、 在Java中,一定要在数据库连接,数据库查询,流处理后,在finally块中调用close()方法。

二、示例说明

本示例以“前后端分离模式”进行演示,调试用的异常信息通过日志的形式打印出来,代码并不完整,仅从异常处理进行部分代码示例。

1、创建异常类

 @Getter //通过lombok插件实现省写setter或者getter方法
public class SellException extends RuntimeException { private Integer code;
private String message; public SellException(ResultEnum resultEnum) {
super(resultEnum.getMessage());
this.code = resultEnum.getCode();
} public SellException(Integer code,String message) {
this.code = code;
this.message = message;
}
}

2、使用Handler类捕获异常,统一格式返回给前端

 @ControllerAdvice
public class SellExceptionHandler { @ExceptionHandler(value = SellException.class)
@ResponseBody
public ResultVO handlerSellerException(SellException e){
return ResultVOUtil.error(e.getCode(),e.getMessage());
} }

  统一格式类:

 public class ResultVOUtil {

     public static ResultVO success(Object object) {
ResultVO resultVO = new ResultVO();
resultVO.setData(object);
resultVO.setCode(0);
resultVO.setMsg("成功");
return resultVO;
} public static ResultVO success() {
return success(null);
} public static ResultVO error(Integer code,String msg) {
ResultVO resultVO = new ResultVO();
resultVO.setCode(code);
resultVO.setMsg(msg);
return resultVO;
} }
 @Data
public class ResultVO<T> implements Serializable{ private static final long serialVersionUID = 8960474786737581150L; /**
* 错误码
*/
private Integer code;
/**
*提示信息
*/
private String msg;
/**
* 具体内容
*/
private T data; }

3、异常的信息通过枚举统一定义,方便定义管理

 @Getter
public enum ResultEnum { SUCCESS(0,"成功"), PARAM_ERROR(1,"参数不正确"), PRODUCT_NOT_EXIST(10,"商品不存在"), PRODUCT_STOCK_ERROR(11,"商品库存不正确"), ORDER_NOT_EXIST(12,"订单不存在"), ORDERDETAIL_NOT_EXIST(13,"订单详情不存在"), ORDER_STATUS_ERROR(14,"订单状态不正确"), ORDER_UPDATE_FAIL(15,"订单更新失败"), ORDER_DETAIL_EMPTY(16,"订单详情为空"), CART_EMPTY(18,"购物车为空"), ORDER_OWNER_ERROR(19,"该订单不属于当前用户"),
; private Integer code;
private String message; ResultEnum(Integer code, String message) {
this.code = code;
this.message = message;
} }

4、使用异常类

① controller层处理页面传来参数的校验,如参数不正确,抛出自定义异常,由handler捕获返回给页面。

 @RestController
@RequestMapping("/buyer/order")
@Slf4j
public class BuyerOrderController { @Autowired
private OrderService orderService; @Autowired
private BuyerService buyerService; //创建订单
@PostMapping("/create")
public ResultVO<Map<String,String>> create(@Valid OrderForm orderForm,
BindingResult bindingResult){
if (bindingResult.hasErrors()){
log.error("[创建订单] 参数不正确,orderForm={}",orderForm);
throw new SellException(ResultEnum.PARAM_ERROR.getCode(),
bindingResult.getFieldError().getDefaultMessage());
}
OrderDTO orderDTO = OrderForm2OrderDTOConverter.convert(orderForm);
if (CollectionUtils.isEmpty(orderDTO.getOrderDetailList())){
log.error("[创建订单] 购物不能为空");
throw new SellException(ResultEnum.CART_EMPTY);
} OrderDTO createResult = orderService.create(orderDTO);
Map<String,String> map = new HashMap<>();
map.put("orderId",createResult.getOrderId()); return ResultVOUtil.success(map); }
//订单列表
@GetMapping("/list")
public ResultVO<List<OrderDTO>> list(@RequestParam("openid") String openid,
@RequestParam(value = "page",defaultValue = "0") Integer page,
@RequestParam(value = "size",defaultValue = "10") Integer size){
if (StringUtils.isEmpty(openid)){
log.error("[查询订单列表] openid为空");
throw new SellException(ResultEnum.PARAM_ERROR);
}
PageRequest request = new PageRequest(page, size);
Page<OrderDTO> orderDTOPage = orderService.findList(openid, request); return ResultVOUtil.success(orderDTOPage.getContent());
} //订单详情
@GetMapping("/detail")
public ResultVO<OrderDTO> detail(@RequestParam("openid") String openid,
@RequestParam("orderId") String orderId){ OrderDTO orderDTO = buyerService.findOrderOne(openid, orderId);
return ResultVOUtil.success(orderDTO);
} //取消订单
@PostMapping("/cancel")
public ResultVO<OrderDTO> cancel(@RequestParam("openid") String openid,
@RequestParam("orderId") String orderId) { buyerService.cancelOrderOne(openid, orderId);
return ResultVOUtil.success();
}
}

② service处理返回的结果的异常,抛出自定义异常,由handler捕获返回给页面。

 @Service
@Slf4j
public class BuyerServiceImpl implements BuyerService { @Autowired
private OrderService orderService; @Override
public OrderDTO findOrderOne(String openid, String orderId) {
return checkOrderOwner(openid, orderId);
} @Override
public OrderDTO cancelOrderOne(String openid, String orderId) {
OrderDTO orderDTO = checkOrderOwner(openid, orderId);
if (orderDTO == null){
log.error("[取消订单] 查不到该订单,orderDTO={}",orderId);
throw new SellException(ResultEnum.ORDER_NOT_EXIST);
}
return orderService.cancel(orderDTO);
} private OrderDTO checkOrderOwner(String openid, String orderId) {
OrderDTO orderDTO = orderService.findOne(orderId);
if (orderDTO == null){
return null;
}
if (!orderDTO.getBuyerOpenid().equalsIgnoreCase(openid)){
log.error("[查询订单] 订单的openid不一致,openid={},orderDTO={}",openid,orderDTO);
throw new SellException(ResultEnum.ORDER_OWNER_ERROR);
}
return orderDTO;
} }

Spring Boot统一异常处理方案示例的更多相关文章

  1. Spring Boot统一异常处理实践

    摘要: SpringBoot异常处理. 原文:Spring MVC/Boot 统一异常处理最佳实践 作者:赵俊 前言 在 Web 开发中, 我们经常会需要处理各种异常, 这是一件棘手的事情, 对于很多 ...

  2. spring boot 统一异常处理

    需求源自于任何一个业务的编写总会有各种各样的条件判断,需要时时手动抛出异常,又希望让接口返回友好的错误信息. spring boot提供的帮助是自动将异常重定向到路由为/error的控制器 但是我们又 ...

  3. Spring Boot☞ 统一异常处理

    效果区:  代码区: package com.wls.integrateplugs.exception.dto; public class ErrorInfo<T> { public st ...

  4. js构建ui的统一异常处理方案(四)

    上一篇我们介绍了统一异常处理方案的设计方案,这一篇我们将直接做一个小例子,验证我们的设计方案. 例子是一个todo的列表界面(页面代码参考于https://github.com/zongxiao/Dj ...

  5. js构建ui的统一异常处理方案(三)

    笔者之前分析了如何实现js的责任链异常处理的方法,通过promise这个异步模型,我们能够对同步方法和异步方法的两种情况,均可以实现责任链模式.有了这些武器,我们就可以开始设计ui的统一异常处理方案了 ...

  6. Spring MVC 统一异常处理

    Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...

  7. 编程小白入门分享三:Spring AOP统一异常处理

    Spring AOP统一异常处理 简介 在Controller层,Service层,可能会有很多的try catch代码块.这将会严重影响代码的可读性."美观性".怎样才可以把更多 ...

  8. Spring Boot全局异常处理

    本文为大家分享了Spring Boot全局异常处理,供大家参考,具体内容如下 1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dep ...

  9. Spring Boot Ftp Client 客户端示例支持断点续传

    本章介绍 Spring Boot 整合 Ftpclient 的示例,支持断点续传 本项目源码下载 1 新建 Spring Boot Maven 示例工程项目 注意:是用来 IDEA 开发工具 File ...

随机推荐

  1. poj1269---直线位置关系

    题目大意:给你8个点,也就是两条直线,让你判断他们的位置关系 代码如下: #include <iostream> #include<cstdio> #include<cm ...

  2. webpack快速入门——配置文件:入口和出口,多入口、多出口配置

    1.在根目录新建一个webpack.config.js文件,然后开始配置: const path = require('path'); module.exports={ //入口文件的配置项 entr ...

  3. ES6字符串相关扩展

    变量的解构赋值 // 数组的解构赋值 let [a,b,c] = [1,2,3]; //1,2,3 let [a,b,c] = [,123,]; //undefined 123 undefined l ...

  4. 1. Python中如何使用其他语言?(python的胶水作用,python又叫胶水语言)

    1. python中如何插入C语言运行? (1)编写C语言代码: #include<stdio.h> void CFun() { printf("---------我是c语言:- ...

  5. day 50 AJAX 初入门

    前情提要: jq 学不好,ajax   难用好, 食用先请先确保最起码的jq 能会用 https://www.cnblogs.com/baili-luoyun/p/10473518.html  jq ...

  6. git命令上传项目到码云总结

    码云上传项目git命令总结: git clone https://git.oschina.net/xh-lxx/xh-lxx.oschina.io.git 进入到克隆下来的文件夹,然后操作git命令 ...

  7. javascript数据结构与算法--二叉树遍历(后序)

    javascript数据结构与算法--二叉树遍历(后序) 后序遍历先访问叶子节点,从左子树到右子树,再到根节点. /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * * * */ ...

  8. 维特比算法(Viterbi)-实例讲解(暴力破解+代码实现)

    1.简介 维特比算法是一个通用的求序列最短路径的动态规划算法,也可以用于很多其他问题,比如:文本挖掘.分词原理.既然是动态规划算法,那么就需要找到合适的局部状态,以及局部状态的递推公式.在HMM中,维 ...

  9. grep常用用法

    grep常用用法 [root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename 选项与参数: -a :将 binary 文件以 text 文件 ...

  10. Android 开发服务类 02_NewsListServlet

    Servlet implementation class NewsListServlet package com.wangjialin.server.xml; import java.io.IOExc ...