利用JSONPath简化工作

我们的项目中有这样的一个需求:我们存在oss中的数据,仅记录其相对位置,但是当我们将这些数据返回给前端的时候,我们需要将这些相对位置转换成带有签名鉴权等信息的url。我们之前是如何处理这个问题的呢?当我们的数据从数据库查查来后,将这个数据转换成JSONObject或者JSONArray,然后一个一个字段的处理(拿出来,处理后,放回去)。

我不是很满意这种处理方法,感觉代码量非常的大,而且非常的不优雅,所以我开发了如下的工具:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

public class OSSTagUtils {
    public static <T> T tagByJsonPaths(T target, Class<T> clazz, String[] jsonPaths) {

        // todo 研究一下能不能提升JSONPath的性能
        // todo 寻找性能更高的的jsonPath框架
        // todo 完善工具的边界检查

        if (jsonPaths.length == 0) {
            return target;
        }

        // 这种写法是因为已有的Bean深拷贝工具对Map类型支持并不是很好,所以不如转换成JSONObject处理
        JSONObject toDispose = (JSONObject) JSON.toJSON(target);

        for (String jsonPath : jsonPaths) {
            if (JSONPath.contains(toDispose, jsonPath)) {
                Object jsonPathValue = JSONPath.eval(toDispose, jsonPath);
                if (!(jsonPathValue instanceof String)) {
                    throw new RuntimeException("该jsonPath指向的值不为字符串类型");
                }
                String accessUrl = OssUtil.storage.getAccessUrl("", (String) jsonPathValue);
                JSONPath.set(toDispose, jsonPath, accessUrl);
            }
        }

        return toDispose.toJavaObject(clazz);
    }
}

从设计的角度来说,我这个工具还不是非常的强大,我仅对jsonPath指向的字段的值是String时才进行处理,而且我还没有考虑传入的jsonPath定位到一个字符串时如何处理。但是的但,这个工具目前是符合我自己的需求的,倘若我之后有其他的需求,我可以添加上相关的代码。

过度设计和实现,价值意义并不大。

参考资料

  1. JsonPath - 根据表达式路径解析Json
  2. jsonpath - 使用 JSONPath 解析 JSON 完整内容详解
  3. fastJson 之 JSONPath使用