代码优雅之道——Springboot统一返回结果

简介: 代码优雅之道 第一集

1、为什么要统一返回结果

从前后端分离模式开始后,后端只返回给前端json数据,在实际开发中,为了降低开发人员之间的沟通成本,一般返回结果会定义成一个统一格式,具体的格式根据实际开发业务不同有所区别。从前端的角度思考,调用后端接口后如果成功了则拿到想要的数据或者对应的信息提示,如果不成功也应该有相应的信息提示。从这个角度出发,我们将返回结果设计为:

  • code:响应状态码,根据状态码判断是否成功
  • msg:提示信息,根据调用的接口自定义
  • data:返回的数据

2、返回结果类

importlombok.Data;
importjava.io.Serializable;
/*** @author LoneWalker*/@DatapublicclassApiResult<T>implementsSerializable {
privatestaticfinallongserialVersionUID=411731814484355577L;
/*** 状态码*/privateintcode;
/*** 提示信息*/privateStringmsg;
/*** 相关数据*/privateTdata;
publicStringtoString() {
return"ApiResult(code="+this.getCode() +", msg="+this.getMsg() +", data="+this.getData() +")";
        }
/*** 构造器 自定义响应码与提示信息* @param code    响应码* @param message 提示信息*/privateApiResult(intcode,Stringmessage){
this.code=code;
this.msg=message;
        }
/*** 构造器 自定义响应码、提示信息、数据* @param code    响应码* @param message 提示信息* @param data    返回数据*/privateApiResult(intcode,Stringmessage,Tdata){
this(code,message);
this.data=data;
        }
/*** 成功构造器  无返回数据*/publicstatic<T>ApiResult<T>success(){
returnnewApiResult<>(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage());
        }
/*** 成功构造器 自定义提示信息 无返回数据* @param message 提示信息*/publicstatic<T>ApiResult<T>success(Stringmessage){
returnnewApiResult<>(ResultCodeEnum.SUCCESS.getCode(), message);
        }
/*** 成功构造器  有返回数据*/publicstatic<T>ApiResult<T>success(Tdata){
returnnewApiResult<>(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage(),data);
        }
/*** 失败构造器  无返回数据*/publicstatic<T>ApiResult<T>fail(){
returnnewApiResult<>(ResultCodeEnum.FAIL.getCode(), ResultCodeEnum.FAIL.getMessage());
        }
/*** 失败构造器 自定义提示信息 无返回数据* @param message 提示信息*/publicstatic<T>ApiResult<T>fail(Stringmessage){
returnnewApiResult<>(ResultCodeEnum.FAIL.getCode(), message);
        }
/*** 失败构造器  有返回数据*/publicstatic<T>ApiResult<T>fail(Tdata){
returnnewApiResult<>(ResultCodeEnum.FAIL.getCode(), ResultCodeEnum.FAIL.getMessage(),data);
        }
    }


3、状态码及提示信息枚举

除去基础的操作成功或失败,可以将状态码归类,例如请求参数问题归纳到1001-1999之间。

importlombok.Getter;
/*** @author LoneWalker*/@GetterpublicenumResultCodeEnum{
/*** success*/SUCCESS(0,"操作成功"),
/*** fail*/FAIL(-1,"操作失败"),
/*** 参数错误:1001-1999*/PARAM_IS_INVALID(1001,"参数无效"),
PARAM_TYPE_ERROR(1002,"参数类型错误"),
    ;
/*** 状态码*/privatefinalintcode;
/*** 提示信息*/privatefinalStringmessage;
ResultCodeEnum(Integercode, Stringmessage){
this.code=code;
this.message=message;
    }
}

4、使用与测试

controller

importcom.example.assertdemo.common.ApiResult;
importcom.example.assertdemo.entity.Contract;
importcom.example.assertdemo.req.AddContractReq;
importcom.example.assertdemo.req.QueryContractReq;
importcom.example.assertdemo.service.ContractService;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.PostMapping;
importorg.springframework.web.bind.annotation.RequestBody;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;
importjava.util.List;
@RestController@RequestMapping("/contract/")
publicclassContractController {
@AutowiredprivateContractServicecontractService;
@PostMapping("add")
publicApiResultaddContract(@RequestBodyAddContractReqrequest) {
returncontractService.addContract(request);
    }
@PostMapping("list")
publicApiResult<List<Contract>>listContract(@RequestBodyQueryContractReqrequest) {
returncontractService.listContract(request);
    }
}


新增或查询参数类

importlombok.Data;
/*** @author LoneWalker* @date 2022/8/28* @description*/@DatapublicclassAddContractReq {
/*** 合同编号*/privateStringcode;
/*** 合同名称*/privateStringname;
/*** 客户名称*/privateStringcustomer;
}


importlombok.Data;
/*** @author LoneWalker* @date 2022/8/28* @description*/@DatapublicclassQueryContractReq {
/*** 合同名称*/privateStringcontractName;
/*** 客户名称*/privateStringcustomer;
}

Service

importcom.example.assertdemo.common.ApiResult;
importcom.example.assertdemo.entity.Contract;
importcom.example.assertdemo.req.AddContractReq;
importcom.example.assertdemo.req.QueryContractReq;
importjava.util.List;
publicinterfaceContractService {
/*** 添加合同信息* @param request* @return*/ApiResultaddContract(AddContractReqrequest);
/*** 合同列表数据* @param request 查询参数* @return*/ApiResult<List<Contract>>listContract(QueryContractReqrequest);
}


impl

importcom.example.assertdemo.common.ApiResult;
importcom.example.assertdemo.entity.Contract;
importcom.example.assertdemo.req.AddContractReq;
importcom.example.assertdemo.req.QueryContractReq;
importcom.example.assertdemo.service.ContractService;
importorg.springframework.stereotype.Service;
importjava.util.ArrayList;
importjava.util.List;
@Service("contractService")
publicclassContractServiceImplimplementsContractService {
@OverridepublicApiResultaddContract(AddContractReqrequest) {
//存入数据库returnApiResult.success();
    }
@OverridepublicApiResult<List<Contract>>listContract(QueryContractReqrequest) {
//模拟数据List<Contract>list=newArrayList<>();
ContractcontractOne=newContract(1L, "HT082801", "临床试验一期合同", "省立医院");
ContractcontractTwo=newContract(2L, "HT082802", "临床试验二期合同", "省立医院");
ContractcontractThree=newContract(3L, "HT082803", "临床试验三期合同", "省立医院");
list.add(contractOne);
list.add(contractTwo);
list.add(contractThree);
returnApiResult.success(list);
    }
}

启动项目,新增一条数据

查询数据

5、问题

以上都是接口调用成功的情况,当业务出现异常,按照我们的初衷,需要将业务异常结果组装成统一的信息返回给前端进行提示。

下一篇 代码优雅之道——断言 + Springboot统一异常处理

相关文章
|
1月前
|
缓存 监控 Java
|
2月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
153 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1月前
|
缓存 监控 Java
|
2月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
565 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
2月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
667 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
2月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
2月前
|
消息中间件 Java 大数据
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
大数据-56 Kafka SpringBoot与Kafka 基础简单配置和使用 Java代码 POM文件
79 2
|
2月前
|
前端开发 Java
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
文章介绍了如何使用SpringBoot创建简单的后端服务器来处理HTTP请求,包括建立连接、编写Controller处理请求,并返回响应给前端或网址。
62 0
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
|
2月前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
97 0
|
3月前
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码