如何高效解析每次变化的 Rest Api 响应。

huangapple go评论71阅读模式
英文:

How to parse efficiently a Rest Api response that evolve each time

问题

以下是翻译好的内容:

我不是程序员,所以我缺乏基本知识。

我想创建一个桌面应用程序,一个词典,你可以搜索一个词,然后得到一个简短的定义。

我使用了下面这些资源。

https://api.lexicala.com/

接下来是我的脚本的一部分。

我的问题是,对于每个部分我搜索的词,词的含义,词的性质等等。

我必须编写这些解封装的代码行。
// 编辑:解封装=反序列化

response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONObject("headword").get("text")

如果 JSON 每次都不改变,那就没有问题,但是实际上是会改变的。

形容词和名词会完全改变结构,我会收到一个错误。

一个 JSON 对象现在是一个 JSON 数组。

我想知道是否有一种简单的方法,可以使用 Jackson、Gson 或者 Json 来简单地询问像这样的问题

Json.Parse(JsonResponse);
get("Definition");

而不是

Object Resultat4 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONArray("senses").getJSONObject(0).get("definition");

并且只获取内容,而不经过所有这些变化的代码行。

谢谢你在这个问题上的帮助。

// 值

String motacherch = "grand";

public void gettest() {

HttpResponse response = Unirest.get("https://dictapi.lexicala.com/search?source=global&language=fr&text=" + motacherch)
.basicAuth("user", "password")
.asJson();

JSONObject responsejson = (JSONObject) response.getBody().getObject();
System.out.println(responsejson);

Object Resultat = response.getBody().getObject().get("n_results");
System.out.println("Le nombre de resultats est:" + Resultat);

Object Resultat2 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONObject("headword").get("text");
System.out.println("Le mot que l'on cherche est: " + Resultat2);
Object Resultat3 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONObject("headword").get("pos");
System.out.println("C'est un: " + Resultat3);
Object Resultat4 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONArray("senses").getJSONObject(0).get("definition");

System.out.println("Definition: " + Resultat4);

System.out.println("---------------------------------------------");

HttpResponse response2 = Unirest.get("https://dictapi.lexicala.com/users/me")
.basicAuth("", "")
.asJson();
//System.out.println(response2.getBody());
JSONObject responsejson2 = response2.getBody().getObject();
JSONObject results = responsejson2.getJSONObject("usage").getJSONObject("today");
Object results2 = results.get("count");
System.out.println(results2);
}

英文:

I am not a programmer, then I lake basic knowledge.

I want to create a desktop app, a dictionary, you search a word, you have a short definition.

I use those guys.

https://api.lexicala.com/

Then here is part of my script bellow.

My problem is that for each part I search for, the meaning of the word, its nature, etc.

I have to make this decapsulation code lines.
// Edit: decapsulation=deserialization

response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONObject("headword").get("text")

If the Json was not changing each time, no problem, but it does.

An Adjective, and a noun change completely the structure, and I get an error.

A Json Object is now a Json Array.

I would like to know if there is a simple way, either Jackson, or Gson or Json to
simply ask something like

Json.Parse (JsonResponse);
get("Definition");

Instead of

Object Resultat4 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONArray("senses").getJSONObject(0).get("definition");

And have the content only, without passing by all this changing lines of codes.

Thanks you to help me on this.

//Values

String motacherch = "grand";



public void  gettest(){



   HttpResponse<JsonNode> response = Unirest.get("https://dictapi.lexicala.com/search?source=global&language=fr&text="+motacherch)
           .basicAuth("user", "password")
           .asJson();

   JSONObject responsejson = (JSONObject) response.getBody().getObject();
   System.out.println( responsejson);


   Object Resultat = response.getBody().getObject().get("n_results");
   System.out.println( "Le nombre de resultats est:"+ Resultat);


    Object Resultat2 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONObject("headword").get("text");
    System.out.println( "Le mot que l'on cherche est: "+ Resultat2);
    Object Resultat3 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONObject("headword").get("pos");
    System.out.println( "C'est un: "+ Resultat3);
    Object Resultat4 = response.getBody().getObject().getJSONArray("results").getJSONObject(0).getJSONArray("senses").getJSONObject(0).get("definition");

    System.out.println( "Definition: "+ Resultat4);


    System.out.println( "---------------------------------------------" );

HttpResponse<JsonNode> response2 = Unirest.get("https://dictapi.lexicala.com/users/me")
        .basicAuth("", "")
        .asJson();
    //System.out.println( response2.getBody());
    JSONObject responsejson2 = response2.getBody().getObject();
    JSONObject results = responsejson2.getJSONObject("usage").getJSONObject("today");
    Object results2=results.get("count");
    System.out.println( results2);

}

答案1

得分: 2

最简单的方法是将 JSON 解析为一个 Java Map<String, Object>,这总是成功的(值本身可以是映射),使用你喜欢的库(尝试 Jackson 或 gson)。

然后检查地图的键以确定要执行的操作。

更难但更“正确”的方法是根据有效负载的属性解析为多种不同的类,但在这种情况下,我不会这样做,因为 API 设计听起来有点不稳定。


这里有一些将 JSON 解析为地图的代码:

import com.fasterxml.jackson.databind.ObjectMapper;

Map<String, Object> map = (HashMap<String, Object>) new ObjectMapper().readValue(jsonStr, LinkedHashMap.class); // LinkedHashMap 会保留顺序

