Java Bean to Map
1、背景
ある業務シナリオでは、JavaBean を Map に変換して再利用する必要があります。
2、よくある落とし穴
2.0 テスト対象
2.1 JSON デシリアライズによる型の喪失
2.1.1 問題の再発
JavaBean を Map に変換する最も一般的な方法は、fastjson、gson、jackson などの JSON フレームワークを使用することです。
ただし、JSON を使用して JavaBean を Map に変換すると、一部のデータ型が失われる原因になります。
たとえば fastjson を使用した場合、属性が Long 型であっても、その値が Integer の最大値より小さいと、デシリアライズ後に Map に変換すると Integer 型になってしまいます。
2.2.2 問題の説明
問題は 2 つあります
(1) fastjson で JavaBean を Map に変換する際、型が変化する問題。
たとえば、Long が Integer に、Date が Long に、Double が Decimal に変化します。
(2) 一部のシナリオでは、Map のキーが属性名と完全に一致しない問題。たとえば getter/setter メソッドから推論される属性名の場合などです。
2.2 BeanMap 変換における属性名エラー
2.2.1 commons-beanutils の BeanMap
コードから次のことがわかります
(1) name の長さが 1 より大きく、最初の 2 文字が大文字の場合、パラメータが PropertyDescriptor の名前としてそのまま返されます。
(2) それ以外の場合、name を小文字に変換します
この処理の元々の意図は、URL のような略語が属性として uRL に変換されるのを防ぐことですが、これが私たちのシナリオに問題を引き起こしています。
2.2.2 cglib を使用した BeanMap
cglib の依存関係
型は正しいことがわかりましたが、プロパティ名は依然として不正です。
コアコード:
net.sf.cglib.core.ReflectUtils#getBeanGetters
内部では java.beans.Introspector#decapitalize も使用されているため、属性名に同じ問題が発生するのも無理はありません。
3、解決策
3.1 解決策
解決策は複数あります。この記事では Dubbo ベースの解決策を紹介します。
Maven の依存関係:
3.2 原理の分析
ソースコードをダウンロードして簡単に学習できます。
https://github.com/apache/dubbo
コアコード:
org.apache.dubbo.common.utils.PojoUtils#generalize(java.lang.Object)
public static Object generalize(Object pojo) {
eturn generalize(pojo, new IdentityHashMap());
}
これから、属性名が特殊な場合は問題が発生しやすいことがわかりますが、Dubbo のツールクラスはより期待に沿った動作をします。
詳細については、デモに応じてデバッグしながら学習してください。
属性と厳密に一致させたい場合は、リフレクションを使用して属性名と属性値を取得し、キャッシュ機構を追加して解析の効率を向上させることができます。
4、まとめ
JavaBean から Map への変換には多くの落とし穴があります。最も一般的な問題は、型の喪失と属性名の解析エラーです。
JSON フレームワークや JavaBean から Map への変換フレームワークを使用する際は、特に注意すべきです。
フレームワークを使用する際は、より多くのデモで検証し、より多くのソースコードを読み、より多くデバッグして、実際のトラブルを未然に防ぎましょう。
ある業務シナリオでは、JavaBean を Map に変換して再利用する必要があります。
2、よくある落とし穴
2.0 テスト対象
2.1 JSON デシリアライズによる型の喪失
2.1.1 問題の再発
JavaBean を Map に変換する最も一般的な方法は、fastjson、gson、jackson などの JSON フレームワークを使用することです。
ただし、JSON を使用して JavaBean を Map に変換すると、一部のデータ型が失われる原因になります。
たとえば fastjson を使用した場合、属性が Long 型であっても、その値が Integer の最大値より小さいと、デシリアライズ後に Map に変換すると Integer 型になってしまいます。
2.2.2 問題の説明
問題は 2 つあります
(1) fastjson で JavaBean を Map に変換する際、型が変化する問題。
たとえば、Long が Integer に、Date が Long に、Double が Decimal に変化します。
(2) 一部のシナリオでは、Map のキーが属性名と完全に一致しない問題。たとえば getter/setter メソッドから推論される属性名の場合などです。
2.2 BeanMap 変換における属性名エラー
2.2.1 commons-beanutils の BeanMap
コードから次のことがわかります
(1) name の長さが 1 より大きく、最初の 2 文字が大文字の場合、パラメータが PropertyDescriptor の名前としてそのまま返されます。
(2) それ以外の場合、name を小文字に変換します
この処理の元々の意図は、URL のような略語が属性として uRL に変換されるのを防ぐことですが、これが私たちのシナリオに問題を引き起こしています。
2.2.2 cglib を使用した BeanMap
cglib の依存関係
型は正しいことがわかりましたが、プロパティ名は依然として不正です。
コアコード:
net.sf.cglib.core.ReflectUtils#getBeanGetters
内部では java.beans.Introspector#decapitalize も使用されているため、属性名に同じ問題が発生するのも無理はありません。
3、解決策
3.1 解決策
解決策は複数あります。この記事では Dubbo ベースの解決策を紹介します。
Maven の依存関係:
3.2 原理の分析
ソースコードをダウンロードして簡単に学習できます。
https://github.com/apache/dubbo
コアコード:
org.apache.dubbo.common.utils.PojoUtils#generalize(java.lang.Object)
public static Object generalize(Object pojo) {
eturn generalize(pojo, new IdentityHashMap());
}
これから、属性名が特殊な場合は問題が発生しやすいことがわかりますが、Dubbo のツールクラスはより期待に沿った動作をします。
詳細については、デモに応じてデバッグしながら学習してください。
属性と厳密に一致させたい場合は、リフレクションを使用して属性名と属性値を取得し、キャッシュ機構を追加して解析の効率を向上させることができます。
4、まとめ
JavaBean から Map への変換には多くの落とし穴があります。最も一般的な問題は、型の喪失と属性名の解析エラーです。
JSON フレームワークや JavaBean から Map への変換フレームワークを使用する際は、特に注意すべきです。
フレームワークを使用する際は、より多くのデモで検証し、より多くのソースコードを読み、より多くデバッグして、実際のトラブルを未然に防ぎましょう。
Related Articles
-
A detailed explanation of Hadoop core architecture HDFS
Knowledge Base Team
-
What Does IOT Mean
Knowledge Base Team
-
6 Optional Technologies for Data Storage
Knowledge Base Team
-
What Is Blockchain Technology
Knowledge Base Team
Explore More Special Offers
-
Short Message Service(SMS) & Mail Service
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00
