springboot项目处理异常流程
创始人
2025-05-31 12:07:39

后端项目分层一般如下:

  • 控制层:controller

  • 业务层:service

  • 数据访问层:dao

下面演示在实际项目中,移除统一处理流程:

这篇文章的处理原则:controller负责异常统一处理,业务层负责把异常抛至控制层

  • dao层:

该层直接与数据库交互,而dao层由service调用,因此该层异常在service中处理即可

  • service层

业务层数据牵扯到业务处理流程,所有很容易出现异常,在方法后统一抛出一个Exception的方式。(对于某些代码明确其异常(或需自定义异常)时,可以使用try...catch来处理)

  • controller层

控制层来接收业务层处理的结果,当业务层出现异常且通过抛出异常的方式,那么异常会交由控制层处理,在控制层中,一旦出现异常,需要在该层处理,不能再往外抛,否则能影响服务器性能。

案例:

模拟一个service----controller流程,来处理异常,如下:

1、service层:

接口层:模拟一个testException方法,并在接口后抛出统一的异常Exception

package com.shuizhu.service;import java.util.Map;/*** @author 睡竹* @date 2023/3/20*/
public interface TestService {Map testException() throws Exception;
}

接口实现层:

package com.shuizhu.service.impl;import com.shuizhu.service.TestService;
import org.springframework.stereotype.Service;import java.util.LinkedHashMap;
import java.util.Map;/*** @author 睡竹* @date 2023/3/20*/
@Service
public class TestExceptionImpl implements TestService {@Overridepublic Map testException() throws Exception{//1/0 会出现异常,当出现异常时,会抛至controller层进行统一处理int i = 1/0;Map map = new LinkedHashMap();map.put("result",i);return map;}
}

2、前后端统一响应的工具类

package com.shuizhu.utils;import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;import java.util.HashMap;
import java.util.Map;/*** 返回数据** @author 睡竹*/
public class R extends HashMap {private static final long serialVersionUID = 1L;private static final Integer METHOD_INDEX = 1;private static final Logger logger= LogManager.getLogger();public R() {put("code", 0);put("msg", "success");}//测试获取的codepublic Integer getCode() {return (Integer) this.get("code");}public static R error() {return error(500, "未知异常,请联系管理员");}public static R error(String msg) {return error(500, msg);}public static R error(int code, String msg) {R r = new R();r.put("code", code);r.put("msg", msg);return r;}public static R errorApi(Exception e) {/** 通过getStackTrace获取controller中的方法名称 */StackTraceElement[] stackTrace = new Throwable().getStackTrace();String method = "";if (stackTrace.length > 0) {/** 获取方法名称 */method = stackTrace[METHOD_INDEX].getMethodName();}/** 把错误日志打印至控制台,按文本形式可以提高系统性能 */logger.error(method + "接口异常->",e);/***  日志输出格式:"方法名称  接口异常->  异常重要的信息"*  前提:接口名称需要与controller方法名称一致*/return error(method + "接口异常->" + e.getMessage());}public static R ok(String msg) {R r = new R();r.put("msg", msg);return r;}public static R ok(Map map) {R r = new R();r.putAll(map);return r;}public static R ok() {return new R();}@Overridepublic R put(String key, Object value) {super.put(key, value);return this;}
}

3、controller层

package com.shuizhu.controller;import com.shuizhu.service.TestService;
import com.shuizhu.utils.R;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.Map;/*** @author 睡竹* @date 2023/3/20*/
@RestController
public class TestController {@ResourceTestService testService;@RequestMapping("/testException")public R testException(){try {Map map = testService.testException();return R.ok(map);} catch (Exception e) {return R.errorApi(e);}}
}

4、测试

接口为:http://127.0.0.1:8080/testException

接口返回了异常中的getMessage()信息,再来看控制台打印日志:

上述日志是通过logger进行日志打印输出的

下面改下代码,直接打印堆栈信息至控制台(这种方式不能出现在生产环境中):

    try {Map map = testService.testException();return R.ok(map);} catch (Exception e) {e.printStackTrace();//直接打印堆栈信息,会影响性能return R.error(e.getMessage());}

可以再控制台中看到明显的区别:

相关内容

热门资讯

玩家攻略科普“天天福建麻将为什... 有 亲,根据资深记者爆料天天福建麻将是可以开挂的,确实有挂(咨询软件无需...
玩家推荐“天天乐清麻将辅助开挂... 您好,天天乐清麻将这款游戏可以开挂的,确实是有挂的,需要了解加微【9752949】很多玩家在这款游戏...
一分钟讲解“微信群里用链接玩金... 微信群里用链接玩金花是一款非常受欢迎的游戏,咨询房/卡添加微信:44858861许多玩家在游戏中会购...
德州ai辅助(好运大菠萝有没有... 德州ai辅助(好运大菠萝有没有挂的)德州之星辅助透视(其实真的有挂)-哔哩哔哩是一款可以让一直输的玩...
德扑数据软件(微扑克)aapo... 德扑数据软件(微扑克)aapoker辅助工具下载(原来真的有挂)-哔哩哔哩1、用户打开应用后不用登录...