【JavaEE】Spring(7):统一功能处理


一、拦截器

拦截器的使用步骤:

  1. 定义拦截器
  2. 注册配置拦截器

1. 定义拦截器

java 复制代码
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    log.info("目标方法执行前执行");
    return true;
}

preHandle是HandlerInterceptor接口提供的方法,该方法用来判断目标方法执行前是否要拦截,返回true就不拦截,即目标方法可以执行,返回false就拦截,即目标方法禁止执行

2. 配置注册拦截器

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login")
                .excludePathPatterns("/css/**")
                .excludePathPatterns("/js/**")
                .excludePathPatterns("/pic/**")
                .excludePathPatterns("/**/*.html")
                .excludePathPatterns("/test/**")
        ;
    }
}

二、统一数据返回格式

在进行项目开发时,我们通常将后端返回给前端的数据做一个包装,使得让返回的数据格式都相同

java 复制代码
@Data
public class Result<T> {
    private ResultCodeEnum code;
    private String errMsg;
    private T data; //包装前,接口返回的数据
}

那么如何将数据进行包装:

java 复制代码
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest
                                          request, ServerHttpResponse response) {
        return Result.success(body);
    }
}

当一个Controller方法返回一个值时,该值会作为参数传递给supports方法;在supports方法中,通过我们自己编写的逻辑来判断是否需要对返回值进行处理,如果返回true,则将返回值传递给beforeBodyWrite方法,在beforeBodyWrite方法中对返回值进行处理,将处理后的格式作为响应发送给客户端

返回false就不执行beforeBodyWrite方法,即不对返回值进行处理,直接作为响应发送给客户端

三、统一异常处理

统一异常处理通过@ControllerAdvice + @ExceptionHandler 来实现

java 复制代码
@ControllerAdvice
@ResponseBody
public class ErrorAdvice {

    @ExceptionHandler
    public Object handler(Exception e) {
        return Result.fail(e.getMessage());
    }

}

上述代码表示,如果代码中出现Exception异常(包括Exception子类),就返回一个Result对象,Result.fail(e.getMessage());方法实现如下:

java 复制代码
public static <T> Result<T> fail(String errMsg){
    Result result = new Result<>();
    result.setErrMsg(errMsg);
    result.setCode(ResultCodeEnum.FAIL);
    result.setData(null);
    return result;
}

将Result对象转换为Json格式后返回给前端

如果想要针对不同的异常返回不同的结果,可以这么写:

java 复制代码
@RestControllerAdvice //相当于@ResponseBody + @ControllerAdvice
public class ErrorAdvice {

    @ExceptionHandler(ArithmeticException.class) //针对算数异常
    public Result handler1(Exception e){
        log.error("发生ArithmeticException, e:", e);
        return Result.fail("发生算术异常: "+e.getMessage());
    }

    @ExceptionHandler(NullPointerException.class) //针对空指针异常
    public Result handler2(Exception e){
        log.error("发生NullPointerException, e:", e);
        return Result.fail("发生空指针异常: "+e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result handler3(Exception e){
        log.error("发生异常, e:", e);
        return Result.fail("发生异常: "+ e.getMessage());
    }
}

接下来模拟几个异常:

java 复制代码
@RequestMapping("/test")
@RestController
public class TestController {

    @RequestMapping("/t1")
    public String t1(){
        int[] arr = {1,2,3};
        System.out.println(arr[5]);
        return "t1";
    }

    @RequestMapping("/t2")
    public Integer t2(){
        int a = 10/0;
        return 10;
    }

    @RequestMapping("/t3")
    public Boolean t3(){
        String a = null;
        System.out.println(a.length());
        return true;
    }

}

http://127.0.0.1:8080/test/t1:

http://127.0.0.1:8080/test/t2:

http://127.0.0.1:8080/test/t3:


🙉本篇文章到此结束

相关推荐
wuminyu5 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
txxzjmzlh5 小时前
SpringBoot 配置⽂件
java·spring boot·spring
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
骑着蜗牛撵大象3276 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕6 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南7 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
香蕉大香蕉(06敬畏市场)8 小时前
MySQL 单点详解(07)
java·数据库·mysql·ai·博客·八股
nice_lcj5208 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
骑着蜗牛撵大象3279 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp
tryxr9 小时前
JVM 垃圾回收机制
java·jvm·gc·垃圾回收