我有以下JSON文本。我如何解析它以获得pageName, pagePic, post_id等的值?

{
  "pageInfo": {
    "pageName": "abc",
    "pagePic": "http://example.com/content.jpg"
  },
  "posts": [
    {
      "post_id": "123456789012_123456789012",
      "actor_id": "1234567890",
      "picOfPersonWhoPosted": "http://example.com/photo.jpg",
      "nameOfPersonWhoPosted": "Jane Doe",
      "message": "Sounds cool. Can't wait to see it!",
      "likesCount": "2",
      "comments": [],
      "timeOfPost": "1234567890"
    }
  ]
}

当前回答

您可以使用JsonNode来表示JSON字符串的结构化树。它是无处不在的杰克逊图书馆的一部分。

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");

其他回答

可以使用Apache @Model注释创建表示JSON文件结构的Java模型类,并使用它们访问JSON树中的各种元素。与其他解决方案不同,该解决方案完全没有反射,因此适用于不可能反射或开销很大的环境。

有一个示例Maven项目展示了这种用法。首先它定义了结构:

@Model(className="RepositoryInfo", properties = {
    @Property(name = "id", type = int.class),
    @Property(name = "name", type = String.class),
    @Property(name = "owner", type = Owner.class),
    @Property(name = "private", type = boolean.class),
})
final class RepositoryCntrl {
    @Model(className = "Owner", properties = {
        @Property(name = "login", type = String.class)
    })
    static final class OwnerCntrl {
    }
}

然后它使用生成的RepositoryInfo和Owner类来解析所提供的输入流,并在此过程中获取某些信息:

List<RepositoryInfo> repositories = new ArrayList<>();
try (InputStream is = initializeStream(args)) {
    Models.parse(CONTEXT, RepositoryInfo.class, is, repositories);
}

System.err.println("there is " + repositories.size() + " repositories");
repositories.stream().filter((repo) -> repo != null).forEach((repo) -> {
    System.err.println("repository " + repo.getName() + 
        " is owned by " + repo.getOwner().getLogin()
    );
})

就是这样!除此之外,这里还有一个生动的要点,展示了类似的例子以及异步网络通信。

Quick-json解析器非常简单,灵活,快速,可定制。试一试

特点:

Compliant with JSON specification (RFC4627) High-Performance JSON parser Supports Flexible/Configurable parsing approach Configurable validation of key/value pairs of any JSON Hierarchy Easy to use # Very small footprint Raises developer friendly and easy to trace exceptions Pluggable Custom Validation support - Keys/Values can be validated by configuring custom validators as and when encountered Validating and Non-Validating parser support Support for two types of configuration (JSON/XML) for using quick-JSON validating parser Requires JDK 1.5 No dependency on external libraries Support for JSON Generation through object serialisation Support for collection type selection during parsing process

它可以这样使用:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);

如果你的数据很简单,你不想要外部依赖,可以使用以下几行代码:

/**
 * A very simple JSON parser for one level, everything quoted.
 * @param json the json content.
 * @return a key => value map.
 */
public static Map<String, String> simpleParseJson(String json) {
    Map<String, String> map = new TreeMap<>();
    String qs[] = json.replace("\\\"", "\u0001").replace("\\\\", "\\").split("\"");
    for (int i = 1; i + 3 < qs.length; i += 4) {
        map.put(qs[i].replace('\u0001', '"'), qs[i + 2].replace('\u0001', '"'));
    }
    return map;
}

这些数据

{"name":"John", "age":"30", "car":"a \"quoted\" back\\slash car"}

生成一个包含

{age=30, car=a "quoted" back\slash car, name=John}

这也可以升级为使用未加引号的值…

/**
 * A very simple JSON parser for one level, names are quoted.
 * @param json the json content.
 * @return a key => value map.
 */
public static Map<String, String> simpleParseJson(String json) {
    Map<String, String> map = new TreeMap<>();
    String qs[] = json.replace("\\\"", "\u0001").replace("\\\\",  "\\").split("\"");
    for (int i = 1; i + 1 < qs.length; i += 4) {
        if (qs[i + 1].trim().length() > 1) {
            String x = qs[i + 1].trim();
            map.put(qs[i].replace('\u0001', '"'), x.substring(1, x.length() - 1).trim().replace('\u0001', '"'));
            i -= 2;
        } else {
            map.put(qs[i].replace('\u0001', '"'), qs[i + 2].replace('\u0001', '"'));
        }
    }
    return map;
}

为了解决复杂的结构,它变得很难看… ... 对不起! !... 但我忍不住把它编码了^^ 这将解析给定的JSON以及更多内容。它产生嵌套的映射和列表。

/**
 * A very simple JSON parser, names are quoted.
 * 
 * @param json the json content.
 * @return a key => value map.
 */
