代码编织梦想

特别说明:本次项目整合基于idea进行的,如果使用Eclipse可能操作会略有不同,不过总的来说不影响。

springboot整合之如何选择版本及项目搭建

springboot整合之版本号统一管理 

springboot整合mybatis-plus+durid数据库连接池

springboot整合swagger

springboot整合mybatis代码快速生成

springboot整合之统一结果返回

springboot整合之统一异常处理

springboot整合之logback日志配置

springboot整合pagehelper分页

springboot整合本地缓存

springboot整合redis + redisson

springboot整合elasticsearch

springboot整合rabbitMq

springboot整合canal实现缓存一致性

springboot整合springSecurity(前后端不分离版本)

一、为什么要对结果进行统一的返回

可能有很多小伙伴不理解为什么我们要对结果进行统一的返回,我们之前那种直接返回结果不也挺好的吗?

类似于上面这种,我们是直接就给接口调用方返回了用户信息,这样也不能说有问题,但是不够优雅。比如说现在用户请求参数错了,我们该怎么返回? 

 这样以来,接口调用方还要根据内容去判断我们的返回结果,如果说不同的错误返回的信息又是不一样的,比如现在这个返回“当前用户不存在,参数错误”,另一个接口返回“权限不足,请申请权限后操作!”,那这样对接口调用方来说简直就是痛苦面具。

所以为了我们的接口调用返回结果更加优雅,我们可以采取统一返回结果。我们在结果里面加上状态码,消息以及返回的数据。这样接口调用方就能够根据我们的返回状态码来判定结果的状态,然后根据状态去判定显示结果还是显示错误提示。这样就会显得优雅一点。具体实现也很简单。下面我们就一步一步来实现一下。

二、准备需要的目录结构

我们首先在项目里新建下面的几个包,以备后用。简单说明一下:common就是打算以后把公共的类就放到这里面来,enums就是放我们用到的枚举类,response就是放我们的返回结果类,utils存放工具类。

三、创建统一返回结果类

按照我们上面说的,这个类有三个成员属性,分别是:status用来标记请求状态,msg用来返回消息,如果成功就返回“OK”,失败就返回错误消息提示。data用来返回数据。这里面我还增加了一个常量 SUCCESS,用来表示200,表示请求成功的状态。定义为了public类型,后面方便我们在别的类调用。本来也打算把401,403,404,500这些常见的状态也都定义进来的。但是考虑了一下,打算把常见的错误状态做成枚举,避免大家重复定义,用起来更加简单方便一点。

package com.example.springbootdemo.common.response;

import com.example.springbootdemo.common.enums.ErrorCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @description: Result 统一返回结果<br>
 * @date: 2022/12/27 0027 下午 1:09 <br>
 * @author: William <br>
 * @version: 1.0 <br>
 */
@Data
@ApiModel(value="统一返回结果对象", description="")
public class Result {

    /**
     *操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 响应业务状态
     */
    @ApiModelProperty(value = "响应业务状态")
    private Integer status;

    /**
     * 响应消息
     */
    @ApiModelProperty(value = "响应消息")
    private String msg;

    /**
     * 响应中的数据
     */
    @ApiModelProperty(value = "响应中的数据")
    private Object data;



    /**
     * description: Result  默认无参构造<br>
     * @version: 1.0
     * @date: 2022/12/27 0027 下午 1:21
     * @author: William
     */
    public Result() {

    }

    /**
     * description: Result  只包含返回数据构造方法<br>
     * @version: 1.0
     * @date: 2022/12/27 0027 下午 1:22
     * @author: William
     * @param data   需要返回数据
     */
    public Result(Object data) {
        this.status = SUCCESS;
        this.msg = "OK";
        this.data = data;
    }

