V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kqq19930511
V2EX  ›  Java

后端接口枚举值和对应的描述是如何返回的?

  •  
  •   kqq19930511 · 2 天前 · 2009 次点击

    例如有以下的枚举值:

    DANGER(0, "危急"),
    SERIOUS(1, "严重"),
    GENERAL(2, "一般")
    
    • 第一种方法:只返回对应的数值,前端根据数值转换为中文描述,但是存在一个缺陷:添加新的枚举值后,前端需要重新部署
    • 第二种方法:定义一个包装对象,添加一个描述属性,然后循环遍历所有对象,将枚举值转换为中文描述值
    • 第三种方法:数据库中有通用字典表,将枚举值写入到数据库中,查询时关联字典表,查出描述值
    • 第四种方法:返回对象列表和枚举值列表,让前端自己组合两个对象,展示到页面上

    大家平时开发用的什么方案?或者 java springboot 中有通用的解决方案吗?

    37 条回复    2025-02-20 11:40:01 +08:00
    spritecn
        1
    spritecn  
       2 天前
    我这边大概这样:
    权限类经常改的用 2
    大部分情况 status,type 类的用 1(一般后端添加了枚举后,前端也得做对应界面功能,不然为啥要改)
    RandomJoke
        2
    RandomJoke  
       2 天前
    一般场景 enum 存储 SERIOUS 字符串,存储一般情况都不值钱。不太变动的场景直接返回,经常变动的返回 desc 以及 enum 字符串
    shuangbiaog
        3
    shuangbiaog  
       2 天前
    一般用方法 1 吧,除了 4 都可行,如果字典和数据要独立,那应该拆分成两个接口
    kqq19930511
        4
    kqq19930511  
    OP
       2 天前
    @spritecn #1 第二种有通用解决方案吗?每次都得遍历去设置描述?
    kqq19930511
        5
    kqq19930511  
    OP
       2 天前
    @shuangbiaog #3 如果拆开,每次前端展示列表的页面,都得请求两次接口才能展示了,合并成一个不好吗?
    shuangbiaog
        6
    shuangbiaog  
       2 天前
    @kqq19930511 不符合设计原则,碰到分页场景也不好处理,另外请求两次不一定就比请求一次慢
    fciasth
        7
    fciasth  
       2 天前
    第二种,用 AOP+注解实现
    jeepc
        8
    jeepc  
       2 天前
    @kqq19930511 #4 转成 map
    kqq19930511
        9
    kqq19930511  
    OP
       2 天前
    @fciasth #7 自己实现的?还是有开源解决方案
    DonaldY
        10
    DonaldY  
       2 天前
    我们做法是返回:code (枚举值)、desc (对应 code 描述)
    存储有本地、缓存、数据库,达到后端更新,前端不需要改动。

    以及 desc 描述,国际化多语言,搭配 i18n
    fengpan567
        11
    fengpan567  
       2 天前
    没有专门的枚举字典接口?
    kqq19930511
        12
    kqq19930511  
    OP
       2 天前
    @DonaldY #10 返回结果如何组织的?方案二还是方案四?
    vikaptain
        13
    vikaptain  
       2 天前
    我一般是具体的数据返回 State:枚举值,返回 StateDescription:具体的描述内容。
    接口文档列举所有的枚举值和描述。
    w292614191
        14
    w292614191  
       2 天前
    可以看下这个: https://crane4j.cn/

    但实际业务中还是比较复杂,都是前端转一遍。
    DonaldY
        15
    DonaldY  
       2 天前
    @kqq19930511
    @DonaldY
    类似这样,前端直接展示就行
    [{
    "code": 0,
    "desc": "危急"
    }]
    lasuar
        16
    lasuar  
       2 天前
    业务复杂后,设计一个字典表,支持在管理后台修改,其他需要的页面传参拉取对应的字典枚举就行了。
    HaibaraDP
        17
    HaibaraDP  
       2 天前
    自定义序列化返回枚举对象,返回{"code":0,"name":"危急"},另外再提供一个字典接口
    CyouYamato
        18
    CyouYamato  
       2 天前
    第一种, 重新部署就是多会摸鱼时间呗.自己业余时间全栈项目也是第一种, 后端用的 Nest.js, 对象,枚举 直接往前端复制.没啥成本.
    lasuar
        19
    lasuar  
       2 天前
    业务前期不需要设计字典表,浪费人力资源,把枚举映射发给前端即可
    PRStarDust
        20
    PRStarDust  
       2 天前
    用的 jeecgboot 框架,它有单独的字典表,每次启动的时候会缓存到 redis 里。之后前端在登录后好像会调用字典接口获取所有字典项。最后还用 aop+注解自动给加了字典注解的字段额外返回一个叫做 [原字段名_dictText] 的字段,里面放的是字段 code 对应的描述,这样前端调用列表查询接口就不用额外再查直接显示就行
    andy2415
        21
    andy2415  
       2 天前
    使用 @EnumValue
    importmeta
        22
    importmeta  
       2 天前
    前端不用管, 后端自己查, 加个字段返给前端,碰见过这样的.
    lambdaq
        23
    lambdaq  
       2 天前
    非 java 。
    我一般是返回 code: 0, code_name: 危急

    这个定义,如果不经常变,就写到代码里作为枚举。如果随着业务会增改,会放到 db 字典表。

    感觉是你 2 3 方法的结合。1 4 都麻烦了。
    lyxxxh2
        24
    lyxxxh2  
       2 天前
    一直都是第一种,api 文档,将后端常量代码 cv 上去就行。
    至于新增一个枚举重新部署,你不说我都不知道。
    一开始都设计好了,新增很少,而且枚举也没几个。

    数据库我都不用枚举,更喜欢用`UNSIGNED TINYINT`。
    不然新增个枚举元素,还得生成迁移改数据库。
    git00ll
        25
    git00ll  
       2 天前
    就 1, 一次尽量定义全,万一需要加就拉着前端一起加。
    万一是各个国家的语言还要后端写死在代码里吗
    Plutooo
        26
    Plutooo  
       2 天前
    如果有当前页面导出的功能,那么最好后端自己转好,不然导出还是要重新写一遍
    如果没有导出的,可以把字典表做成一个单独的接口返回给前端
    kinkin666
        27
    kinkin666  
       2 天前
    主要是 1 、3 ,

    关于 1 ,因为没有 i18n 需求,我们这里前端相对不动,前端根据 code 兜底显示成功失败告警,具体对客描述还是要服务端返回的,特殊流程要约定具体的 code 要干嘛
    关于 3 ,主要是用作单选框复选框的列表值,配在这里的东西都是假设前端可以在无权限的情况下拿到的(实际上还需要字典代码)(我给这个功能套的是 guava 的缓存,前端那边自己也缓存了一下,每次只加载一次)

    不认为将所有枚举值列表不作区分的返回到前端是一个好做法,暴露的信息有点多!
    如果未来有 i18n 需求,恐怕也是前端干前端的,后端干后端的
    kqq19930511
        28
    kqq19930511  
    OP
       2 天前
    @w292614191 #14 学习一下这个方案
    oldManNewThought
        29
    oldManNewThought  
       2 天前
    第 5 种:具体接口返回数值。另外单独提供接口获取相应枚举列表。前端封装一个字典组件,只需要传入枚举名称,组件里根据名称去后端查询枚举列表,组件里做了缓存,不需要一直查询。这方案,目前我感觉是最完美的
    wangtian2020
        30
    wangtian2020  
       2 天前
    没有银弹

    我的做法是返回值一定是 200 的,
    然后在 json 里 code 区分 500 啥的
    然后根据不同的 json 对象的 code ,弹 error 或者 warning 弹窗,把 message 弹出来。返回 message 的语言类型可以由请求头控制
    guiling
        31
    guiling  
       2 天前
    我们管理后台类的项目目前就是类似 4 的方案,因为枚举前端大概率还是要存一份的,比如表单下拉搜索这种,不过都是业务需要动态创建的枚举,静态的那种没必要

    前端组件做优化,防抖+缓存,相同枚举接口短时间内不会重复请求,根据变动频率设置缓存时间
    chenuu
        32
    chenuu  
       2 天前
    @JsonValue
    public Object toJson() {
    return new EnumJson(this.ordinal(), this.name(), this.desc);
    }
    ShirOvO
        33
    ShirOvO  
       2 天前
    用反射,以前写过一个通用返回枚举的接口,传参枚举名,在后端找到对应的类,通过反射实现获取枚举值
    Nitsuya
        34
    Nitsuya  
       2 天前
    4 + swagger 会生成使用 Key 对应的名称.
    前端只需要用组件 把 key 和值传进去..
    guanhui07
        35
    guanhui07  
       1 天前
    没银弹 一般都 1 然后写好接口文档
    blessingcr
        36
    blessingcr  
       1 天前
    4
    设计一个字典表,支持在管理后台修改,其他需要的页面传参拉取对应的字典枚举就行了。
    scalpel666
        37
    scalpel666  
       1 天前
    用字典表,后端只需要返回数字就行,前端对应的字段只需要绑定字典编码直接查字典表转换就行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5051 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 09:27 · PVG 17:27 · LAX 01:27 · JFK 04:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.