Dozer物件對映框架Map到JSONString對映問題排查
引言
Dozer是一個優秀的物件對映的框架,可以幫助程式設計師減少大量的物件之間對映的get/set程式碼,在ATA上有好幾篇文章介紹了dozer的使用:
dozer開發手冊
使用Dozer幫你提高開發效率(解決繁瑣的DO轉BO、TO轉BO問題) 有興趣的同學,可以去看下基本的使用。
問題
我在開發後臺系統中,經常會遇到從前臺提交的物件,轉為後臺的服務模型物件做操作,通過dozer工具,靈活的配置就可以輕易的解決。我需要將將一個物件的Map物件轉為json的字串,按照dozer的文件需要編寫自定義的Convertor來進行處理(這裡面針對欄位的轉換,,dozer支援類級別,欄位級別的Convertor. ),但測試卻發現了一些問題。具體請看例子:
源物件
public class SourceA{
private Map<String,Object> field;
//省略get/set
}
public class SourceB{
private String field;
//省略get/set
}
//dozerMapper配置
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping type="bi-directional">
<class-a>com.alibaba.xxx.SourceA</class-a>
<class-b>com.alibaba.xxx.SourceB</class-b>
<field custom-converter="com.alibaba.xxx.JsonConverter">
<a>field</a>
<b>field</b>
</field>
</mapping>
</mappings>
//自定義的Convertor
public class JsonConverter extends DozerConverter<Map,String> {
public JsonConverter(){
super(Map.class, String.class);
}
@Override
public String convertTo(Map source, String destination) {
if (source == null) {
return null;
}
return JSON.toJSONString(source);
}
@Override
public Map convertFrom(String source, Map destination) {
if (source == null) {
return null;
}
return JSON.parseObject(source);
}
}
//單元測試:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:dozer_test/test.xml" })
public class DozerBugTest {
@Resource
DozerBeanMapper dozerBeanMapper;
@Test
public void test_mapper(){
SourceA sa = new SourceA();
Map<String,Object> map = Maps.newHashMap();
map.put("losemoney", "losemoney");
clueInfo.setField(map);
SourceB sourceB = new SourceB();
dozerBeanMapper.map(sa, sourceB);
assertNotNull(sourceB.getField());
}
}
從結果上,我是期望傳入的Map物件自動可以轉為JSON的字串進行處理,但是跑了單元測試執行的結果是不通過。
分析
我在自定義的轉換器JsonConverter類的convertTo方法中加了斷點,發現了傳入的源物件是一個空值:
為什麼明明有map物件設定,到自定義轉換器哪裡就為空了。於是從dozer的map方法開始debug:
- 實際是呼叫了MappingProcessor做對映處理,
- 獲取每個欄位的值: 從斷點顯示的值看,這裡取到的就是null了。
- 問題就應該出在 srcFieldValue = fieldMapping.getSrcFieldValue(srcObj);
- FieldMap有多個物件實現類,,在這裡需要檢視MapFieldMap獲取物件。
,預設設定Map和欄位做對映的時候,會將Map作為物件,呼叫get方法,以配置的欄位名作為key獲取值,在這個場景就是Map.get(“field”)取值,所以取到的為空。
解決方案
- 解決方案其實很簡單,更改配置對映檔案加上java.util.HashMap
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping type="bi-directional">
<class-a>com.alibaba.xxx.SourceA</class-a>
<class-b>com.alibaba.xxx.SourceB</class-b>
<field custom-converter="com.alibaba.xxx.JsonConverter">
<a>field</a>
<b>field</b>
<a-hint>java.util.HashMap</a-hint>
</field>
</mapping>
</mappings>
- 重新執行後:
由於getSrcHintContainer() 不為空,會執行到標紅的邏輯,即直接從物件中獲取Map的欄位作為值返回,
相關文章
- Util應用框架基礎(二) - 物件到物件對映(AutoMapper)框架物件APP
- Mapster 高效能物件對映框架物件框架
- Redis OM .NET Redis物件對映框架Redis物件框架
- Hibernate (開源物件關係對映框架)物件框架
- [譯] part 13: golang 對映 mapGolang
- PHP轉Go系列:map對映PHPGo
- 物件對映 - Mapping.Mapster物件APP
- MapStruct 解了物件對映的毒Struct物件
- Javascript - 物件對映automapper介紹JavaScript物件APP
- java物件關係對映ROMJava物件
- 對映
- [譯] 原始碼對映(Source Map)簡介原始碼
- C# 高效能物件對映C#物件
- Go語言之對映(map)快速入門篇Go
- [非專業翻譯] 高效能物件對映框架 - Mapster物件框架
- 多重對映
- MyBatis從入門到精通(十一):MyBatis高階結果對映之一對多對映MyBatis
- MyBatis從入門到精通(九):MyBatis高階結果對映之一對一對映MyBatis
- MyBatis(四) 對映器配置(自動對映、resultMap手動對映、引數傳遞)MyBatis
- [非專業翻譯] Mapster - 對映前&對映後
- WSL 埠對映
- Cache對映方式
- 09 對映(mappings)APP
- Linux埠對映是什麼?如何進行埠對映?Linux
- .NET CORE 中使用AutoMapper進行物件對映APP物件
- resultMap 和 resultType 的欄位對映覆蓋問題
- 玩轉dnmp之埠對映問題解決方案
- vue--vue-router 元件對映到路由Vue元件路由
- JPA關係對映系列四:many-to-many 關聯對映
- MyBatis框架之SQL對映和動態SQLMyBatis框架SQL
- Jackson JSON包在從物件對映到Json字串過程的迴圈依賴問題-分析與解決JSON物件字串
- ElasticSearch中的對映Elasticsearch
- Nginx埠對映配置Nginx
- python 關係對映Python
- MFC訊息對映
- TypeScript 對映型別TypeScript型別
- 對映本地圖片地圖
- VMware Fusion 埠對映
- Mybatis結果對映MyBatis