通过占位符获取json对象中对应位置的值的工具类

序言

最近在写一个天气文字控件,其中想实现通过占位符获取json对应位置数据的功能。这样用户就可以通过占位符自定义要显示的内容。
比如有如下的数据。
这里写图片描述

1。我想显示城市名称,和今天的天气。可以使用如下占位符。

“当前城市{currentCity},今天天气:{weather_data[0].weather},星期:{weather_data[0].date}”

规则如下:
1.占位符最外层为{}
2.如果要获取数组下面的某个元素则可通过 arryName[index] 方式获取
3.如果要获取多级则可通过 valueA.valueB 的方式获取
4.如果没有相关元素则显示[null]
5.如果元素出错,比如数组越界则显示[error]

实现

主要使用了正则表达式和反射来实现。

package com.zgh.weather.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by zhuguohui on 2018/3/21.
 */

public class JSONObjectValueGetter {
    private static final Pattern arrayPatten = Pattern.compile("(\\w+)\\[(\\d+)\\]");
    private static final String VALUE_NULL = "[null]";
    private static final String VALUE_ERROR = "[error]";

    /**
     * @param object     需要获取的JSON对应的javabean
     * @param testFormat 占位符
     *                   <p>规则如下:
     *                   <p> 1.占位符最外层为{} </p>
     *                   <p> 2.如果要获取数组下面的某个元素则可通过 arryName[index] 方式获取
     *                   <p> 3.如果要获取多级则可通过 valueA.valueB 的方式获取
     *                   <p> 4.如果没有相关元素则显示[null]
     *                   <p> 5.如果元素出错,比如数组越界则显示[error]
     * @return
     */
    public static String getValueByFormatString(Object object, String testFormat) {
        Pattern pattern = Pattern.compile("\\{([^\\}]*)\\}");
        Matcher matcher = pattern.matcher(testFormat);
        List<ValueHolder> valueHolderList = new ArrayList<>();
        while (matcher.find()) {
            String holderStr = matcher.group();
            String filedStr = matcher.group(1);
            ValueHolder valueHolder = new ValueHolder(holderStr, getValueString(object, filedStr));
            valueHolderList.add(valueHolder);

        }
        for (ValueHolder valueHolder : valueHolderList) {
            testFormat = Pattern.compile(valueHolder.getKey(), Pattern.LITERAL).matcher(
                    testFormat).replaceFirst(Matcher.quoteReplacement(valueHolder.getValue()));
        }
        return testFormat;
    }

    private static String getValueString(Object object, String filedStr) {
        String valueStr = VALUE_NULL;
        if (object == null || filedStr == null || filedStr.trim().equals("")) {
            return valueStr;
        }
        //判断是否还有下一级
        String subFiledString = null;
        boolean haveSubFile = false;
        boolean isArray = false;
        int arrayIndex = -1;
        Object subObject;
        if (filedStr.contains(".")) {
            subFiledString = filedStr.substring(filedStr.indexOf(".") + 1);
            filedStr = filedStr.substring(0, filedStr.indexOf("."));
            haveSubFile = true;
        }
        //处理数组
        Matcher arrayMatcher = arrayPatten.matcher(filedStr);
        if (arrayMatcher.find()) {
            isArray = true;
            filedStr = arrayMatcher.group(1);
            arrayIndex = Integer.valueOf(arrayMatcher.group(2));
        }

        //获取这一级对应的对象
        try {
            Field field = object.getClass().getDeclaredField(filedStr);
            field.setAccessible(true);
            subObject = field.get(object);
            if (isArray) {
                List list = (List) subObject;
                subObject = list.get(arrayIndex);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return VALUE_ERROR;
        }
        //如果没有下一级
        if (!haveSubFile) {
            return subObject == null ? VALUE_NULL : subObject.toString();
        }else{
            return getValueString(subObject, subFiledString);
        }

    }


    private static class ValueHolder {
        String key, value;

        public ValueHolder(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }
}

使用

public class myClass {


    public static void main(String[] args) {
        Gson gson = new Gson();
        BaiduResult baiduResult = gson.fromJson(DataSupport.TEST_DATA, BaiduResult.class);
        String testFormat = "当前城市{currentCity},今天天气:{weather_data[0].weather},星期:{weather_data[0].date}";
        //注意:此处是从results[0]开始获取
        String showStr = JSONObjectValueGetter.getValueByFormatString(baiduResult.getResults().get(0), testFormat);
        System.out.println(showStr);
    }


}

结果

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_22706515/article/details/79640470