    /**
     * description: Result 包含所有参数的构造方法<br>
     * @version: 1.0
     * @date: 2022/12/27 0027 下午 1:23
     * @author: William
     * @param status    状态
     * @param msg       消息
     * @param data      数据
     */
    public Result(Integer status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public static Result ok() {
        return new Result(null);
    }

    public static Result ok(Object data) {
        return new Result(data);
    }

    /**
     * description: error 异常时返回方法<br>
     * @version: 1.0
     * @date: 2022/12/27 0027 下午 1:25
     * @author: William
     * @param errorCodeEnum   异常枚举对象
     * @return com.example.springbootdemo.common.response.Result
     */
    public static Result error(ErrorCodeEnum errorCodeEnum) {
        return new Result(errorCodeEnum.getValue(), errorCodeEnum.getMessage(), "");
    }

    public static Result build(Integer status, String msg) {
        return new Result(status, msg, null);
    }

    public static Result build(Integer status, String msg, Object data) {
        return new Result(status, msg, data);
    }

}

四、创建统一异常枚举类

package com.example.springbootdemo.common.enums;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
 * description:  错误信息枚举类规定:编写时按照模块分类,每个模块写到一起,便于修改和维护返回状态根据Http状态码定义来 <br>
 * @version: 1.0
 * @date: 2022/12/27 0027 下午 1:18
 * @author: William
 */
@NoArgsConstructor
@Getter
@AllArgsConstructor
public enum ErrorCodeEnum {

    //公共模块
    UNAUTHORIZED(401,"未认证"),
    FORBIDDEN(401,"未授权"),
    ILLEGAL_VALUE(404,"参数非法"),
    OPERATION_FAILED(404,"操作失败");

    int value;
    String message;
}

五、修改测试接口

到上面第四步完成我们的统一结果返回就算封装好了,接下来我们就能够使用我们自己定义的统一返回结果类了。我们来修改一下userController,把之前的返回字符串改为返回同意结果返回。

这里有个点跟大家讲一下,因为我这就是demo,并不是真正的业务,我就把查询用户放到了controller里面了,如果是正式项目,大家把查询还是要放到业务层service里面去做。

package com.example.springbootdemo.controller;


import cn.hutool.core.bean.BeanUtil;
import com.example.springbootdemo.common.enums.ErrorCodeEnum;
import com.example.springbootdemo.common.response.Result;
import com.example.springbootdemo.entity.User;
import com.example.springbootdemo.service.UserService;
import com.example.springbootdemo.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author William
 * @since 2022-12-27
 */
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;



    /**
     * description: userInfo 过根据用户ID获取用户信息<br>
     * @version: 1.0
     * @date: 2022/12/27 0027 下午 2:30
     * @author: William
     * @param id   用户ID
     * @return com.example.springbootdemo.common.response.Result
     */
    @ApiOperation(value = "根据用户ID获取用户信息")
    @GetMapping("/{id}")
    public Result userInfo(@PathVariable("id") Integer id){
        if(id == null || id <= 0){
            return Result.error(ErrorCodeEnum.ILLEGAL_VALUE);
        }
        User user = userService.getById(id);
        if(user == null){
            return Result.error(ErrorCodeEnum.ILLEGAL_VALUE);
        }
        return Result.ok(user);
    }

}

六、启动测试

操作完成后我们就可以启动测试了。

 启动成功,接下来我们打开swagger来测试一把。首先我们输入一个不存在的用户试一下(我这里把前两条数据给删除了,所以输入1和2是不存在的,你们看一下自己的数据库进行测试就好)

 可以看到当前的结果是

{
  "status": 404,
  "msg": "参数非法",
  "data": ""
}

这样看起来是不是就舒服多了。然后我们再来看一下正常的

 怎么样是不是体验感一下就上来了。

七、遗留问题解决

。。。突然返现一个严重的问题,就是大家有没有发现我们竟然把用户密码给返回出来了!!!这岂不是要出大问题。我们在返回用户数据的时候一定要格外的小心,因为一不小心就会发生用户信息泄露的事故。这里我们来改造一下吧。我们现在先假设前端只需要返回id和userName.

