如何解析响应的 JSON 表示?

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

How can I parse a json representation of a response?

问题

我对JAVA还比较新,对于提出这样一个相对基础的问题感到抱歉。

我有一个看起来像这样的JSON字符串。

{"statusCode":201,
 "body":"[["food_corn","48"],["food_potatoes","130"],["food_rice","80"]]",
 "headers":{"Access-Control-Allow-Origin":"*"}}

我只对文本的主体部分感兴趣,它可能包含任意数量的元素。

最后,我想要一个map,其中项目名称作为键,相应的数字作为值(作为整数)。

谢谢你的帮助!


我所在的进展更新如下:

String decoded = new String(invoke.getPayload().array(), "UTF-8");
HashMap<String, Object> map = new ObjectMapper().readValue(decoded, HashMap.class);
Object body = map.get("body")

其中body看起来像这样

[["food_corn","48"],["food_potatoes","130"],["food_rice","80"],["food_wheat","999"]]

然后我尝试将其解析为数组,如下所示

JSONArray array = new JSONArray(body);

但我遇到了错误

EXCEPTION: JSONArray initial value should be a string or collection or array.

这对我来说不太合理,因为上面看起来像是一个数组的数组,不是吗?

英文:

I'm pretty new to JAVA so my apologies for asking a rather elementary question.

I have a json string that looks like this.

{&quot;statusCode&quot;:201,
 &quot;body&quot;:&quot;[[\&quot;food_corn\&quot;,\&quot;48\&quot;],[\&quot;food_potatoes\&quot;,\&quot;130\&quot;],[\&quot;food_rice\&quot;,\&quot;80\&quot;]]&quot;,
 &quot;headers&quot;:{&quot;Access-Control-Allow-Origin&quot;:&quot;*&quot;}}

I'm only interested in the body of the text which may have any number of elements.

At the end I'd like to have a map with the item name as the key and the number as the correspond value (as an integer).

Thanks for the help!


Update on where I'm at

String decoded = new String(invoke.getPayload().array(), &quot;UTF-8&quot;);
HashMap&lt;String, Object&gt; map = new ObjectMapper().readValue(decoded, HashMap.class);
Object body = map.get(&quot;body&quot;)

where body looks like this

[[&quot;food_corn&quot;,&quot;48&quot;],[&quot;food_potatoes&quot;,&quot;130&quot;],[&quot;food_rice&quot;,&quot;80&quot;],[&quot;food_wheat&quot;,&quot;999&quot;]]

So then I try parsing it into an array like so

JSONArray array = new JSONArray(body);

But I get the error

EXCEPTION: JSONArray initial value should be a string or collection or array.

Which doesn't make sensee to me because the above looks like an array of arrays, no?

答案1

得分: 1

 @SneakyThrows
 @Test
 public void covertTest() {
   String str = "{\"statusCode\":201,\"body\":\"[[\\\"food_corn\\\",\\\"48\\\"],[\\\"food_potatoes\\\",\\\"130\\\"],"
     + "[\\\"food_rice\\\",\\\"80\\\"]]\",\"headers\":{\"Access-Control-Allow-Origin\":\"*\"}}";
   Map map = objectMapper.readValue(str, Map.class);
   System.out.println(map);
 //{statusCode=201, body=[[\"food_corn\",\"48\"],[\"food_potatoes\",\"130\"],[\"food_rice\",\"80\"]], headers={Access-Control-Allow-Origin=*}}
 }
英文:
 @SneakyThrows
 @Test
 public void covertTest() {
  String str = &quot;{\&quot;statusCode\&quot;:201,\&quot;body\&quot;:\&quot;[[\\\&quot;food_corn\\\&quot;,\\\&quot;48\\\&quot;],[\\\&quot;food_potatoes\\\&quot;,\\\&quot;130\\\&quot;],&quot;
    + &quot;[\\\&quot;food_rice\\\&quot;,\\\&quot;80\\\&quot;]]\&quot;,\&quot;headers\&quot;:{\&quot;Access-Control-Allow-Origin\&quot;:\&quot;*\&quot;}}&quot;;
  Map map = objectMapper.readValue(str, Map.class);
  System.out.println(map);
//{statusCode=201, body=[[&quot;food_corn&quot;,&quot;48&quot;],[&quot;food_potatoes&quot;,&quot;130&quot;],[&quot;food_rice&quot;,&quot;80&quot;]], headers={Access-Control-Allow-Origin=*}}
}

