用途:某些时候需要获取一个JSON格式里面的里层的一个key 对应的value,很多时候都会手动去解析(至少我工作中是一直手动解析取值的)。其实逻辑很捡到,就是对已知json 的结构进行层层转换,然后getValue.
今天花了1个多小时手写了一个解析类。测试目前正常。发出来是希望大佬们帮忙看看有什么问题。
需要指定方法的返回的类型,和JSON结构的一个字符串 类似于 "results[0].index[1].title",
results 层级为数组,取 第1个元素
index 层级为数组,取 第2个元素。
title 层级为object,直接取值。
话不多说上代码:
package com.demo.utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.TypeUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import java.util.Arrays;
import java.util.Map;
/**
* personal util for get key-value from a Map
*this util is on testing...so if u want to try ,please focus your
* inParam is same as the temple
* temple : "results[0].index[1].title"
*
*
* */
public class JeeKyMapUtils {
public static <T> T getObjectByTargetKeyPath(Map jsonMap, String path,Class<T> clazz) {
if (StringUtils.isNotEmpty(path)) {
String[] pathArr = path.split("\\.");
if (pathArr.length > 0 && jsonMap != null) {
return getStrByPath(jsonMap, pathArr,clazz);
}
}
return null;
}
public static <T> T getStrByPath(Map map, String[] pathArr,Class<T> clazz) {
String key = pathArr[0];
int index = key.indexOf("[");
//deal Array or Object use [number]
if (index == -1) {
//object
if (pathArr.length == 1) {
Object object = map.get(key);
return TypeUtils.castToJavaBean(object, clazz);
} else {
Map nextMap = (Map) map.get(key);
String[] nextPathArr = Arrays.copyOfRange(pathArr, 1, pathArr.length);
return getStrByPath(nextMap, nextPathArr, clazz);
}
}else{
//Array
int subIndex = Integer.parseInt((key.substring(index).replaceAll("\\[", "").replaceAll("]", "")));
if((pathArr.length == 1)){
JSONArray jsonArray = (JSONArray) map.get(key.substring(0, index));
Object object = jsonArray.get(subIndex);
return TypeUtils.castToJavaBean(object, clazz);
}else{
String[] nextPathArr = Arrays.copyOfRange(pathArr, 1, pathArr.length);
String itemKey = key.substring(0, index);
JSONArray jsonArray = (JSONArray) map.get(itemKey);
Object object = jsonArray.get(subIndex);
Map nextMap = TypeUtils.castToJavaBean(object,Map.class);
return getStrByPath(nextMap,nextPathArr,clazz);
}
}
}
@Test
public void TestUtil(){
Map map = JSONObject.parseObject(jsonStr);
String path="results[0].index[1].title";
Long before = System.currentTimeMillis();
String out =getObjectByTargetKeyPath(map,path,String.class);
System.out.println(out);
System.out.println(System.currentTimeMillis()-before);
}
private static final String jsonStr= new String("{\n" +
" \"error\": 0,\n" +
" \"status\": \"success\",\n" +
" \"results\": [\n" +
" {\n" +
" \"currentCity\": \"青岛\",\n" +
" \"index\": [\n" +
" {\n" +
" \"title\": \"穿衣\",\n" +
" \"zs\": \"较冷\",\n" +
" \"tipt\": \"穿衣指数\",\n" +
" \"des\": \"建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。\"\n" +
" },\n" +
" {\n" +
" \"title\": \"紫外线强度\",\n" +
" \"zs\": \"中等\",\n" +
" \"tipt\": \"紫外线强度指数\",\n" +
" \"des\": \"属中等强度紫外线辐射天气,外出时建议涂擦SPF高于15、PA+的防晒护肤品,戴帽子、太阳镜。\"\n" +
" }\n" +
" ]\n" +
" \n" +
" }\n" +
" ]\n" +
"}");
}