美文网首页
springboot bug实例8 :javaBean的规范导致

springboot bug实例8 :javaBean的规范导致

作者: 凉风拂面秋挽月 | 来源:发表于2019-11-20 21:18 被阅读0次

    在springboot项目中,通过@RequestBody来将json数据封装成JavaBean的时候出现了问题。我在用JavaBean去接收Json参数的时候,有个字段首字母大写了,如下图:然后发现在请求的时候无论我传入什么值,这里的DustData始终为null。

    image.png

    最开始的时候,怀疑是前端没有传过来这个值(但除了它,所有的值都正确获取并封装成javabean)于时采用@RequestBody Map<String,Objerct> result的方式接收json,并在第一时间将其打印在控制台,发现DustData并不为空?那么现象就很有意思了,json数据完整的传到了springboot服务器上,@RequestBody封装了除了DustData的所有属性,就是不封装它。
    我们来看下前端发来的json数据和服务器相应的javabean


    image.png
    public class Result {
        private String notifyType;
        private String deviceId;
        private String gatewayId;
        private String requestId;
        private Service service;
        //get/set/toString方法略。。
    }
    
    public class Service {
        private String serviceId;
        private String serviceType;
        private String eventTime;
        private Data data;
    //get/set/toString方法略。。
    }
    
    public class Data {
        private String DustData;
    //get/set/toString方法略。。
    }
    

    在一开始并没有意识到是属性名导致的封装失败,而是怀疑是由于DustData位于json嵌套的最内层而导致的错误,但查阅资料并没有发现@RequestBody封装多层嵌套的json导致最内层数据无法封装,于时只能自己动手验证了,我在最内层的json中又嵌套了一个Data2,其中有一个view属性,这样DustData就不是最内层了,我想看到的结果是view为空,DustData有值,这样就可以提交一个springboot的bug(想多了)。
    结果却是DustData依然没有值,而view被封装了。


    image.png

    虽然没有成功,但问题的答案已经很接近了,我尝试把DustData改为小写,成功被封装。

    原因

    这是由于JavaBean的规范导致的。一般JavaBean属性都是首字母小写,以驼峰命名格式命名,相应的 getter/setter 方法是 get/set 接上首字母大写的属性名。例如:属性名为clientId,其对应的getter/setter 方法是 getClientId/setClientId。
    那么如果实际中一定要用首字母大写的字段怎么办呢?我们可以直接在JavaBean的对应字段上加上@JsonProperty注解,如下:

         @JsonProperty("DustData")
        private String DustData;
    

    通过测试,也能获得正常的值。

    所以要注意规范啊以后定义json字段的同事们啊,体谅下javaer的规矩吧。

    ps:javabean规范

    1.第二个字母为大写的属性名要区别对待。如果属性名的第二个字母是大写的,那么该属性名直接用作 getter/setter 方法中 get/set 的后部分,就是说大小写不变。

    2.属性是首字母大写,次字母小写是,你永远都找不到它的 getter/setter 方法的。

    3.对于 boolean 类型属性的 getter 方法是 isXxx() 还是 getXxx() 就自己决定了,isXxx() 应该更接近于自然语言,更顺溜些。

    一般JavaBean属性以小写字母开头,驼峰命名格式,相应的 getter/setter 方法是 get/set 接上首字母大写的属性名。例如:属性名为userName,其对应的getter/setter 方法是 getUserName/setUserName。

    但是,还有一些特殊情况:

    1、如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中 get/set 的后部分,就是说大小写不变。例如属性名为uName,方法是getuName/setuName。

    2、如果属性名的前两个字母是大写(一般的专有名词和缩略词都会大写),也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为URL,方法是getURL/setURL。

    3、如果属性名的首字母大写,也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为Name,方法是getName/setName,这种是最糟糕的情况,会找不到属性出错,因为默认的属性名是name。

    4、如果属性名以"is"开头,则getter方法会省掉get,set方法会去掉is。例如属性名为isOK,方法是isOK/setOK。

    需要注意的是有些开发工具自动生成的getter/setter方法,并没有考虑到上面所说的特例情况,会导致bug的产生。

    我们在定义JavaBean的属性名时,应该尽量避免属性名的头两个字母中任意一个为大写以及属性名以"is"开头。

    相关文章

      网友评论

          本文标题:springboot bug实例8 :javaBean的规范导致

          本文链接:https://www.haomeiwen.com/subject/ljeaictx.html