因为等下我们需要将用户信息copy到userVo中,所以我们需要用到一个工具类,这里我给大家推荐一个我觉得非常好用的工具类,那就是hutool工具包,相信不少小伙伴都用过。两个字好用!!但是有一个问题就是这个里面工具类非常的多,如果有代码洁癖那么不太建议引入。可以自己按照要求来写就好。像我们经常用到的框架或者中间件,感兴趣的小伙伴可以研究一下源码,你会发现他们基本上都是自己封装工具类,不会引入其他jar包。这样主要是为了框架更加轻量级,不需要引入其他jar包即可使用,还有就是用到什么就封装什么,不会导致项目里面存在没有用的代码。减少代码打包的体积,以及运行的速度。言归正传,我们还是先把我们的问题给解决了。

1.引入hutool工具包

        <hutool.version>5.8.7</hutool.version>   
        <!--hutool工具-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>

2.新建UserVo类

package com.example.springbootdemo.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @description: UserVo <br>
 * @date: 2022/12/27 0027 下午 2:39 <br>
 * @author: William <br>
 * @version: 1.0 <br>
 */
@Data
@ApiModel(value = "用户信息对象")
public class UserVo implements Serializable {

    /**
     * 用户ID
     */
    @ApiModelProperty(value = "用户ID")
    private Long id;

    /**
     * 用户名
     */
    @ApiModelProperty(value = "用户名")
    private String userName;
}

3.修改测试类

package com.example.springbootdemo.controller;


import cn.hutool.core.bean.BeanUtil;
import com.example.springbootdemo.common.enums.ErrorCodeEnum;
import com.example.springbootdemo.common.response.Result;
import com.example.springbootdemo.entity.User;
import com.example.springbootdemo.service.UserService;
import com.example.springbootdemo.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author William
 * @since 2022-12-27
 */
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;



    /**
     * description: userInfo 过根据用户ID获取用户信息<br>
     * @version: 1.0
     * @date: 2022/12/27 0027 下午 2:30
     * @author: William
     * @param id   用户ID
     * @return com.example.springbootdemo.common.response.Result
     */
    @ApiOperation(value = "根据用户ID获取用户信息")
    @GetMapping("/{id}")
    public Result userInfo(@PathVariable("id") Integer id){
        if(id == null || id <= 0){
            return Result.error(ErrorCodeEnum.ILLEGAL_VALUE);
        }
        User user = userService.getById(id);
        if(user == null){
            return Result.error(ErrorCodeEnum.ILLEGAL_VALUE);
        }
        UserVo userVo = new UserVo();
        BeanUtil.copyProperties(user, userVo);
        return Result.ok(userVo);
    }

}

OK,我们再来重新启动测试一把。

 可以看到,现在就只返回了需要的信息。

好了,到这里我们的统一返回结果就OK了。如果对你有所帮助,希望你能够给个点赞和关注呦,多谢啦~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_35771266/article/details/128454724

springboot统一封装返回结果-爱代码爱编程