答案2

得分: 0

将 JSON 解析为对象称为反序列化。您需要使用一些库来执行此操作。我建议使用 Jackson。https://github.com/FasterXML/jackson

下面的代码是一个示例,用于将 JSON 反序列化为类的对象。您需要定义一个包含所有字段的类,然后它将创建一个与 JSON 数据相对应的该类的对象。

public void deserializeData() {
  var mapper = new ObjectMapper();
  var json = "{\"statusCode\":201, \"body\":\"[[\"food_corn\",\"48\"],[\"food_potatoes\",\"130\"],[\"food_rice\",\"80\"]]\",
 \"headers\":{\"Access-Control-Allow-Origin\":\"*\"}}";
  var throwable = catchThrowable(() -> mapper.readValue(json, JSONBody.class));
  log.info("You need to use an empty constructor: {}", throwable.getMessage());
  assertThat(throwable).isInstanceOf(InvalidDefinitionException.class);
}

请注意,上面的 JSON 数据字符串中包含了一些转义字符(\)来转义双引号,以使其有效。如果您使用其他语言进行编程,可能需要进行适当的调整。

英文:

Parsing json to obj is called deserialization. You need to use some libarary to do this. I recommend Jackson. https://github.com/FasterXML/jackson

The below code is a sample to deserialize json into an object of a class. You need to define a class with all the fields then it will create an object of that class mapping to the json data.

    public void deserializeData() {
      var mapper = new ObjectMapper();
      var json = &quot;{\&quot;statusCode\&quot;:201,
     &quot;body&quot;:&quot;[[\&quot;food_corn\&quot;,\&quot;48\&quot;],[\&quot;food_potatoes\&quot;,\&quot;130\&quot;],[\&quot;food_rice\&quot;,\&quot;80\&quot;]]&quot;,
     &quot;headers&quot;:{&quot;Access-Control-Allow-Origin&quot;:&quot;*&quot;}}&quot;;
      var throwable = catchThrowable(() -&gt; mapper.readValue(json, JSONBody.class));
      log.info(&quot;You need to use an empty constructor: {}&quot;, throwable.getMessage());
      assertThat(throwable).isInstanceOf(InvalidDefinitionException.class);
    }

答案3

得分: 0

以下是翻译好的部分:

"Got it to work. Here's how I did it in case it helps anyone in the future.

(The 'invoke' variable is the response from invoking a lambda call form a lambda call within the same region.)

try {
     String decoded = new String(invoke.getPayload().array(), "UTF-8");
     HashMap<String, Object> map = new ObjectMapper().readValue(decoded, HashMap.class);
     String body = map.get("body").toString();
     JSONArray array = new JSONArray(body);

     Map<String, Integer> inventory = new HashMap<>();
     for (Integer i=0; i < array.length(); i++) {
         JSONArray tuple = array.getJSONArray(i);
         String itemName = tuple.getString(0);
         Integer itemCount = tuple.getInt(1);
         inventory.put(itemName, itemCount);
     }
     logger.log("COMPILED INVENTORY: "+inventory.toString()+"\n");
} catch (Exception e) {
     logger.log("EXCEPTION: "+e.getMessage()+"\n");
}
英文:

Got it to work. Here's how I did it in case it helps anyone in the future.

(The invoke variable is the response from invoking a lambda call form a lambda call within the same region.)

try {
     String decoded = new String(invoke.getPayload().array(), &quot;UTF-8&quot;);
     HashMap&lt;String, Object&gt; map = new ObjectMapper().readValue(decoded, HashMap.class);
     String body = map.get(&quot;body&quot;).toString();
     JSONArray array = new JSONArray(body);

     Map&lt;String, Integer&gt; inventory = new HashMap&lt;&gt;();
     for (Integer i=0; i &lt; array.length(); i++) {
         JSONArray tuple = array.getJSONArray(i);
         String itemName = tuple.getString(0);
         Integer itemCount = tuple.getInt(1);
         inventory.put(itemName, itemCount);
     }
     logger.log(&quot;COMPILED INVENTORY: &quot;+inventory.toString()+&quot;\n&quot;);
} catch (Exception e) {
     logger.log(&quot;EXCEPTION: &quot;+e.getMessage()+&quot;\n&quot;);
}

</details>



huangapple
  • 本文由 发表于 2020年8月12日 12:52:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63369982.html
匿名

发表评论

匿名网友

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

确定