Spring Boot统一功能处理(Spring拦截器)

为什么需要Spring拦截器

原生的Spring AOP实现统一拦截有两大难点,1.定义拦截的规则难写;2.在切面类中拿到HttpSession比较难。为此Spring官方提供了拦截器帮我们解决了上面痛点。

实现登入信息验证拦截器

  1. 实现HanderInterceptor接口
  2. 重写preHeadler方法,在方法中编写自己的业务代码
java 复制代码
//验证登入信息的拦截器
public class LoginInterceptor implements HandlerInterceptor {
    //此方法返回一个boolean,如果为true表示验证成功,继续执行后续流程
    //如果是false表示验证失败,后面流程不能执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession(false);
        if(session != null && session.getAttribute("userinfo") != null) {
            return true;
        }
        //身份验证失败,重定向到登入页面
        response.sendRedirect("/login.html");
        return false;
    }
}
将拦截器添加到配置文件中,并且设置拦截规则
java 复制代码
@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")  //**表示拦截所有请求
                .excludePathPatterns("/user/login") //不拦截的url地址
                .excludePathPatterns("/user/reg")
                .excludePathPatterns("/login.html");//登入页面不拦截,否则会报重定向多次的错误
    }
}
拦截器实现原理


Spring中的拦截器是通过动态代理和环绕通知的思想实现的

给当前项目配置统一的前缀

之所以要配置统一的前缀是因为在一个服务器中有多个程序,却只有一个域名,就需要在每个程序添加url前缀才知道访问哪个程序

  1. 在系统的配置文件中配置
java 复制代码
@Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("/zhangsan",  c ->true);//设置true启动前缀
    }
  1. 在application.properies配置
java 复制代码
server.servlet.context-path=/lisi

统一异常处理

创建一个类,并在类上标识 @ControllerAdvice
java 复制代码
@ControllerAdvice
@ResponseBody
public class MyExhandler {
}
添加方法@ExeceptionHandler来订阅异常
java 复制代码
/*
    拦截所有空指针异常
     */
    @ExceptionHandler(NullPointerException.class)
    public HashMap<String, Object> nullException(NullPointerException e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", -1);
        result.put("msg", "空指针异常:" + e.getMessage());
        result.put("data", null);
        return result;
    }
    @ExceptionHandler(Exception.class)
    public HashMap<String, Object> exception(Exception e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", -1);
        result.put("msg", "异常:" + e.getMessage());
        result.put("data", null);
        return result;
    }

统一数据格式返回

  1. 创建一个类,并添加@ControllerAdvice
  2. 实现ResponseBodyAdvice接口,并重写supports和beforeBodyWrite
java 复制代码
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;
    /*
    返回true则执行beforeBodyWrite方法,反之不执行
     */
    @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) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", 200);
        result.put("msg", "");
        result.put("data", body);
        //body是String时转换时会报错,需要特殊处理
        if(body instanceof String) {
            try {
                return objectMapper.writeValueAsString(result);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}
相关推荐
武藤一雄7 小时前
C# 关于多线程如何实现需要注意的问题(持续更新)
windows·后端·microsoft·c#·.net·.netcore·死锁
華勳全栈8 小时前
两天开发完成智能体平台
java·spring·go
程序新视界8 小时前
为什么不建议基于Multi-Agent来构建Agent工程?
人工智能·后端·agent
alonewolf_998 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
Victor3568 小时前
Hibernate(29)什么是Hibernate的连接池?
后端
Victor3568 小时前
Hibernate(30)Hibernate的Named Query是什么?
后端
源代码•宸8 小时前
GoLang八股(Go语言基础)
开发语言·后端·golang·map·defer·recover·panic
czlczl200209258 小时前
OAuth 2.0 解析:后端开发者视角的原理与流程讲解
java·spring boot·后端
颜淡慕潇9 小时前
Spring Boot 3.3.x、3.4.x、3.5.x 深度对比与演进分析
java·后端·架构
布列瑟农的星空9 小时前
WebAssembly入门(一)——Emscripten
前端·后端