public static Map<String, Object> simpleParseJson(String json) {
    Map<String, Object> map = new TreeMap<>();
    String qs[] = json.replace("\\\"", "\u0001").replace("\\\\", "\\").split("\"");
    int index[] = { 1 };
    recurse(index, map, qs);
    return map;
}

/**
 * Eierlegende Wollmilchsau.
 * 
 * @param index index into array.
 * @param map   the current map to fill.
 * @param qs    the data.
 */
private static void recurse(int[] index, Map<String, Object> map, String[] qs) {
    int i = index[0];
    for (;; i += 4) {
        String end = qs[i - 1].trim(); // check for termination of an object
        if (end.startsWith("}")) {
            qs[i - 1] = end.substring(1).trim();
            i -= 4;
            break;
        }

        String key = qs[i].replace('\u0001', '"');
        String x = qs[i + 1].trim();
        if (x.endsWith("{")) {
            x = x.substring(0, x.length() - 1).trim();
            if (x.endsWith("[")) {
                List<Object> list = new ArrayList<>();
                index[0] = i + 2;
                for (;;) {
                    Map<String, Object> inner = new TreeMap<>();
                    list.add(inner);
                    recurse(index, inner, qs);
                    map.put(key, list);
                    i = index[0];

                    String y = qs[i + 3]; // check for termination of array
                    if (y.startsWith("]")) {
                        qs[i + 3] = y.substring(1).trim();
                        break;
                    }
                }
                continue;
            }

            Map<String, Object> inner = new TreeMap<>();
            index[0] = i + 2;
            recurse(index, inner, qs);
            map.put(key, inner);
            i = index[0];
            continue;
        }
        if (x.length() > 1) { // unquoted
            String value = x.substring(1, x.length() - 1).trim().replace('\u0001', '"');
            if ("[]".equals(value)) // handle empty array
                map.put(key, new ArrayList<>());
            else
                map.put(key, value);
            i -= 2;
        } else {
            map.put(key, qs[i + 2].replace('\u0001', '"'));
        }
    }
    index[0] = i;
}

yield -如果你打印地图:

{pageInfo={pageName=abc, pagePic=http://example.com/content.jpg}, posts=[{actor_id=1234567890, comments=[], likesCount=2, message=Sounds cool. Can't wait to see it!, nameOfPersonWhoPosted=Jane Doe, picOfPersonWhoPosted=http://example.com/photo.jpg, post_id=123456789012_123456789012, timeOfPost=1234567890}]}

由于还没有人提到它,这里是一个使用Nashorn (Java 8的JavaScript运行时部分,但在Java 11中已弃用)的解决方案的开始。

解决方案

private static final String EXTRACTOR_SCRIPT =
    "var fun = function(raw) { " +
    "var json = JSON.parse(raw); " +
    "return [json.pageInfo.pageName, json.pageInfo.pagePic, json.posts[0].post_id];};";

public void run() throws ScriptException, NoSuchMethodException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(EXTRACTOR_SCRIPT);
    Invocable invocable = (Invocable) engine;
    JSObject result = (JSObject) invocable.invokeFunction("fun", JSON);
    result.values().forEach(e -> System.out.println(e));
}

性能比较

我编写的JSON内容包含三个数组,分别为20、20和100个元素。我只想从第三个数组中获取100个元素。我使用下面的JavaScript函数来解析和获取我的条目。

var fun = function(raw) {JSON.parse(raw).entries};

使用Nashorn运行一百万次调用需要7.5~7.8秒

(JSObject) invocable.invokeFunction("fun", json);

org。Json需要20~21秒

new JSONObject(JSON).getJSONArray("entries");

杰克逊用时6.5~7秒

mapper.readValue(JSON, Entries.class).getEntries();

在这种情况下,Jackson的性能比Nashorn好,后者的性能比org.json好得多。 Nashorn API比org更难使用。json或Jackson的。根据您的需求,Jackson和Nashorn都是可行的解决方案。

使用minimal-json,它非常快速和容易使用。 你可以从String obj和Stream中解析。

样本数据:

{
  "order": 4711,
  "items": [
    {
      "name": "NE555 Timer IC",
      "cat-id": "645723",
      "quantity": 10,
    },
    {
      "name": "LM358N OpAmp IC",
      "cat-id": "764525",
      "quantity": 2
    }
  ]
}

解析:

JsonObject object = Json.parse(input).asObject();
int orders = object.get("order").asInt();
JsonArray items = object.get("items").asArray();

创建JSON:

JsonObject user = Json.object().add("name", "Sakib").add("age", 23);

Maven:

<dependency>
  <groupId>com.eclipsesource.minimal-json</groupId>
  <artifactId>minimal-json</artifactId>
  <version>0.9.4</version>
</dependency>