Java 中使用枚举参数,如何进行 JSR303 校验意外值? 或者说参数是否直接使用枚举类型 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
daiwenzh5
V2EX    Java

Java 中使用枚举参数,如何进行 JSR303 校验意外值? 或者说参数是否直接使用枚举类型

  •  
  •   daiwenzh5 2022-08-05 15:22:32 +08:00 2911 次点击
    这是一个创建于 1163 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Java 中使用枚举参数,如何进行 JSR303 校验意外值?

    如题,使用枚举直接接收参数,使用 json 反序列化,对于意外值会接收成 null ,此实际的参数已经丢失了,只能判断是否为 null 。

    enum Sex { MALE(1), FEMALE(0) } 

    像这样的枚举值,如果参数为 2 、3 或其他任意值,在不进行自定义序列化时,接收会报错,但是自定义序列化后,只有 null 以及合法枚举。

    预期的目标,使用参数校验,提示“性别可选值 [ 1 ,0 ] ”。

    使用原始类型接收,可以实现,但如何直接使用枚举类型实现。

    现在测试结果,可以在运行时动态添加一个 UNKNOWN 类型的枚举值,用于映射非预期值。

    但感觉太重了。

    或者换个问题,参数使用原始值,还是枚举值较好

    18 条回复    2022-08-06 17:48:37 +08:00
    RainCats
        1
    RainCats  
       2022-08-05 15:31:20 +08:00
    前端直接传数字进来的话,反序列化不是根据你定义的 code 值,是根据枚举的 ordinal ,也就是从零开始的次序来找的枚举。你得自己重写枚举反序列化的东西才行
    ql562482472
        2
    ql562482472  
       2022-08-05 15:33:47 +08:00
    用“ MALE”“ FEMALE” 拒绝数字定义
    sulinwork
        3
    sulinwork  
       2022-08-05 19:25:45 +08:00
    可以定义一个枚举的统一接口 在写一个枚举的 json 适配器就行了
    itechify
        4
    itechify  
    PRO
       2022-08-05 20:39:30 +08:00 via Android
    用字符串接受,值是 enum.name(),就是字面上定义的字符串,另外,值对不上 springboot 用 jackson 反序列化默认会报错
    mmdsun
        5
    mmdsun  
       2022-08-05 22:03:14 +08:00
    jsr-303 可以自定义校验注解,自己写个就好
    daiwenzh5
        6
    daiwenzh5  
    OP
       2022-08-05 23:46:14 +08:00
    @sulinwork 这样用校验器就没法区分出非预取值了,因为匹配不上的就被转成 null 了
    daiwenzh5
        7
    daiwenzh5  
    OP
       2022-08-05 23:48:41 +08:00
    @oneisall8955 用原始值感觉不够优雅,正是如此才会想要讨论一下
    liuzhaowei55
        8
    liuzhaowei55  
       2022-08-05 23:56:09 +08:00 via iPhone
    自己手写一个 validator 可以校验 enums ,然后如果用 jackson 可以使用 @jsonvalve 注解加在 enums 属性上来指明反序列化的字段
    itechify
        9
    itechify  
    PRO
       2022-08-06 00:45:07 +08:00 via Android
    @daiwenzh5 每个人有每个人的理解,举个例子,搜索引擎枚举,前端传递 BAIDU,GOOGLE,SOUGOU ,比 0 ,1 ,2 更优雅。

    另外,技术上当然可以做自定义序列化反序列化,你想要的都可以,不过得区分 fastjson ,jackson ,gson 等 json 工具,因为哪天不知道某个同事用的工具不支持被吐槽
    daiwenzh5
        10
    daiwenzh5  
    OP
       2022-08-06 00:59:41 +08:00
    @oneisall8955 不是序列化的问题, 而是同时使用枚举入参,并且注解校验,目前我了解的是无法做到的,因为序列化在前,没有的值,就成了 null
    panxiuqing
        11
    panxiuqing  
       2022-08-06 07:20:09 +08:00 via Android
    如果用枚举类型接收,为什么要知道意外值?
    ymmud
        12
    ymmud  
       2022-08-06 09:03:59 +08:00
    在原始 class 上使用枚举,对外使用原始值。 json -> vo -> 原始 class
    itechify
        13
    itechify  
    PRO
       2022-08-06 10:41:18 +08:00 via Android
    @daiwenzh5 那,直接在反序列化 throw ?不也能达到校验效果?
    tairan2006
        14
    tairan2006  
       2022-08-06 11:17:22 +08:00
    你直接用枚举接受,然后在字段上加一个 @NotNull 就行……
    mossrock
        15
    mossrock  
       2022-08-06 13:17:41 +08:00
    @JsonEnumDefaultValue
    UNKNOWN(-1, "未知");
    用这个?不确定是不是这个场景
    read_unknown_enum_values_using_default_value
    daiwenzh5
        16
    daiwenzh5  
    OP
       2022-08-06 17:41:15 +08:00
    @tairan2006 #14 NotNull 只是非空校验,如果允许为空呢?可以不填,但是填了必须在可选范围内的这种
    daiwenzh5
        17
    daiwenzh5  
    OP
       2022-08-06 17:43:11 +08:00
    @mossrock #15 这种的我考虑过,但是需要在枚举中手动设置一个“未知”枚举项了,如果做团队通用设计的话,通过人工约束也不太好,枚举又不能自定义抽象类,所以我在描述中也说了,测试了反射动态添加 UNKNOWN 枚举值。
    daiwenzh5
        18
    daiwenzh5  
    OP
       2022-08-06 17:48:37 +08:00
    @oneisall8955 #13 额,实际上对于单个入参异常是无所谓,但是对于批量的情况下,我是想要知道那些数据是正确的,哪些是错误的,此时异常的话就终止了,目前看来,好像是只有用 String, Interge 这种原始类型,去映射枚举的 name ,或者 code 比较好一点,用反射动态写入枚举值,感觉挺怪的。
    这个问题是最近在做 Excel 导入时想到的,想做成一个通用的自动校验。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1751 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 00:01 PVG 08:01 LAX 17:01 JFK 20:01
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86