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的欄位作為值返回,
相關文章
- dozer- JavaBean對映工具JavaBean
- 業務物件對映到表之間的關聯問題!!物件
- Redis OM .NET Redis物件對映框架Redis物件框架
- hibernate物件對映的一個問題。物件
- Mapster 高效能物件對映框架物件框架
- Util應用框架基礎(二) - 物件到物件對映(AutoMapper)框架物件APP
- [譯] part 13: golang 對映 mapGolang
- PHP轉Go系列:map對映PHPGo
- 在Watir中進行物件對映(Object Map)的方法物件Object
- Hibernate (開源物件關係對映框架)物件框架
- Docker 埠對映問題解決Docker
- 埠對映,內網網站對映外網訪問,透過80埠對映實現內網網站
- [譯] 原始碼對映(Source Map)簡介原始碼
- Image Map,是對映還是地圖?地圖
- java物件關係對映ROMJava物件
- hibernate對映合成模式的問題模式
- 捉蟲記之dozer對映父類屬性被重寫
- MVC框架的對映和解耦MVC框架解耦
- 資料訪問模式:Identity Map(標識對映)模式模式IDE
- 關於URL連結對映到檔案目錄的問題
- 多重對映
- C# 高效能物件對映C#物件
- MapStruct 解了物件對映的毒Struct物件
- MongoDB、Java與物件關係對映MongoDBJava物件
- MongoDB、Java和物件關係對映MongoDBJava物件
- MyBatis從入門到精通(九):MyBatis高階結果對映之一對一對映MyBatis
- MyBatis從入門到精通(十一):MyBatis高階結果對映之一對多對映MyBatis
- MyBatis(四) 對映器配置(自動對映、resultMap手動對映、引數傳遞)MyBatis
- C# ORM從物件到資料庫表的對映C#ORM物件資料庫
- Javascript - 物件對映automapper介紹JavaScript物件APP
- 物件對映 - Mapping.Mapster物件APP
- 物件關係對映(ORM)簡單看懂物件ORM
- [非專業翻譯] 高效能物件對映框架 - Mapster物件框架
- 修改對映地址
- Mybatis學習筆記(5)-高階對映之多對多對映MyBatis筆記
- [非專業翻譯] Mapster - 對映前&對映後
- vue--vue-router 元件對映到路由Vue元件路由
- Mybatis學習筆記(4)-高階對映之一對多對映MyBatis筆記