两种后端返回值类型的封装方式
两种后端返回值类型的封装方式
引言:在开发中,前后端分离是常态。前后端使用json交换信息是一种标准化。一般前端通过访问路径传递到后端的Json内容,后端可以通过@RequestBody解析,Rest风格的传参方式可以使用@PathVariable注解解析。后端在完成前端增,删,查,的功能后,一般会将结果形成实体类,返回前端。而单实体类并不能满足前端调用的方便性,且包含的信息少,需要后端将结果的状态,短信息,以及数据内容封装起来。
前后端共识的返回信息包括:
- 前端请求后端执行结果的状态码(status);
- 前端请求后端执行结果的执行信息(message);
- 后端完成请求获得的数据实体类(data);
1.状态码和状态信息的封装
状态码、状态信息一般为固定信息,包含成功,失败两部分。而具体的操作的成功和失败,又包含大量的自定义信息。如查询成功,操作成功,登录成功等等。一般作为公司内部定义的状态信息,各个模块可以通用调用。
那么一般封装为枚举类。
封装一个状态码和状态信息枚举类。
//首先定义一个枚举类ReturnStatus
public Enum ReturnStatus{
//定义枚举状态
LOGIN_OK(20000,"登录成功"),LOGIN_FAIL(30000,"登录失败"),
ERROR(30001,"账号或密码错误"),
//定义通用的返回信息和返回状态码
OK(2000,"操作成功"),ERROR(3000,"操作失败");
//定义成员
//状态码
private int code;
//状态信息
private String message;
//私有构造
private ReturnStatus(int code,String message){
this.code=code;
this.message=message;
}
/*
不设置set方法,程序运行外部无法修改Enum类中的成员,只可以统一维护
*/
//getter方法
public String getMessage(){
return this.message;
}
public int getCode(){
return this.code;
}
}
2.返回类型(数据+状态)的封装
2.1继承HashMap封装返回类
//创建返回类型类--将要被转换为json返回给前端
//可以使用map k-v对应的方式构造返回类型
//继承hashmap,key为String格式,V为Object格式
public class ResultData extends HashMap<String,Object>{
//要返回的信息的key必须不可变,防止在外部手动输入key出错 包括
//code
public static final String CODE="code";
//message
public static final String MESSAGE="message";
//实体data
public static final String DATA="data";
//创建私有构造,使外部不能直接创建该对象
/*
因该返回类中,包含3种信息,一种为code,一种为message,一种为Object的data
因此前两项为ReturnEnum中的值,后一种为实际执行功能后得到的值,私有构造传参为ReturnEnum
*/
private ResultData(ReturnEnum returnEnum){
//使用本类对象的put方法,设置code为returnEnum中拿到的code
this.put(CODE,returnEnum.getCode());
//同上
this.put(MESSAGE,returnEnum.getMessage())
}
//创建静态方法
//默认成功
public static ResultData success(){
return new ResultData(returnEnum.OK);
}
//默认成功并携带数据
public static ResultData success(Object data){
ResultData resultData = new ResultData();
returnData.put(DATA,data);
return resultData;
}
//自定义成功,不携带数据
public static ResultData success(ReturnEnum returnEnum){
return new ResultData(returnEnum);
}
//自定义成功,携带数据
public static ResultData success(ReturnEnum returnEnum,Object data){
ResultData resultData = new ResultData();
resultData.put(CODE,returnEnum.getCode());
resultData.put(MESSAGE,returnEnum.getMessage());
resultData.put(DATA,data);
return resultData;
}
//默认失败
public static ResultData error(){
return new ResultData(returnEnum.ERROR);
}
//自定义失败
public static ResultData error(ReurnEnum returnEnum){
ResultData resultData = new ResultData();
resultData.put(CODE,returnEnum.getCode());
return resultData;
}
//自定义失败携带数据
public static ResultData error(ReturnEnum returnEnum, Object data){
ResultData resultData = new ResultData();
resultData.put(CODE,returnEnum.getCode());
resultData.put(MESSAGE,returnEnum.getMessage());
resultData.put(DATA,data);
return resultData;
}
}
这样封装的好处是:
1.外部调用方便,不必关心要返回的对象是如何创建,如何赋值的,只需传如参数即可
2.继承HashMap,保证key的正确性,前端拿取数据不必担心出错
3.数据data和code/msg统一放入value
2.2 封装带泛型返回类
不知道返回的数据类型情况下,创建的返回类为泛型类,根据传入的数据确定返回的数据类型
已经确定的2个成员,为Enum中的2个属性
泛型类
1.返回类中,2个成员已确定,为int 的code 和String的 message
2.携带的数据不确定。如果定位Object,导致外部调用时可能需要强转,需要创建泛型类
泛型类
public class AjaxResult<T>{} //类名后加 <T>
成员变量
prvate int code;
private String message;
//代表返回数据类的成员
private T t;
构造无参,setter和getter方法,略
要返回AjaxResult,之前的方法是创建静态方法,调用时返回new AjaxResult
如要携带数据,在该静态方法内创建AjaxResult对象,并设置AjaxResult内的成员变量T
新思路
创建一个setData方法,调用各个返回的静态方法时,在方法内创建AjaxResult对象,并设置参数,return setData()方法即可
1.setData方法的返回值时AjaxResult
2.setData方法不能保证携带的数据类型,因此必须是泛型方法(方法名前 < T >,方法形参T t)
创建setData内部方法
private static<T> AjaxResult<T> setData(ReturnEnum returnEnum, T t){
//创建AjaxResult对象
AjaxResult<T> ajaxResult = new AjaxResult<>();
//设置AjaxResult
ajaxResult.setCode(returnEnum.getCode());
ajaxResult.setMessage(returnEnum.getMessage());
ajaxResult.setT(t);
//setData方法返回设置好的AjaxResult对象
return ajaxResult;
}
成功和失败的默认方法,以及自定义成功code/message和失败code/message的方法,没有返回值,在调用setData方法时,T参数传null即可;不携带数据不必加泛型,因为返回的内容是确定的
创建成功/失败返回默认Code/Message的方法
//成功
public static AjaxResult success(){
return setData(ReturnEnum.OK,null);
}
//失败
public static AjaxResult error(){
return setData(ReturnEnum.ERROR,null);
}
创建成功/失败返回自定义Code/Message的方法
public static AjaxResult success (ReturnEnum returnEnum){
return new setData(returnEnum);
}
public static AjaxResult error (ReturnEnum returnEnum){
return new setData(returnEnum);
}
创建成功/失败自定义code/message并且携带数据,泛型方法
//成功
public static<T> AjaxResult<T> success(ReturnEnum returnEnum, T t){
return setData(returnEnum,t);
}
//失败
public static<T> AjaxResult<T> error(ReturnEnum returnEnum, T t){
return setData(returnEnum,t);
}
一览
public class AjaxResult<T>{
prvate int code;
private String message;
//代表返回数据类的成员
private T t;
//创建构造方法
public AjaxResult(){}
//创建Setter和getter
public void setCode(int code){
this.code = code;
}
public void setMessage(String message){
this.message = message;
}
public void setT(T t){
this.t = t;
}
public int getCode(){
return this.code;
}
public String getMessage(){
return this.message;
}
public T getT(){
return this.t;
}
//创建给AjaxResult赋值的方法
private static<T> AjaxResult<T> setData(RetrunEnum returnEnum,T t){
AjaxResult<T> ajaxResult = new AjaxResult<T>();
ajaxResult.setCode(returnEnum.getCode());
ajaxResult.setMessage(returnEnum.getMessage());
ajaxResult.setT(t);
return ajaxResult;
}
//创建默认的成功方法
public static AjaxResult success(){
return setData(ReturnEnum.ok,null);
}
//创建自定义成功不携带数据
public static AjaxResult success(ReturnEnum returnEnum){
return setData(returnEnum,null);
}
//创建自定义成功携带数据
public static<T> AjaxResult<T> success(ReturnEnum returnEnum,T t){
return setData(returnEnum,t);
}
//失败
public static AjaxResult error(){
return setData(ReturnEnum.ERROR,null);
}
//自定义失败
public static AjaxResult error (ReturnEnum returnEnum){
return new setData(returnEnum);
}
//自定义失败返回数据
public static<T> AjaxResult<T> error(ReturnEnum returnEnum, T t){
return setData(returnEnum,t);
}
}
这样封装的好处是:
1.外部调用方便,不需要关心要返回的对象时如何创建的,只需传参
2.节省代码,创建同一的setData方法,各种返回状态的设置只需return setData方法的返回值即可
3.明确返回数据实体的类型,通过泛型,约束了返回实体的类型
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