當(dāng)解析復(fù)雜的json結(jié)構(gòu)時幻梯,ognl是一個很方便的工具,實現(xiàn)基于圖對屬性的訪問瓦宜,類似于以(user.name | user.depart[0])的方式獲取json內(nèi)的嵌套對象字段值。
請看以下示例,你將對ognl的作用有一個更清晰的理解:
String json = "{\"user\":{\"name\":\"123\",\"depart\":[1,2]}}";
Map<?, ?> map = JacksonHelper.fromJson(json, Map.class);
OgnlWrapper ognlWrapper = new OgnlWrapper(map);
System.err.println(ognlWrapper.get("user.name"));
System.err.println(ognlWrapper.get("user.depart.size"));
System.err.println(ognlWrapper.get("user.depart[0]"));
- 內(nèi)部對象的普通字段可以通過user.name這樣的方式獲取
- 內(nèi)部對象的集合字段可以通過user.depart.size獲取其集合長度
- 內(nèi)部對象的集合字段可以通過user.depart[0]的方式獲取對應(yīng)下標(biāo)出的值
通常json對象解析可以通過一層一層的轉(zhuǎn)換為map來實現(xiàn)凭戴,但如果嵌套對象層次有3層以上,內(nèi)部結(jié)構(gòu)較復(fù)雜炕矮,那實現(xiàn)起來就很繁瑣么夫,代碼冗長者冤,這種情況下使用ognl能讓代碼精簡很多。
1档痪、添加maven依賴
<!-- ognl -->
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.2.1</version>
</dependency>
2涉枫、OgnlWrapper
@SuppressWarnings("unchecked")
public class OgnlWrapper {
private static Logger logger = LoggerFactory.getLogger(OgnlWrapper.class);
private static ObjectMapper om = new ObjectMapper();
private Map<String, Object> payload;
public OgnlWrapper(Map<String, Object> playload) {
Validate.notEmpty(playload, "can not construct with none playload!");
this.payload = playload;
}
public OgnlWrapper(Object playload) {
this.payload = om.convertValue(playload, Map.class);
}
public <T> T get(String expression) {
try {
return (T) Ognl.getValue(expression, this.payload);
} catch (OgnlException e) {
logger.trace(String.format("get value with expression:[%s] due to error, return null instead of",
expression), e);
return null;
}
}
public Long getLong(String expression) {
try {
Object obj = Ognl.getValue(expression, this.payload);
if (null == obj)
return null;
try {
return Long.parseLong(obj.toString());
} catch (NumberFormatException nfe) {
logger.warn(String.format("get value with expression:[%s] due to error, return null. value[%s] cannot be cast to java.lang.Long",
expression,
obj.toString()));
return null;
}
} catch (OgnlException e) {
logger.trace(String.format("get value with expression:[%s] due to error, return null instead of",
expression), e);
return null;
}
}
public Integer getInt(String expression) {
try {
Object obj = Ognl.getValue(expression, this.payload);
if (null == obj)
return null;
try {
return Integer.parseInt(obj.toString());
} catch (NumberFormatException nfe) {
logger.warn(String.format("get value with expression:[%s] due to error, return null. value[%s] cannot be cast to java.lang.Integer",
expression,
obj.toString()));
return null;
}
} catch (OgnlException e) {
logger.trace(String.format("get value with expression:[%s] due to error, return null instead of",
expression), e);
return null;
}
}
@Override
public String toString() {
return String.format("OgnlWrapper[%s]", this.payload.toString());
}
public static void main(String[] args) {
String json = "{\"user\":{\"name\":\"123\",\"depart\":[1,2]}}";
Map<?, ?> map = JacksonHelper.fromJson(json, Map.class);
OgnlWrapper ognlWrapper = new OgnlWrapper(map);
System.err.println(ognlWrapper.get("user.name"));
System.err.println(ognlWrapper.get("user.depart.size"));
System.err.println(ognlWrapper.get("user.depart[0]"));
}
}
3、使用手冊
說明
OgnlWrapper是基于ognl.Ognl類的一個工具類钞它,實現(xiàn)基于圖對屬性的訪問拜银,支持ognl的所有語法。 提供三個核心方法:
get();
getLong(); //如果值非long型遭垛,將返回null
getInt(); //如果值非int型尼桶,將返回null
使用注意
在使用Long longvalue = ognlWrapper.get("body.payload.page.page_size"); 時出現(xiàn)如下錯誤: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
解決方法:使用getLong方法
Long longvalue = ognlWrapper.getLong("body.payload.page.page_size");
獲取不存在的屬性時返回null,日志中會打印warn警告日志锯仪。 如:ognlWrapper.getLong("body.payload[0].childrens[0].childrens.size"); // return null
單個對象
User user = new User(); //設(shè)置用戶的相關(guān)屬性
//...省略屬性設(shè)置
//使用OgnlWrapper
OgnlWrapper ognlWrapper = new OgnlWrapper(user);
String id = ognlWrapper.get("id");//獲取id
//狀態(tài). 請使用基本數(shù)據(jù)類型的封裝類型
Integer status = ognlWrapper.getInt("status");
//聯(lián)系信息中的郵件地址
String email = ognlWrapper.get("contact_info.email");
//獲取一個不存在的屬性
//將返回null
String noexist = ognlWrapper.get("noexist");
//將返回null
noexist = ognlWrapper.get("contact_info.noexist");
對list操作
//將存放用戶的列表數(shù)據(jù)放到map中 map.put("users",list);
//使用OgnlWrapper獲取用戶列表數(shù)據(jù)
OgnlWrapper ognlWrapper = new OgnlWrapper(map);
//獲取list大小泵督。如果map未存放list則返回null
Integer size = ognlWrapper.getInt("users.size");
if(null == size || 0 == size.intValue()) return ;
//獲取list中第一用戶的用戶id和name 注意:下標(biāo)從0開始
String id = ognlWrapper.get("users[0].id");
String name = ognlWrapper.get("users[0].name");
//如果索引超出list的大小,將返回null
String nullvalue = ognlWrapper.get("users[9999999].id");
使用OgnlWrapper獲取屬性值時庶喜,請使用對象類型小腊。如int 使用Integer類型。
完整代碼請參考github內(nèi)rest-base項目com.onecoderspace.base.util.ognl.OgnlWrapper久窟。
https://github.com/q7322068/rest-base