SpringBoot统一功能处理

简介: SpringBoot统一功能处理

本次博客完成有关Aop的三个实战环节,如下三个:

一:用户登录权限验证

1.1:原生Spring Aop实现拦截的难点

1.2:Spring 拦截器

1.2.1:自定义拦截器

public class LoginInterceptor implements HandlerInterceptor {
    /*
      此方法返回一个boolean类型的值
      如果为true,代表验证成功,执行后续功能
      如果为false,代表验证失败,后面的流程就不能执行了。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //用户登录业务判断
        // 当session不存在时候,不需要创建session的绘画信息
        HttpSession session = request.getSession(false);
        if(session!=null&&session.getAttribute("userinfo")!=null){
            //说明用户已经登录
            return true;
        }
        //跳转到登录页面or返回401/403无权限的状态码
        response.setStatus(403);
        return false;
    }
}

1.2.2:将自定义拦截器加入到系统配置中

@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("/**/*.html")
                .excludePathPatterns("/**/*.css")
                .excludePathPatterns("/**/*.js");
    }
}

1.2.3:测试类

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getuser")
    public String getUser(){
        System.out.println("执行了get User");
        return "getUser";
    }
    @RequestMapping("/login")
    public String login(){
        System.out.println("执行了 login");
        return "login";
    }
}

运行结果:

1.2.4:拦截器的实现原理

实现原理:

当用户调用后端程序时,先进行预处理,即利用拦截器拦截

判断有没有在包含的路径下:

如果有,则进入Handler......这个接口,执行里面的流程,1):当符合预处理的规则,走控制器层-->服务器层-->数据持久层(数据持久层再 调用底层的数据库).2):当不符合出路的规则,返回无权限访问或者相应的前端页面。

如果没有,走当符合预处理规则的这一条路径。


 

二:统一异常处理

2.1:统一异常处理步骤

2.1.1:创建一个类,在类上添加注解@ControllerAdvice(增强对Controller的通知)+@ResponseBody(告诉前端返回的是一个数据,并非是静态页面html)

2.1.2:在方法上添加@ExceptionHandler(异常管理器),对异常做出处理。

2.2:案例

@ControllerAdvice
//当前所有的方法返回的是一个数据,而不是一个静态页面
@ResponseBody
public class MyExHandler {
    //拦截所有的空指针异常,并返回所有的信息
    @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(ArithmeticException.class)
    public HashMap<String,Object> mathException(ArithmeticException e){
        HashMap<String,Object> result=new HashMap<>();
        result.put("code",-1);
        result.put("state",0);
        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("state",0);
        result.put("msg","异常"+e.getMessage());
        result.put("data",null);
        return result;
    }
}

在第一步的时候,即用户登录权限验证,我们并没有对注册和登录做出拦截,因此,为了方便期间,我们在这两个方法里面添加异常,用来验证能不能统一处理异常。

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getuser")
    public String getUser(){
        System.out.println("执行了get User");
        return "getUser";
    }
    @RequestMapping("/login")
    public String login(){
        Object obj=null;
        obj.hashCode();
        System.out.println("执行了 login");
        return "login";
    }
    @RequestMapping("/reg")
    public String reg(){
        int num=10/0;
        System.out.println("执行了reg");
        return "reg!";
    }
}

2.3:运行结果:


三:统一数据返回格式

3.1:统一数据返回格式的步骤

3.1.1:创建一个类,添加注解@ControllerAdvice

3.1.2:让创建的类实现 ResponseBodyAdvice 接口

3.1.3:重写boforeBodyWritesupports方法

3.2:统一数据返回格式的案例

以1-9返回任意的数据,以json的格式返回给前端页面。

3.2.1:Controller层

@RequestMapping("/getnum")
    public Integer getNumber(){
        return new Random().nextInt(10);
    }

