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

Java 加一个字段很难吗?

  •  2
     
  •   liuidetmks · 2021-09-26 17:24:13 +08:00 · 10742 次点击
    这是一个创建于 914 天前的主题,其中的信息可能已经有所发展或是发生改变。

    传输数据 加一个字段非常麻烦, 甚至同一种结构,从 xml 换成 json 返回,就会改动非常大?

    难道 java 就没用一种通用的 map 结构表示 字典吗? 加个东西总是有很大抵触?

    例如 一个 map

    {
       ....
    }
    

    在使用的时候 按需取值
    var a = map['a']
    var b = map['b']
    或者从页面 A 直接传一个 map,A 页面不需要关注到底 map 有什么(服务器返回) 到 B 页面, B 页面按需取用。

    第 1 条附言  ·  2021-09-26 18:17:59 +08:00

    v友说的map 火葬场,对于稳定的业务,只和自己服务器交互的,当然不推荐map了
    但现实是,由于项目原因,接口需要不断适应变化, 唯一不变的就是接口随时会变.

    需要尽量在不发版的情况下,完成需求(一般是修复bug,即使当时测试OK了,由于其他原因,接口要变动).
    例如,一些字段需要透传,方便server端进行处理。

    为此引入了脚本预处理数据
    app 把数据交给 脚本预处理,然后回传到native ,然后再发送给server。
    这个过程中,第一步的情况,app 把数据交给脚本,A端就很死,加一个参数就很麻烦,尤其是跨页面想加多个参数时候,失去了很多灵活性

    90 条回复    2021-10-09 18:14:29 +08:00
    oldroot
        1
    oldroot  
       2021-09-26 17:29:18 +08:00
    你好有的 @RequestBody Map<String,Object> map
    zzfer
        2
    zzfer  
       2021-09-26 17:30:18 +08:00
    没看懂你说什么,我只知道 Java 加字段很简单
    liuidetmks
        3
    liuidetmks  
    OP
       2021-09-26 17:30:22 +08:00
    @oldroot 那为什么从 xml 切换到 json 格式 也有很大难度呢?
    AllenHua
        4
    AllenHua  
       2021-09-26 17:30:43 +08:00   ❤️ 29
    来了来了,用 map 传参,🐶️
    HanLi2021
        5
    HanLi2021  
       2021-09-26 17:31:02 +08:00
    这不是语言的问题,这是沟通的问题。

    1 java 当然有 map
    2 改动抵触大是不是前期没有沟通好接口?
    Tenma
        6
    Tenma  
       2021-09-26 17:31:12 +08:00   ❤️ 1
    Map 当然是有,但是如果全部是 map,项目大了就是地狱,你不知道每个接口到底返回什么,也很难区分每个 key 代表什么意思。除非你们是有标准的接口定义文档,但是如果是有标准文档,那就不会出现随便添加 key 值的操作。
    Jooooooooo
        7
    Jooooooooo  
       2021-09-26 17:32:01 +08:00   ❤️ 40
    5 年后的你发明了时间机器, 穿越回现在, 杀死了那个用 map 传参的你.
    hcen1997
        8
    hcen1997  
       2021-09-26 17:32:31 +08:00   ❤️ 1
    动态一时爽, 重构火葬场
    没有编译器的类型系统提示, 就要靠你自己了解接口定义了
    yuhangch
        9
    yuhangch  
       2021-09-26 17:36:39 +08:00
    @Jooooooooo 绝了
    ytll21
        10
    ytll21  
       2021-09-26 17:38:59 +08:00
    同一种结构,从 xml 换成 json 返回,就会改动非常大? => Why? 有例子可以看看吗?
    BBCCBB
        11
    BBCCBB  
       2021-09-26 17:40:11 +08:00
    谁给你说的很难?
    JsonSnowNothing
        12
    JsonSnowNothing  
       2021-09-26 17:44:01 +08:00   ❤️ 3
    上家公司,项目里全是 map 入参出参,我真的想杀了之前的开发
    x940727
        13
    x940727  
       2021-09-26 17:45:30 +08:00   ❤️ 5
    加一个字段不难,难得是加数据对象字段,加实体类字段,加判断逻辑,加查询条件,加数据库字段,清洗现有数据,回归测试。
    anzu
        14
    anzu  
       2021-09-26 17:53:41 +08:00
    可以用 Map,但后果其他人说了。
    一般是每一种数据结构定义一个 class,而这个 class 可能被用于其它 class,或被用于多个接口,随便加字段容易变屎山。
    比较烦的地方在于,如果结构不能兼容,需要另外定义一套新结构,而新旧结构只有细微差别,于是折腾出废话般的 vo po do dto,写到吐
    Macolor21
        15
    Macolor21  
       2021-09-26 17:53:42 +08:00
    groovy 好像可以做你说的事,我之前一个项目里,是 JSON 格式-> 通过 JsonPath ?好像是,反正是 groovy -> JAVA 对象。
    就是这种 obj[field] 的写法,我没深入看这一段。
    lix7
        16
    lix7  
       2021-09-26 17:54:09 +08:00
    哈哈哈 用 Map 传参还不如索性直接动态语言走起
    xaplux
        17
    xaplux  
       2021-09-26 17:56:06 +08:00   ❤️ 13
    盲猜,楼主是个前端,想要后端加个字段,后端不给加,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
    lyog
        18
    lyog  
       2021-09-26 17:56:33 +08:00 via iPhone
    我手头这项目是要么 map 入参出参,要么 json 转成 string 入参出参,整个项目没有一个 Bean,我真是服了
    hsymlg
        19
    hsymlg  
       2021-09-26 17:58:38 +08:00
    作为强类型语言,在 java 工程里最好不要用 map 传参。出参对象要是多处复用的话,确实会有影响,通常建议每个 response 一个对象
    xsqfjys
        20
    xsqfjys  
       2021-09-26 17:58:59 +08:00
    map 传参也就算了,同一个接口不同实现同一个参数用的 key 还不一样,真的想杀人
    lakehylia
        21
    lakehylia  
       2021-09-26 18:01:48 +08:00
    c++表示,参数结构里面都会带个 char reserved[128]; 就怕楼主这样的人 [狗头]
    tommyzhang
        22
    tommyzhang  
       2021-09-26 18:03:32 +08:00
    十大傻逼行为之首 mapv 传参
    xuanbg
        23
    xuanbg  
       2021-09-26 18:04:04 +08:00
    加字段简单得很呐
    thetbw
        24
    thetbw  
       2021-09-26 18:05:41 +08:00
    加一个字段应该是个很谨慎的吧,要么就是你们产品经常改需求,要么就是你数据建模太烂
    dqzcwxb
        25
    dqzcwxb  
       2021-09-26 18:09:42 +08:00
    十大傻逼行为之首 应当是数组传参,二是 map 传参
    sujin190
        26
    sujin190  
       2021-09-26 18:15:43 +08:00
    @Jooooooooo #7 但是真实现实版应该是半年后项目黄了。。
    BrettD
        27
    BrettD  
       2021-09-26 18:25:57 +08:00 via iPhone
    你一定会后悔的
    scxiazi
        28
    scxiazi  
       2021-09-26 18:38:17 +08:00
    为啥要用 map 呢, 还为啥要不同的页面数据放一个接口里
    Kilerd
        29
    Kilerd  
       2021-09-26 18:50:08 +08:00
    怎么那么多楼了还没见到 apijson 啊,这个库是凉掉了吗
    msg7086
        30
    msg7086  
       2021-09-26 19:02:25 +08:00
    用 Map 说白了就是全员无类型。你用 Java 就是为了用他的严谨,用他的类型系统。你那么喜欢用 Map 为什么不去用 PHP Python Ruby 之类的呢。(不过就算是在脚本语言里也有用对象来代替 Map 的倾向。)
    dwlovelife
        31
    dwlovelife  
       2021-09-26 20:44:25 +08:00
    @Macolor21 groovy 也只不过是一种跑在 JVM 之上的语言,简化了语法,算个动态语言,但是像楼主说的这种接口字段从头到尾自适应,不是语言的问题,这是设计方面的问题
    darkengine
        32
    darkengine  
       2021-09-26 20:48:47 +08:00
    照这么说还传啥 map 啊,直接一个 json string,万一业务发展又需要数组了呢 。。。 [滑🐔
    ntop
        33
    ntop  
       2021-09-26 20:49:39 +08:00
    class FinalEntity {
    Map data;
    }
    两全其美,哈哈哈
    dwlovelife
        34
    dwlovelife  
       2021-09-26 20:50:42 +08:00
    楼主你说的这种后台的入参在确实不确定的情况下,完全适应入参,只能采用 map 结构去接收,但是确确实实违法规范,即使使用 map 接受,你每进行一次业务变更添加或者修改一个字段(可能很频繁),后台是一点业务逻辑不需要处理么,那应该不现实,但凡有逻辑要处理用 map 和不用 map 那已经不重要了,因为无非是改一个地方还是改好多地方的问题,但是某些业务场景还是有方案去解决的,单纯的透传后端可能通过使用 map 去兼容你,但是如果大部分字段都和业务紧密相关需要做额外业务操作,那么用 map 和不用 map 没啥大区别
    LowBi
        35
    LowBi  
       2021-09-26 20:51:51 +08:00 via Android
    不懂就问,我有个公共类方法,需要不同的实体类传进来,但是不知道怎么传到这个公共方法里,于是就用 map,把要传的字段先 put 进去,作为参数直接把 map 传过去,公共方法里再 get,取得字段都一样,就是有好几个不同实体类
    Leviathann
        36
    Leviathann  
       2021-09-26 21:06:14 +08:00
    @LowBi 把那几个字段的 get 方法抽成一个接口 A,让各个 entity 都实现一下,方法签名就写 <T extends A>
    darkengine
        37
    darkengine  
       2021-09-26 21:08:00 +08:00
    @LowBi 把这些参数丢到一个类里,用这个类的实例作为参数
    jiom
        38
    jiom  
       2021-09-26 21:12:57 +08:00
    重构火葬场~
    fkdog
        39
    fkdog  
       2021-09-26 21:36:53 +08:00   ❤️ 1
    见过太多的项目从底向上 entity 、domain 、dto 、vo.......

    如果项目里有用到 mongodb 、es 的 mapping 类,那么一张表就可能拉出个 5 、6 个 pojo,从最下边的 entity 字段一直浮到最上边的 dto 或者 vo 。。。。

    不过大部分问题还是软件开发者本身的问题。
    加字段这种东西不管怎么说还是很 ez 的,后端不愿意加往往是因为你需要的字段前端也能计算出来没必要推给后端。
    碰到这种前后端都能做的东西,只能看心情决定了。
    HongJay
        40
    HongJay  
       2021-09-26 21:49:20 +08:00
    属实离谱,不知道 java 是强类型语言么
    gouflv
        41
    gouflv  
       2021-09-26 23:43:25 +08:00 via iPhone
    用 map 这么简单的话,还要 java 何用
    cubecube
        42
    cubecube  
       2021-09-27 00:05:47 +08:00
    @LowBi 定义一个接口不就解决了?
    witcherhope
        43
    witcherhope  
       2021-09-27 00:23:54 +08:00 via iPhone
    你这是在做工程么,也太不严谨了,先不说 Java 加字段很方便,为了你所谓的灵活抛弃 Type-Safe 特性属于脑残行为,后期重构和测试以及定位问题的代价会极其大。
    br00k
        44
    br00k  
       2021-09-27 00:47:46 +08:00
    用了 ts 全是 any 的感觉。
    zerofancy
        45
    zerofancy  
       2021-09-27 00:59:37 +08:00 via Android
    和楼主思想不一样,我们接口返回类型定义在 proto 文件,在一个独立的仓中,真正的客户端实体类由它编译过来,谁也别乱改接口。
    DreamSpace
        46
    DreamSpace  
       2021-09-27 08:24:16 +08:00 via Android
    1. 加字段简单,但是 pojo 多了会很麻烦。如果要加的字段可以算出来或者是用于控制视图逻辑那后端不愿意加也正常。
    2. 如果需要单个接口返回 xml,后端在解析器和反序列化器配置到位的情况下不用动任何代码,只需要前端在发送请求时声明自己需要 application/xml 即可
    mmdsun
        47
    mmdsun  
       2021-09-27 08:34:02 +08:00 via Android
    jsonview 了解一下。spring 可以做 json 视图
    mmdsun
        48
    mmdsun  
       2021-09-27 08:35:08 +08:00 via Android
    @Kilerd 那人去腾讯就没推广了。这个库现在是腾讯的顶级开源项目。
    inhzus
        49
    inhzus  
       2021-09-27 08:53:39 +08:00 via iPhone
    楼主这得是什么快速迭代?一天一发版?迭代多快的项目我都没听说过用 map 传参(搞算法不懂工程的除外
    zhennann
        50
    zhennann  
       2021-09-27 09:26:59 +08:00
    加字段不难,就是让后端加字段有点难。接口一旦确定下来,后端是最讨厌变更的。当然我说的是 java 后端。
    为啥 nodejs 会火起来,就是因为灵活,改动起来很快。但现在又在鼓吹 ts,然后慢慢又回到不愿改接口的老路。
    bk201
        51
    bk201  
       2021-09-27 09:30:02 +08:00
    加起来倒不是很难,但是开了这个口子,就无休止的变更就很烦。
    CaffreySun
        52
    CaffreySun  
       2021-09-27 09:34:22 +08:00
    我讨厌 js 的原因就是它到处都是 Map,到处都是不知道类型的对象。
    拿到一个参数,我不知道它是啥,是不是我想要的类型,它会不会是 null 或者 undefined,所以我比较喜欢 ts 。
    对于后端来说 Map 同样让人讨厌,不知道 Map 里有啥,有没有想要的参数,无法交验参数的类型对不对。
    neptuno
        53
    neptuno  
       2021-09-27 09:35:19 +08:00
    破窗效应?你这是给后人留坑呀,而且业务做大之后,想重构就麻烦了,不是不发版就不会出错,大胆创新小心求证嘛。
    Kilerd
        54
    Kilerd  
       2021-09-27 09:54:22 +08:00 via iPhone
    @mmdsun 也挺好,靠一个“顶级”开源进了腾讯。可是最后怕不是又要变成 kpi 式开源了
    wangxin13g
        55
    wangxin13g  
       2021-09-27 10:02:01 +08:00
    这么喜欢 map 为什么不用 php +1
    从 php 换 java 的主要原因就是看不惯这种薛定谔的 map
    aitaii
        56
    aitaii  
       2021-09-27 10:23:24 +08:00
    用 Object 最好
    wqhui
        57
    wqhui  
       2021-09-27 10:27:22 +08:00
    用 map 传东西,改了几版后谁也不知道这 map 里面会有什么
    QGLNepal
        58
    QGLNepal  
       2021-09-27 10:27:32 +08:00
    json schema
    8e47e42
        59
    8e47e42  
       2021-09-27 10:54:11 +08:00
    @CaffreySun TS 可破,不然 flow ?
    mightofcode
        60
    mightofcode  
       2021-09-27 11:07:29 +08:00
    不难
    改成 map 就完事了
    cw2k13as
        61
    cw2k13as  
       2021-09-27 11:41:58 +08:00
    @xaplux 不加就不加被,领导问为啥没这个数据,后端说他加不了,
    lonenol
        62
    lonenol  
       2021-09-27 13:11:55 +08:00
    如果只是加字段其实是非常简单的。。
    但是 xml 的表达能力要远远强于 json 。。想直接转 json 其实是有点难的
    zjsxwc
        63
    zjsxwc  
       2021-09-27 13:29:06 +08:00
    Map 重构火葬场吗?

    我觉得使用 map 很正常啊,

    就和我写了个接口 interface,你穿过来一个实现 interface 的对象一样正常,只有在重构时我才关心(全局搜索)这个穿过来的对象到底是具体哪个类。
    同样的,我由于接口业务问题,我只知道这是个有某些参数的请求数据,后期可能会变,于是我用了 map, 方便后期维护,至于维护时我才关心(全局搜索)这个穿过来的 map 到底有哪些 key 。

    有没有问题?

    没有问题。
    zjsxwc
        64
    zjsxwc  
       2021-09-27 13:34:50 +08:00 via Android
    总不能说我为了灵活性,用了 interface 没写具体类,就火葬场了吧
    ccppgo
        65
    ccppgo  
       2021-09-27 14:03:36 +08:00
    @zjsxwc interface 限定了返回类型, 方法名, 参数列表, map 有限定什么东西吗, 你应该用 object 举例
    py2ex
        66
    py2ex  
       2021-09-27 14:26:13 +08:00
    #37 说得很客观了,就是都能做,贴主想把工作量甩给后端
    tedzhou1221
        67
    tedzhou1221  
       2021-09-27 14:30:14 +08:00
    自从来了一家公司,发现项目都是用 map 之后,我天天都在无猜迷,猜这个接口入参是什么、出参是什么。
    zjsxwc
        68
    zjsxwc  
       2021-09-27 14:42:45 +08:00
    @ccppgo

    用 interface 举例和 object 一样的,

    比如 1 个 interface 有 50 个 implement,这 50 个 implement 之间可能是 proxy 、adapter 、decorator 等的套娃实现,你不能在维护时立马知道具体用了哪个。
    clf
        69
    clf  
       2021-09-27 14:55:34 +08:00
    前后端应该严格按照接口定义来做。我宁愿在请求传入的类里加参数也不愿意用 Map 。
    hingbong
        70
    hingbong  
       2021-09-27 16:09:03 +08:00
    @zjsxwc 用接口,如果是 Jackson 序列化 /反序列化可以配置 JsonSubTypes,能够固定一个字段区别是哪个实现,如果混在代码逻辑里面判断就不好找吧,能够固定在一个字段总是能够直观一些
    pkoukk
        71
    pkoukk  
       2021-09-27 16:15:44 +08:00
    @zjsxwc
    用 nodejs 写几个后端项目就知道了,在一个无类型的环境下,变量传个三四层你就不知道它里面是个什么玩意了,只能开调试步进,一步步看,维护难度极高。
    pkoukk
        72
    pkoukk  
       2021-09-27 16:27:22 +08:00
    看到你的需求仿佛看到了之前公司惨烈的项目
    一开始,某些字段只需要透传即可,不需要后端处理,ok,上了 map
    然后,前端拿这些参数加入了页面跳转逻辑中,完美
    做着做着,新场景下,某些透传字段的可能为空,前端一下就崩了
    好嘛,还不是得后端帮擦屁股,开始处理 map 里的这些破数据
    一开了这个口,没完没了,干脆整个接口全是 map 了
    zjsxwc
        73
    zjsxwc  
       2021-09-27 16:27:28 +08:00
    @pkoukk 我们说的不是同一个问题,
    况且你的问题可以用 jsdoc 解决 https://jsdoc.app/tags-property.html#examples
    pkoukk
        74
    pkoukk  
       2021-09-27 16:29:53 +08:00
    痛定思痛,结论就是,加参数虽然可能很简单,但你不能认为他简单,不能完全不考虑架构,什么需求全靠加参数解决。
    加到最后,代码里一万个参数,没人知道哪些有用哪些没有,数据库里一堆垃圾数据,没人敢动。
    pkoukk
        75
    pkoukk  
       2021-09-27 16:39:51 +08:00
    @zjsxwc
    emm..看了下你的回答,好像你的 map 和楼主说的 map 也不是一回事。
    因为楼主说的是 “在不发版的情况下完成需求”,实际想表达的是只把后端当存储,后端不会对任何字段进行检查或处理。这显然是不合理的,因为后端必须要对需要保存的字段进行检查和校验来避免恶意行为。
    Bisyfish
        76
    Bisyfish  
       2021-09-27 17:09:11 +08:00
    存储过程加 map 就完事了 。。。存储过程加字段直接返回。
    ptaooo
        77
    ptaooo  
       2021-09-27 17:18:06 +08:00   ❤️ 1
    你们根本不知道用 String 接收参数,再转成 JSONObject 的项目有多恐怖
    mawerss1
        78
    mawerss1  
       2021-09-27 17:24:36 +08:00
    淘宝订单表加个字段应该挺难的吧
    IronProp
        79
    IronProp  
       2021-09-27 19:09:06 +08:00
    你以为是技术问题. 却不知这是人情世故 [狗头]
    `难道 java 就没用一种通用的 map 结构表示 字典吗? 加个东西总是有很大抵触?`
    seliote
        80
    seliote  
       2021-09-27 19:55:34 +08:00
    维护过这样的代码,不通读代码根本不知道他写的什么
    Oktfolio
        81
    Oktfolio  
       2021-09-28 09:40:21 +08:00
    @ptaooo 杭州健康码第一行代码不就是用 String 接的吗?
    2i2Re2PLMaDnghL
        82
    2i2Re2PLMaDnghL  
       2021-09-28 10:28:23 +08:00
    如果你已经用上 doc db 了就别 Java 了。

    @pkoukk 后端仅存储也不是没有,firebase 好像就是这类吧(没用过
    james122333
        83
    james122333  
       2021-09-28 11:04:29 +08:00 via Android
    我也爱用字典 因为不爱看到一堆类别 而且还是命名乱糟糟的类别 而且如果有很多複杂继承关係要改非常多 容易搞混功能 宁愿 map 外包层 wrapper 重点在于减轻心智负担 换个方法思考方式 map 也非常好用
    hhjswf
        84
    hhjswf  
       2021-09-28 13:52:09 +08:00
    Map...也行吧,不管用 Bean 还是 map 反正都要做文档维护,差别不算特别大
    FawkesV
        85
    FawkesV  
       2021-09-28 15:14:19 +08:00
    哈哈 map 传参远远没有 PHP 中的数组来的恐怖...
    RainCats
        86
    RainCats  
       2021-09-28 17:03:20 +08:00
    加一个字段很难吗?这句话令我想起之前产品说的小改动:将金额改成应用内的某种货币,很难吗,不就是改个字段吗,不就是改个字段吗????
    是的没错,就是改个字段,可是你知道后面要改多少东西吗。。。
    tctc4869
        87
    tctc4869  
       2021-09-28 19:58:59 +08:00
    @ptaooo 接收 Body 是 json 类型用 JSONObject 不很正常吗?难道 body 是表单?然后转成 JSONObject ?
    tctc4869
        88
    tctc4869  
       2021-09-28 20:06:34 +08:00
    @zjsxwc 只用 Map 不用 Class 修饰来变量的话,时间长了,开发者自己可能都记不得某个 Map 是用来干什么了的,只能靠上下代码来推断这是什么了。

    使用 class 也有考虑使用 IDE 智能提示来增加开发效率的习惯。只用 Map 的话,开发者想要智能提示打出字段名怎么办呢?
    tctc4869
        89
    tctc4869  
       2021-09-28 20:14:20 +08:00
    @Kilerd 我说一下我对 apiJson 的看法,哪怕最简单的,也需要对数据库做配置吧(比如必须要啥数据表才能运行)。
    liian2019
        90
    liian2019  
       2021-10-09 18:14:29 +08:00
    不是很明白,接口一直在变化,那即使 controller 用 map 随便你传什么参数,那收到这些参数之后需要做的逻辑难道不需要重新开发吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3257 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 13:52 · PVG 21:52 · LAX 06:52 · JFK 09:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.