为了更轻松地访问地图值,你可能会发现这个通过推断进行转换的辅助方法很方便:

static <T> T getValue(Map<String, Object> map, String key) {
    return (T) map.get(key);
}

像这样使用它:

List<Map<String, Object>> list = getValue(map, "results"); // 无需转换
英文:

The simplest way is to parse (deserialise) the json to a java Map&lt;String, Object&gt;, which always succeeds (the values may themselves be maps) using your favourite library (try Jackson or gson).

Then examine the map’s keys to figure out what to do with it.

The harder, but more “correct” way is to deserialise to a variety of classes chosen by the attributes of the payload, but in this case I wouldn’t, as the API design sounds a little flakey.


Here’s some code to parse json to a map:

import com.fasterxml.jackson.databind.ObjectMapper;

Map&lt;String, Object&gt; map = (HashMap&lt;String, Object&gt;) new ObjectMapper().readValue(jsonStr, LinkedHashMap.class); // LinkedHashMap will preserve order

To make accessing map values easier, you may find this helper method that does the cast by inference handy:

static &lt;T&gt; T getValue(Map&lt;String, Object&gt; map, String key) {
    return (T)map.get(key);
}

Use it like this:

List&lt;Map&lt;String, Object&gt;&gt; list = getValue(map, &quot;results&quot;); // no cast needed

答案2

得分: 0

   Json数据:

    {"n_results":1,"page_number":1,"results_per_page":10,"n_pages":1,"available_n_pages":1,"results":[{"id":"FR_DE00114905","language":"fr","headword":{"text":"briser","pos":"verb"},"senses":[{"id":"FR_SE00126791","definition":"réduire en morceaux"},{"id":"FR_SE00002638","definition":"détruire"}]}]}

代码部分:

    String motacherch = "briser";

    public void gettest() throws IOException {
        HttpResponse<JsonNode> response = Unirest.get("https://dictapi.lexicala.com/search?source=global&language=fr&text=" + motacherch)
                .basicAuth("user", "password")
                .asJson();
        System.out.println("---------------------------------------------");

        JSONObject responsejson = (JSONObject) response.getBody().getObject();
        System.out.println(responsejson);

        System.out.println("---------------------------------------------");

        Map<String, Object> map;
        map = (HashMap<String, Object>) new ObjectMapper().readValue(responsejson.toString(), LinkedHashMap.class);
        System.out.println(map.get("results"));

        System.out.println("---------------------------------------------");

        List<Map<String, Object>> results = (List<Map<String, Object>>) map.get("results");
        System.out.println(results.get(0).get("id"));
        System.out.println(results.get(0).get("senses"));
        List<Map<String, Object>> results33 = (List<Map<String, Object>>) results.get(0).get("senses");
        System.out.println(results33.get(0).get("definition"));
        System.out.println(results33.get(1).get("definition"));
    }
英文:

The Json:

{&quot;n_results&quot;:1,&quot;page_number&quot;:1,&quot;results_per_page&quot;:10,&quot;n_pages&quot;:1,&quot;available_n_pages&quot;:1,&quot;results&quot;:[{&quot;id&quot;:&quot;FR_DE00114905&quot;,&quot;language&quot;:&quot;fr&quot;,&quot;headword&quot;:{&quot;text&quot;:&quot;briser&quot;,&quot;pos&quot;:&quot;verb&quot;},&quot;senses&quot;:[{&quot;id&quot;:&quot;FR_SE00126791&quot;,&quot;definition&quot;:&quot;r&#233;duire en morceaux&quot;},{&quot;id&quot;:&quot;FR_SE00002638&quot;,&quot;definition&quot;:&quot;d&#233;truire&quot;}]}]}

Part of the code:

String motacherch = &quot;briser&quot;;



public void  gettest() throws IOException {



    HttpResponse&lt;JsonNode&gt; response = Unirest.get(&quot;https://dictapi.lexicala.com/search?source=global&amp;language=fr&amp;text=&quot;+motacherch)
            .basicAuth(&quot;user&quot;, &quot;password&quot;)
            .asJson();
    System.out.println( &quot;---------------------------------------------&quot; );

    JSONObject responsejson = (JSONObject) response.getBody().getObject();
    System.out.println( responsejson);

    System.out.println( &quot;---------------------------------------------&quot; );

    Map&lt;String, Object&gt; map;
    map = (HashMap&lt;String, Object&gt;) new ObjectMapper().readValue(responsejson.toString(), LinkedHashMap.class);
    System.out.println(map.get(&quot;results&quot;));

    System.out.println( &quot;---------------------------------------------&quot; );

    List&lt;Map&lt;String, Object&gt;&gt; results = (List&lt;Map&lt;String, Object&gt;&gt;)map.get(&quot;results&quot;);
    System.out.println( results.get(0).get(&quot;id&quot;) );
    System.out.println( results.get(0).get(&quot;senses&quot;) );
    List&lt;Map&lt;String, Object&gt;&gt; results33 = (List&lt;Map&lt;String, Object&gt;&gt;)results.get(0).get(&quot;senses&quot;);
    System.out.println( results33.get(0).get(&quot;definition&quot;) );
    System.out.println( results33.get(1).get(&quot;definition&quot;) );




}

huangapple
  • 本文由 发表于 2020年10月6日 09:41:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/64218241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定