请教大佬们一个关于 springmvc 的一个简单问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
DXDE443
V2EX    Java

请教大佬们一个关于 springmvc 的一个简单问题

  •  1
     
  •   DXDE443 2018-03-26 11:58:16 +08:00 5298 次点击
    这是一个创建于 2807 天前的主题,其中的信息可能已经有所发展或是发生改变。
    @GetMapping("test")
    public void Test(Job example){
    System.out.println(example);
    }

    对于这样一个 controller,我想要接受 example 这样一个可选实体参数,我希望前台传这个参数时,我可以正常接收到这个参数,前台不穿这个参数时,我希望这个参数为 null,但 springmvc 的逻辑是,不管前台是否穿了参数,都会 new 一个对象传进来,这样我就不好判断前台是否穿了这个参数,我尝试了@RequestParam(required = false)@RequestParam(defaultValue = "null"),均以失败告终,目前临时解决办法是重写了 eqauls 方法

    if(example.equals(new Job())){
    example = null;
    }
    判断传进来的实体是否和新 new 出来的空实体 eqauls,从而判断有没有参数,但我感觉这样很 low,请教一下各位大佬有没有更优雅的解决办法
    31 条回复    2018-03-27 14:00:23 +08:00
    sorra
        1
    sorra  
       2018-03-26 14:12:01 +08:00
    可以直接调用 request 做判断,检查一下 request body 之类的
    yang2yang
        2
    yang2yang  
       2018-03-26 14:19:56 +08:00
    目的是判断前台是否传递了这个参数,既然对象一定会 new 出来,那么是不是可以判断 example 对象里面的其他字段是否为 null,进一步来判断有没有传递这个 example 这个参数
    north521
        3
    north521  
       2018-03-26 14:24:08 +08:00
    不要判断对象,判断你需要的字段即可
    LucasLee92
        4
    LucasLee92  
       2018-03-26 14:38:21 +08:00
    可以用 aop 拦截,用 Objects.equals 做判断,然后判断与 new 的一致,把输出结果变为 null
    LucasLee92
        5
    LucasLee92  
       2018-03-26 14:39:27 +08:00
    可以考虑加自定义注解和 aop 的方式来定制实现你需要的功能
    seancheer
        6
    seancheer  
       2018-03-26 14:52:21 +08:00
    判断 job 里面的字段就可以了。。不行的话自行自定 interceptor,手动将 url 映射到 controller,然后就可以实现你想要的功能了。
    mosliu
        7
    mosliu  
    nbsp;  2018-03-26 14:54:52 +08:00
    我一般采用字段判断,
    好比:Long 类型的 id,判断 id==null 就好。
    DXDE443
        8
    DXDE443  
    OP
       2018-03-26 15:22:11 +08:00
    谢大佬们回答,感觉 spring 这块设计的不太好啊,我觉得我这个需求应该很正常吧,没传参留 null,竟然挺复杂。。。实体字段比较多而且都是可选参数,特别是部分字段是基本类型(int 什么的)有默认值,通过实体判断代码不少也不太靠谱,分析 request+aop/拦截器应该是可以,但这又得造轮子了。。。想了半天感觉干脆拆成两个 controller 一个带参数一个不带参数还简单点(逃
    pmispig
        9
    pmispig  
       2018-03-26 18:36:19 +08:00
    直接对参数对象进行判断就行了,比如传一个 map 进来,你看下 map 是不是空,是空的话肯定是没传,何必固执一定要空指针...
    azygote
        10
    azygote  
       2018-03-26 19:14:56 +08:00 via iPhone
    你这里 Job 对象类似一个容器,这个对象的每个字段对应你 get 请求的键值对,这个设计很合理,因为你 get 请求传参数肯定一个参数一个参数中间加&来传的,不存在直接传一个对象过来。
    lastpass
        11
    lastpass  
       2018-03-26 19:17:33 +08:00 via Android
    没有猜错的话(没有仔细研究过 springmvc 源码),
    springmvc 也是通过反射泛型来给你进行注入的。。
    你要你这个 example 为 null。
    那在反射的时候就直接 gg 了。
    而且没记错的话 struct2 也是这样的吧。
    DXDE443
        12
    DXDE443  
    OP
       2018-03-26 20:26:54 +08:00 via Android
    @lastpass 但这里如果是 Integer 或 String 它就会很聪明的留 null,特别是我加上了 @RequestParam(required=false)后,这个 example 更迷了,无论传什么字段都为 null,但穿 example=123 就会装配到第一个字段,虽然感觉应该是个 bug 但也说明了实现应该是可能的
    zhouyou457
        13
    zhouyou457  
       2018-03-26 21:17:01 +08:00 via iPhone
    requestmapping 了解一下
    yianing
        14
    yianing  
       2018-03-26 21:46:37 +08:00
    @zhouyou457 #13 getmapping 好像就是 requestmapping,只不过方式指明了 get
    watzds
        15
    watzds  
       2018-03-27 00:37:25 +08:00 via Android
    为什么要判断 null 呢,实在需要 Test 里再加一个 bool 参数也行啊
    yanjinbin
        16
    yanjinbin  
       2018-03-27 02:09:07 +08:00 via iPhone
    没听懂,你的接口设计有问题,spring mvc 会扫描注解,装备。有
    mgcnrx11
        17
    mgcnrx11  
       2018-03-27 07:10:50 +08:00 via iPhone
    @DXDE443 字段部分不用基本类型,用包装类型。阿里的手册也是这样建议
    jorneyr
        18
    jorneyr  
       2018-03-27 08:44:00 +08:00
    这个一般用 @Valid 来验证前端是否传递了某些指定的参数
    liuzuo
        19
    liuzuo  
       2018-03-27 09:23:08 +08:00
    @RequestBody 吧?为啥是 @RequestParam
    domty
        20
    domty  
       2018-03-27 09:36:52 +08:00
    ModelAttrinbute 注解?
    Infernalzero
        21
    Infernalzero  
       2018-03-27 09:38:43 +08:00   1
    你这种情况就应该用 POST,用 GET 的场景这个对象是通过 BeanUtils.instantiateClass 创建的,所以一定会有,如果你写到 body 里就是通过 messageConverter 来转了,这样只要设置 @RequestBody(required = false)就可以了
    ululau
        22
    lululau  
       2018-03-27 09:48:31 +08:00
    自己配置 ArgumentResolver 吧
    paragon
        23
    paragon  
       2018-03-27 09:54:44 +08:00
    @domty 看了这么多 终于有正确答案了~
    lastpass
        24
    lastpass  
       2018-03-27 10:37:12 +08:00 via Android
    回复 @DXDE443 (以下均为瞎猜)你看 integer 和 string 都是可以直接赋值的呀。不需要进行反射。反射的时候你需要存在这个对象,然后找到这个对象的方法,set 值吧。所以并不是 Integer 或 String 它就会很聪明的留 null。
    LucasLee92
        25
    LucasLee92  
       2018-03-27 10:43:02 +08:00
    @Infernalzero
    大佬,想系统学习 spring,看哪本书比较好,还是说得去看源码吗?
    johnj
        26
    johnj  
       2018-03-27 10:50:35 +08:00   1
    @LucasLee92 官方文档不错
    DXDE443
        27
    DXDE443  
    OP
       2018-03-27 11:52:44 +08:00 via Android
    @mgcnrx11 我的实体类是用 idea 的 jpa 工具生成的,这个工具 not null 的字段都会被映射成基本类型,我个人没找到哪里有设置不生成基本类型,一个一个改就太麻烦了
    vjnjc
        28
    vjnjc  
       2018-03-27 12:04:05 +08:00
    #24 楼说得对,string 和 Integer 无法反射赋值,所以是 null。
    一般的 object 都是先构造,再把每个参数反射注入。
    你的情况就是构造好了后没有参数可以注入,程序结束。

    以上情况都是 @RequestMapping,你要不用 @ModelAttribute
    DXDE443
        29
    DXDE443  
    OP
       2018-03-27 12:11:01 +08:00 via Android
    @domty 试了下并没有发现有什么用额,但如果配合 requestparam(required=false)这个 example 就永远为 null 了,穿什么都不好使
    DXDE443
        30
    DXDE443  
    OP
       2018-03-27 12:18:26 +08:00 via Android
    我 requestparam 注解确实用错了,但 requestbody 那前台就要穿 json 了吧,这改动稍微有点大
    seaswalker
        31
    seaswalker  
       2018-03-27 14:00:23 +08:00
    我觉着可以尝试自定义 HandlerMethodArgumentResolver,比如继承 RequestResponseBodyMethodProcessor
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1079 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:16 PVG 02:16 LAX 10:16 JFK 13:16
    Do have faith in what you're doing.
    ubao msn 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