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
    ognl
    3.2.1

2、OgnlWrapper

@SuppressWarnings("unchecked")
public class OgnlWrapper {

    private static Logger logger = LoggerFactory.getLogger(OgnlWrapper.class);

    private static ObjectMapper om = new ObjectMapper();
    private Map payload;

    public OgnlWrapper(Map 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 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

你可能感兴趣的:(spring boot项目实战之工具篇(ognl))