两种后端返回值类型的封装方式

两种后端返回值类型的封装方式

引言:在开发中,前后端分离是常态。前后端使用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.明确返回数据实体的类型,通过泛型,约束了返回实体的类型

posted @   YURainnn  阅读(1297)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示