从0到1搭建前后端分离的脚手架框架之后端(二) 统一异常处理

统一异常处理

全局异常处理封装,统一返回错误格式的异常. 这里通过 @ControllerAdvice 注解来处理异常

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler(value = Throwable.class)
    public RestResponse<Object> handler(ServletRequest request, Throwable throwable, HttpServletResponse response) {
        // 设置状态码为500
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        if (Objects.isNull(throwable)) {
            log.error("没有获取到异常信息");
            return RestResponse.error(GlobalCode.UNKNOWN);
        }
        
        // 业务异常
        if (throwable instanceof BaseException) {
            RestCode code = ((BaseException) throwable).getCode();
            log.warn("自定义异常 异常码 -> {}, 异常信息 -> {}", code.getCode(), code.getText());
            return RestResponse.error(code);
        }

        log.error("未知异常", throwable);
        return RestResponse.error(GlobalCode.UNKNOWN);
    }
}

异常时设置response的状态码为500, 表明服务器错误, 所有业务异常都需要继承BaseException类.

public abstract class BaseException extends RuntimeException {
    private static final long serialVersionUID = 6623312926437427049L;

    protected RestCode code;

    public BaseException() { }


    public BaseException(RestCode code, String message) {
        super(message);
        this.code = code;
    }
}

接下来测试一下全局异常, 新建TestController

@RestController
public class TestController {

    @GetMapping("/test/exception")
    public RestResponse<String> getUtilsException() {
        throw new UtilsException(GlobalCode.UTILS_ERROR, "工具类异常");
        //return RestResponse.success();
    }

}

新建测试类进行测试

@SpringBootTest
@AutoConfigureMockMvc
class TestControllerTest {
    @Autowired
    private MockMvc mockMvc;


    @Test
    public void test_exception_by_controller() {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(RestResponse.error(GlobalCode.UTILS_ERROR));
            System.out.println(json);
            mockMvc.perform(MockMvcRequestBuilders.get("/test/exception"))
                    .andExpect(MockMvcResultMatchers.status().is5xxServerError())
                    .andExpect(MockMvcResultMatchers.content().json(json))
                    .andDo(MockMvcResultHandlers.print())
                    .andReturn();
        } catch (Exception e) {
           e.printStackTrace();
        }
    }

}

测试通过证明全局异常生效,进一步完善结果,返回结果为 {"code":998,"message":"工具类不允许实例化","result":null} result 的
值为null, 这里我们用fastJson替换掉springboot中的jackson

@Configuration
public class FastJsonConfig {
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters(){
        //1. 需要定义一个converter转换消息的对象
        FastJsonHttpMessageConverter fasHttpMessageConverter = new FastJsonHttpMessageConverter();

        //2. 添加fastjson的配置信息,比如:是否需要格式化返回的json的数据
        com.alibaba.fastjson.support.config.FastJsonConfig fastJsonConfig = new com.alibaba.fastjson.support.config.FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);

        //3. 在converter中添加配置信息
        fasHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        return new HttpMessageConverters(fasHttpMessageConverter);
    }
}

统一的异常处理就完成了,之前本来打算fastjson进行封装的,现在就不进行处理了,后期觉得有需要在封装.

项目源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值