前言 在项目框架整合阶段,为了更优雅的封装后端返回结果,便于前后端联调,通常需要对后端的返回值进行一定的封装处理,下面介绍2种比较实用的方式 方式1:常规处理 定义一个枚举类,主要包括返回的code和message,更多的返回码可以根据业务需要在后面继续添加 @Getter public enum ResponseCodeEnums {

SpringBoot 整合 RestTemplate-爱代码爱编程

目录 一、概述 1. 介绍 二、整合 RestTemplate 1. RestTemplateConfig 配置类 2. 工具类 3. RestTemplate 方法 4. getForEntity 方法 4.  exchange 方法 5.  postForEntity 方法 三、测试案例 1. RestTemplateContro

SpringBoot 整合 JWT 实现统一认证-爱代码爱编程

JWT官网:https://jwt.io/introduction/ 参考:http://c.biancheng.net/view/5499.html JWT是什么? JWT(Json Web Token)是为了在网络应用环境间传递声明而执行的一种基于 Json 的开放标准。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信

SpringBoot整合Swagger与统一返回结果问题-爱代码爱编程

        写此博客,以此留念,解决了因使用统一返回结果对象导致,swagger-ui看不到返回对象属性注释的原因。(没有使用泛型导致) Springboot统一结果返回对象 @Data @ApiModel("统一API响应结果封装") public class DataResult<T> { /**操作结果 0为成功*/

【一】springboot整合swagger(超详细)-爱代码爱编程

介绍:接下来我会把学习阶段学到的框架等知识点进行整合,每一次整合是在前一章的基础上进行的,所以后面的整合不会重复放前面的代码。每次的demo我放在结尾。 第一步:创建Springboot项目 打开idea——>点击文件,创建文件。 选择Spring Initializr,点击下一步。 选择java版本8。 点击下一步。 根据需

SpringBoot整合Cache-爱代码爱编程

目录 一、Spring Boot与缓存1.1 缓存注解1.2 注解主要参数1.3 SpEl表达式1.4 基本使用1.5 基本原理1.6 整合redis实现缓存 一、Spring Boot与缓存 Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expi

六、SpringBoot整合日志log-爱代码爱编程

目录 一、SpringBoot整合logback二、SpringBoot整合log4j三、使用AOP统一处理Web请求日志 一、SpringBoot整合logback 1.logback的pom依赖 Springboot 已经默认整合好了logback,日志输出文件在当前项目路径log文件夹下我们只需要添加lombok依赖,可以帮助我们

SpringBoot整合-爱代码爱编程

SpringBoot 新建项目 项目文件结构 @SpringBootApplication public class SpringBootTestApplication { public static void main(String[] args) { SpringApplication.run(SpringBoot

springboot-09-封装统一返回类_老姚coding的博客-爱代码爱编程

前言 在项目框架整合阶段,为了更优雅的封装后端返回结果,便于前后端联调,通常需要对后端的返回值进行一定的封装处理 1、新建返回code 的枚举类 @Getter public enum ResultCodeEnums { SUCCESS("10000","成功"), ERROR("20000","系统繁忙"); Resul

springboot后台统一返回处理_楓楓楓楓楓的博客-爱代码爱编程

后台在接收前端请求数据的时候,后端处理完需要对前端请求的ajax或者H5页面的跳转做统一的返回处理,同时也需要对可能造成的异常进行全局统一处理,使当程序运行异常的时候ajax返回统一的异常码,H5请求跳转到统一的错误提示页面。 1、先对全局正常返回类进行包装 @RestControllerAdvice(basePackages = {"com.xxx

在spring boot项目中使用统一返回结果_picacho_pkq的博客-爱代码爱编程

在一个完整的项目中,如果每一个控制器的方法都返回不同的结果,那么对项目的维护和扩展都会很麻烦;并且现在主流的开发模式时前后端分离的模式,如果后端返回各式各样的结果,那么在前后端联调时会非常的麻烦,还会增加前后端的格外任务。

【springboot笔记18】springboot实现统一异常处理、统一结果响应、统一参数校验_朱友斌的博客-爱代码爱编程

这篇文章,主要介绍如何利用SpringBoot框架实现统一异常处理、统一结果响应、统一参数校验。 目录 一、SpringBoot统一结果响应 1.1、创建工程 1.2、配置FastJson 1.3、创建ResultEnum枚举 1.4、创建Result实体类 二、SpringBoot统一异常处理 2.1、创建自定义异常类 2.2

springboot整合之版本号统一管理-爱代码爱编程

特别说明:本次项目整合基于idea进行的,如果使用Eclipse可能操作会略有不同,不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理  springboot整合mybatis-plus+durid数据库连接池 springboot整合swagger springboot整合mybat

springboot整合thymeleaf_pringboot response.setheader not work thymeleaf-爱代码爱编程

Spring Boot Spring Boot配置绑定 配置文件中的值与 JavaBean 中对应的属性进行绑定 @ConfigurationProperties 注解 application.yml或者ap