日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

lombok 的bug?lombok 导致 springmvc 使用 @RequestBody注解 接收 json数据 对象参数绑定失败

發(fā)布時間:2023/12/10 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lombok 的bug?lombok 导致 springmvc 使用 @RequestBody注解 接收 json数据 对象参数绑定失败 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

大家好,我是烤鴨:
?? ?lombok 導致 springmvc 使用 @RequestBody注解 接收 json數(shù)據(jù) 對象參數(shù)綁定失敗。
?? ?環(huán)境版本:
?? ??? ?spring 5.x

1. 場景復現(xiàn)


?? ?問題出現(xiàn)在創(chuàng)建對象的屬性名稱。比如我有一個類中的屬性值是?
?? ?String aTest;

?? ?首字母小寫,第二個字母大寫。
?? ?lombok 生成的get/set 方法是 getATest/setATest。
?? ?而依據(jù)java的規(guī)范(用各種ide生成的get/set方法) 應該是 getaTest/setaTest。

2. 問題猜測

? ? lombok 生成的方法不符合 JavaBean get/set 規(guī)范,導致mvc 無法封裝進入對象。
?? ?嘗試 form表單提交的方式 是沒有問題的。
?? ?問題在于json 的方式。或者說在于json序列化和反序列化時。
?? ?spring json的包 默認使用的 com.fasterxml.jackson
?? ?可以看一下 com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap
?? ?的 _findWithAlias 方法,如圖:

?? ?BeanPropertyMap 獲取到類中的屬性是 atest,而前臺傳入的key是 aTest,無法匹配。
?? ?將 前臺傳參改為

?{"atest":"1","age":"2"}

? 就可以匹配上了。

3.解決


?? ?不使用lombok 或者 重寫 get/set方法
?? ?或者 不使用 com.fasterxml.jackson 序列化,使用 fastjson

? ? 看下有人提出過issue,而作者也提出了解決辦法。
?? ?https://github.com/rzwitserloot/lombok/issues/1661
? ??

? ??

4.深入源碼看一下


?? ?首先分析一下 com.fasterxml.jackson。

? ??org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver

? ??

protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter parameter,Type targetType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {// ... 省略// 關鍵點部分 1 body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse) :((HttpMessageConverter<T>) converter).read(targtestlass, msgToUse));// ... 省略 }

后邊調(diào)用的就是 ?BeanPropertyMap 的find 方法。

? ? 再看一下 com.alibaba.fastjson
?? ?通過修改 默認 json解析器。原來 AbstractJackson2HttpMessageConverter ?改為 ?FastJsonHttpMessageConverter
?? ?com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer
?? ?的 deserialze 方法。
?? ?可以看到 fastjson 將原來的屬性 放到 fieldinfo 中。后續(xù)操作的的都是fieldinfo 對象。

??

5. 測試


前面寫的還不夠清晰,我們可以寫個簡單的test方法自己測一下。

ATest.java

package com.test.test.test;import lombok.Data;@Data public class ATest{String aTest;String age;}

TestJson.java

package com.test.test;import com.alibaba.fastjson.JSONObject; import com.test.controller.test.ATest; import org.junit.Test;import java.util.HashMap;public class TestJson{@Testpublic void testJson() {HashMap<Object, Object> hashMap = new HashMap<>();hashMap.put("aTest","111");hashMap.put("age","111");ATest test = JSONObject.parseObject(JSONObject.toJSONString(hashMap), ATest.class);System.out.println("fastjson=================="+test);ATest o = (ATest) net.sf.json.JSONObject.toBean(net.sf.json.JSONObject.fromObject(hashMap), ATest.class);System.out.println("net.sf.json=================="+o);} }

可以發(fā)現(xiàn),fastjson 反序列化話的對象是正常的。
net.sf.json 是不行的。
net.sf.json 使用的是 org.apache.commons.beanutils.PropertyUtilsBean
getPropertyDescriptors?
beanInfo.getPropertyDescriptors();
可以看到獲取到的 beanInfo 的 propertyName 是 ATest。

事實證明, lombok ?這波操作確實有點問題,起碼不兼容市面上大部分的json包。


總結:


最開始以為是mvc 無法封裝 的問題,后來發(fā)現(xiàn)跟lombok有關(首字母小寫、第二個字母大寫時的get/set方法生成方式)
form表單提交沒問題,發(fā)現(xiàn)跟json有關(序列化/反序列化)
再換了幾個常見的json包。
fastjson 沒問題,net.sf.json 和 jackson 都不行
lombok 這波操作就是逆規(guī)范的,沒什么好說的。如果非要這種命名的話,建議重寫get/set 方法。

總結

以上是生活随笔為你收集整理的lombok 的bug?lombok 导致 springmvc 使用 @RequestBody注解 接收 json数据 对象参数绑定失败的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。