Java高级特性-泛型:泛型实战,封装统一的服务端响应类

在平时工作中,我们写代码可能都在堆增删改查,很少有机会加上 Java 的高级特性。比如,泛型,你一定在 Mybatis、Hibernate 这些持久化框架中用过。可轮到自己开发的时候,却发现这个东西简直鸡肋,完全用不上。

相信我,这种感觉很正常。因为开源框架往往要用同一套算法,来应对不同的数据结构,而 Java 的高级特性能减少重复代码,从而提高项目的可维护性。

然而,我们可能身处小公司,项目做完就直接交给客户了。你在最短时间完成工作就行,项目完全没有维护的必要。

但是,没有关系。这次我们来解锁泛型,用它来封装一个服务端返回类。

需求分析

不知道你有没有接手过一些老项目?那时候,SpringMVC 才刚刚出来,大家对代码规范也没概念。结果,碰上个这么方便的框架,后端开发人员就想也不想,直接把各种实体类返回给前端。

然而,时间一久,问题就来了。

首先,数据没法保证一致性。你请求某个接口的时候,如果传入的参数不同,得到的结果肯定也会不同。你看下面这个例子:

// 获取用户信息,正确返回
{
    "username": "jiarupc",
    "nickname": "法外狂徒、张三",
    "create_date": "2020-12-31 00:00:00"
}

// 获取用户信息,错误返回
{
    "msg": "缺少参数,请传入 token"
}

然后,前端没法处理。你想想看,一个接口如果有时候就返回一堆用户信息,有时候又只返回一条错误信息,这得写多少 if-else 判断呀?

最后,没法团队合作。如果碰上复杂的项目,最少也要几个人一起开发。这时候,要是返回格式没有一个标准,每个人都按照自己的想法随便写,那项目迟早得乱套。

事实上,在接手一些老项目时,你会经常看到这种情况。业务明明不复杂,但只要改了一点东西,好几个前端页面就白屏了。

这时候,如果你想根本解决问题,就必须封装统一服务端响应类。

设计-服务端响应类

服务端响应类有 2 个要点:返回值、错误码。

先来看返回值。在返回前端的时候,我们必须要有这 3 个信息:

  1. code,响应代码;
  2. data,响应数据;
  3. msg,响应信息;

其中,我们还要进一步设计响应代码,让它能适配更复杂的环境,这里给出几个常用的响应码,你也可以根据实际情况自己设计。

  1. 200-请求成功
  2. 101-执行错误
  3. 102-参数错误

整体的设计工作就完成了,看起来没啥技术含量,可值得你重视。软件开发中,有些工作虽然很简单,但影响重大,服务端响应类就是这样。

那么,接下来就是开发工作了。

开发-服务端响应类

首先,定义响应代码,我用的是枚举。

public enum ResponseCode {

    // 成功返回
    SUCCESS(200, "SUCCESS"),
    // 执行错误
    ERROR(101, "ERROR"),
    // 参数错误
    ILLEGAL_ARGUMENT(102, "ILLEGAL_ARGUMENT"));

    private final int code;
    private final String desc;

    ResponseCode(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    // 省略 getter 方法
}

然后,创建服务端响应类。其中,为了让 data-响应数据 适配更多的业务场景,我们用泛型来定义它。

public class ServerResponse<T> implements Serializable {
    
    // 响应代码
    private int code;
    // 响应信息
    private String msg;
    // 响应数据
    private T data;

    /**
     * 构造方法
     */
    private ServerResponse(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    private ServerResponse(int code, T data) {
        this.code = code;
        this.data = data;
    }
    private ServerResponse(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    private ServerResponse(int code) {
        this.code = code;
    }

    /**
     * 请求成功
     * @param msg  返回信息
     * @param data 泛型数据
     * @param <T>  返回数据,可以不填
     * @return 1.状态码(默认) 2.返回信息 3.泛型数据
     */
    public static <T> ServerResponse<T> createSuccess(String msg, T data) {
        return new ServerResponse<>(ResponseCode.SUCCESS.getCode(), msg, data);
    }
    public static <T> ServerResponse<T> createSuccess(T data) {
        return new ServerResponse<>(ResponseCode.SUCCESS.getCode(), data);
    }
    public static <T> ServerResponse<T> createSuccess(String msg) {
        return new ServerResponse<>(ResponseCode.SUCCESS.getCode(), msg);
    }
    public static <T> ServerResponse<T> createSuccess() {
        return new ServerResponse<>(ResponseCode.SUCCESS.getCode());
    }

    /**
     * 请求失败
     * @param code
     * @param msg
     * @return 1.状态码(自定义) 2.返回信息(自定义)
     */
    public static <T> ServerResponse<T> createError(int code, String msg) {
        return new ServerResponse<>(code, msg);
    }
    public static <T> ServerResponse<T> createError() {
        return new ServerResponse<>(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDesc());
    }
    public static <T> ServerResponse<T> createError(String msg) {
        return new ServerResponse<>(ResponseCode.ERROR.getCode(), msg);
    }

    
    // 省略 getter 方法
}

开发工作也完成了,接下来,我们可以做出规定,在 Controller 层Service 层中,返回数据必须是 ServerResponse,不许另起炉灶。

到了这儿,老项目的数据混乱问题,就被圆满解决了。

写在最后

泛型是 Java 的高级特性,但我们很少在工作中用到,但是没有关系。在老项目中,前后端交互没有统一的数据标准,这正好是机会。

为了解决这个问题,我们封装了统一的服务端返回类 ServerResponse,这其中 data-响应数据 用到了泛型,为的是适应更多的业务场景。

文章演示代码:点击跳转

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容