3.2.2:创建的类

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    /*
      此方法返回true,则执行底下的beforeBodyWrite方法
       如若返回false,则不执行底下的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> hashMap=new HashMap<>();
        hashMap.put("code",200);
        hashMap.put("data",body);
        hashMap.put("msg","");
        return hashMap;
    }
}

3.3.3:运行结果

3.3:总结

总结:

  1:创建一个类,让这个类实现ResponseBodyAdvice这个接口,并且在类的上面添加@ContrrollerAdvice这个注解 ,让其实现控制层进行加强

  2:对接口里面的两个方法(supports,beforeBodyWrite)进行重写,要让后端向前端数据保持统一性,要将supports的返回值为true,再将beforeBodyWrite里面的方法进行重写,利用Map集合包括(code,msg,data),进行补充。

3.4:注意事项

在beforeBodyWrite这个方法里面,如果body的数据为String类,此时,map所创建的集合不能转换为String类。因此,我们进行特殊处理。对于String类,我们使用jackson这个工具类,利用依赖注入注入ObjectMapper创建对象,

调用objectMapper.writeValueAsString(hashMap)这个静态方法,将map集合转换为json格式的字符串。

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;
    /*
      此方法返回true,则执行底下的beforeBodyWrite方法
       如若返回false,则不执行底下的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> hashMap=new HashMap<>();
        hashMap.put("code",200);
        hashMap.put("data",body);
        hashMap.put("msg","");
        if(body instanceof String){
            //需要特殊处理,因为String 在转换的时候需要特殊处理
            try {
                objectMapper.writeValueAsString(hashMap);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        return hashMap;
    }
}

相关文章
|
27天前
|
Java 关系型数据库 MySQL
创建一个SpringBoot项目,实现简单的CRUD功能和分页查询
【9月更文挑战第6天】该内容介绍如何使用 Spring Boot 实现具备 CRUD 功能及分页查询的项目。首先通过 Spring Initializr 创建项目并选择所需依赖;其次配置数据库连接,并创建实体类与数据访问层;接着构建服务层处理业务逻辑;最后创建控制器处理 HTTP 请求。分页查询可通过添加 URL 参数实现。
|
2月前
|
XML 前端开发 Java
基于SpringBoot 3.3实现任意文件在线预览功能的技术分享
【8月更文挑战第30天】在当今的数字化办公环境中,文件在线预览已成为提升工作效率、优化用户体验的重要功能之一。无论是文档、图片、PDF还是代码文件,用户都期望能够直接在浏览器中快速查看而无需下载。本文将围绕如何在Spring Boot 3.3框架下实现这一功能,分享一系列技术干货,助力开发者高效构建文件预览服务。
150 2
|
2月前
|
Java UED 开发者
Spring Boot 降级功能的神秘面纱:Hystrix 与 Resilience4j 究竟藏着怎样的秘密?
【8月更文挑战第29天】在分布式系统中,服务稳定性至关重要。为应对故障,Spring Boot 提供了 Hystrix 和 Resilience4j 两种降级工具。Hystrix 作为 Netflix 的容错框架,通过隔离依赖、控制并发及降级机制增强系统稳定性;Resilience4j 则是一个轻量级库,提供丰富的降级策略。两者均可有效提升系统可靠性,具体选择取决于需求与场景。在面对服务故障时,合理运用这些工具能确保系统基本功能正常运作,优化用户体验。以上简介包括了两个工具的简单示例代码,帮助开发者更好地理解和应用。
42 0
|
4天前
|
存储 前端开发 Java
Spring Boot 集成 MinIO 与 KKFile 实现文件预览功能
本文详细介绍如何在Spring Boot项目中集成MinIO对象存储系统与KKFileView文件预览工具,实现文件上传及在线预览功能。首先搭建MinIO服务器,并在Spring Boot中配置MinIO SDK进行文件管理;接着通过KKFileView提供文件预览服务,最终实现文档管理系统的高效文件处理能力。
|
5天前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
14 6
|
2月前
|
SQL 前端开发 NoSQL
SpringBoot+Vue 实现图片验证码功能需求
这篇文章介绍了如何在SpringBoot+Vue项目中实现图片验证码功能,包括后端生成与校验验证码的方法以及前端展示验证码的实现步骤。
SpringBoot+Vue 实现图片验证码功能需求
|
1月前
|
NoSQL 前端开发 Java
使用 Spring Boot + Neo4j 实现知识图谱功能开发
在数据驱动的时代,知识图谱作为一种强大的信息组织方式,正逐渐在各个领域展现出其独特的价值。本文将围绕使用Spring Boot结合Neo4j图数据库来实现知识图谱功能开发的技术细节进行分享,帮助读者理解并掌握这一技术栈在实际项目中的应用。
102 4
|
2月前
|
机器学习/深度学习 文字识别 前端开发
基于 Spring Boot 3.3 + OCR 实现图片转文字功能
【8月更文挑战第30天】在当今数字化信息时代,图像中的文字信息越来越重要。无论是文档扫描、名片识别,还是车辆牌照识别,OCR(Optical Character Recognition,光学字符识别)技术都发挥着关键作用。本文将围绕如何使用Spring Boot 3.3结合OCR技术,实现图片转文字的功能,分享工作学习中的技术干货。
78 2
|
2月前
|
安全 Java 应用服务中间件
如何在 Spring Boot 3.3 中实现请求 IP 白名单拦截功能
【8月更文挑战第30天】在构建Web应用时,确保应用的安全性是至关重要的。其中,对访问者的IP地址进行限制是一种常见的安全措施,特别是通过实施IP白名单策略,可以只允许特定的IP地址或IP段访问应用,从而有效防止未授权的访问。在Spring Boot 3.3中,我们可以通过多种方式实现这一功能,下面将详细介绍几种实用的方法。
87 1
|
2月前
|
算法 Java UED
你的Spring Boot应用是否足够健壮?揭秘限流功能的实现秘诀
【8月更文挑战第29天】限流是保障服务稳定性的关键策略,通过限制单位时间内的请求数量防止服务过载。本文基于理论介绍,结合Spring Boot应用实例,展示了使用`@RateLimiter`注解和集成`Resilience4j`库实现限流的方法。无论采用哪种方式,都能有效控制请求速率,增强应用的健壮性和用户体验。通过这些示例,读者可以灵活选择适合自身需求的限流方案。
47 2
下一篇
无影云桌面