spring boot项目实战之工具篇(ognl)
当解析复杂的json结构时,ognl是一个很方便的工具,实现基于图对属性的访问,类似于以(user.name | user.depart[0])的方式获取json内的嵌套对象字段值。
请看以下示例,你将对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]"));
- 内部对象的普通字段可以通过user.name这样的方式获取
- 内部对象的集合字段可以通过user.depart.size获取其集合长度
- 内部对象的集合字段可以通过user.depart[0]的方式获取对应下标出的值
通常json对象解析可以通过一层一层的转换为map来实现,但如果嵌套对象层次有3层以上,内部结构较复杂,那实现起来就很繁琐,代码冗长,这种情况下使用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类的一个工具类,实现基于图对属性的访问,支持ognl的所有语法。 提供三个核心方法:
get();
getLong(); //如果值非long型,将返回null
getInt(); //如果值非int型,将返回null
使用注意
在使用Long longvalue = ognlWrapper.get("body.payload.page.page_size"); 时出现如下错误: 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(); //设置用户的相关属性
//...省略属性设置
//使用OgnlWrapper
OgnlWrapper ognlWrapper = new OgnlWrapper(user);
String id = ognlWrapper.get("id");//获取id
//状态. 请使用基本数据类型的封装类型
Integer status = ognlWrapper.getInt("status");
//联系信息中的邮件地址
String email = ognlWrapper.get("contact_info.email");
//获取一个不存在的属性
//将返回null
String noexist = ognlWrapper.get("noexist");
//将返回null
noexist = ognlWrapper.get("contact_info.noexist");
对list操作
//将存放用户的列表数据放到map中 map.put("users",list);
//使用OgnlWrapper获取用户列表数据
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 注意:下标从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内rest-base项目com.onecoderspace.base.util.ognl.OgnlWrapper。
https://github.com/q7322068/rest-base