Java 如何在将 JSON 解析为地图时忽略特定字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32196027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:08:06  来源:igfitidea点击:

How to ignore a specific field while parsing a JSON into map

javajsonHymanson

提问by sag

I want to parse the below JSON into POJO. I am using Hymanson to parse the json.

我想将下面的 JSON 解析为 POJO。我正在使用 Hymanson 来解析 json。

{
  "totalSize": 4,
  "done": true,
  "records": [
    {
      "attributes": {
        "type": "oppor",
        "url": "/service/oppor/456"
      },
      "AccountId": "123",
      "Id": "456",
      "ProposalID": "103"
    }
  ]
}

In the above JSON, the fields "totalSize", "done", "records" and "attributes" are known fields. Whereas, "AccountId", "Id" and "ProposalID" are unknown fields. And in the above JSON, I don't need "attributes" to be part of my bean object.

在上面的 JSON 中,字段“totalSize”、“done”、“records”和“attributes”是已知字段。而“AccountId”、“Id”和“ProposalID”是未知字段。在上面的 JSON 中,我不需要“属性”作为 bean 对象的一部分。

And here is equivalent bean class for my JSON

这是我的 JSON 的等效 bean 类

public class Result {
    private int totalSize;
    private boolean done;
    private List<Map<String, String>> records;

    public int getTotalSize() {
        return totalSize;
    }

    public void setTotalSize(int totalSize) {
        this.totalSize = totalSize;
    }

    public boolean isDone() {
        return done;
    }

    public void setDone(boolean done) {
        this.done = done;
    }

    public List<Map<String,String>> getRecords() {
        return records;
    }

    public void setRecords(List<Map<String, String>> records) {
        this.records = records;
    }

}

Hence there are unknown fields in the records element I just used List to get the results element in bean. Here in this Map, I don't want the field "attributes". How can I ignore this while parsing? And below is the exception that I am getting as attributes is not a string element.

因此,记录元素中有未知字段,我只是使用 List 来获取 bean 中的结果元素。在这张地图中,我不想要“属性”字段。解析时如何忽略它?下面是我得到的例外,因为属性不是字符串元素。

com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: [B@66fdec9; line: 1, column: 40] (through reference chain: com.sample.json.Result["records"])
    at com.fasterxml.Hymanson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.Hymanson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
    at com.fasterxml.Hymanson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:46)
    at com.fasterxml.Hymanson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
    at com.fasterxml.Hymanson.databind.deser.std.MapDeserializer._readAndBindStringMap(MapDeserializer.java:430)
    at com.fasterxml.Hymanson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:312)
    at com.fasterxml.Hymanson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
    at com.fasterxml.Hymanson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:227)
    at com.fasterxml.Hymanson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:204)
    at com.fasterxml.Hymanson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)

采纳答案by BNK

UPDATE 2015/08/29:

更新 2015/08/29:

As you have commented that

正如你所评论的那样

I achieved dynamic field support by parsing the JSON into map. Ignoring bad JSON element is what pending

我通过将 JSON 解析为 map 来实现动态字段支持。忽略坏的 JSON 元素是待定的

I suggest that you should process original JSONObject to remove the "attributes"element from it.

我建议您应该处理原始 JSONObject 以从中删除"attributes"元素。

Original JSONObject, for example:

原始 JSONObject,例如:

{
  "totalSize": 4,
  "done": true,
  "records": [
    {
      "attributes": {
        "type": "oppor",
        "url": "/service/oppor/456"
      },
      "AccountId": "123",
      "Id": "456",
      "ProposalID": "103"
    }
  ]
}

After process, new JSONObject will be like the following:

处理后,新的 JSONObject 将如下所示:

{
    "records": {
        "AccountId": "123",
        "Id": "456",
        "ProposalID": "103"
    },
    "totalSize": 4,
    "done": true
}

Use the code as the following:

使用代码如下:

        JSONObject jsonObject;
        try {            
            jsonObject = new JSONObject(jsonString1);
            JSONArray jsonArray = new JSONArray(jsonObject.get("records").toString());            
            JSONObject jsonObject1 = jsonArray.getJSONObject(0);
            jsonObject1.remove("attributes");
            jsonObject.put("records", jsonObject1);
        } catch (JSONException e) {
            e.printStackTrace();
        }

Then, use your own code that achieved dynamic field support by parsing the JSON into map.

然后,使用您自己的代码achieved dynamic field support by parsing the JSON into map

END OF UPDATE 2015/08/29

更新结束 2015/08/29

I suggest that you use Gsonand transientin this case

我建议你使用Gson,并transient在这种情况下,

Like this

像这样

        String jsonString1 = "{\n" +
                "  \"totalSize\": 4,\n" +
                "  \"done\": true,\n" +
                "  \"records\": [\n" +
                "    {\n" +
                "      \"attributes\": {\n" +
                "        \"type\": \"oppor\",\n" +
                "        \"url\": \"/service/oppor/456\"\n" +
                "      },\n" +
                "      \"AccountId\": \"123\",\n" +
                "      \"Id\": \"456\",\n" +
                "      \"ProposalID\": \"103\"\n" +
                "    }\n" +
                "  ]\n" +
                "}";

        Gson gson = new Gson();
        Result result1 = gson.fromJson(jsonString1, Result.class);

Your classes, pay attention to transient:

你的课,注意transient

public class Result {
    private int totalSize;
    private boolean done;
    private List<Record> records;
}

public class Record {
    private transient Map<String, String> attributes;
    private int AccountId;
    private int Id;
    private int ProposalID;
}

You will get the result:

你会得到结果:

enter image description here

在此处输入图片说明

P/S: I tested in Android Studio :)

P/S:我在 Android Studio 中测试过 :)

UPDATE:

更新:

      String jsonString1 = "{\n" +
                "  \"totalSize\": 4,\n" +
                "  \"done\": true,\n" +
                "  \"records\": [\n" +
                "    {\n" +
                "      \"attributes\": {\n" +
                "        \"type\": \"oppor\",\n" +
                "        \"url\": \"/service/oppor/456\"\n" +
                "      },\n" +
                "      \"AccountId\": \"123\",\n" +
                "      \"Id\": \"456\",\n" +
                "      \"ProposalID\": \"103\"\n" +
                "    }\n" +
                "  ]\n" +
                "}";
        Gson gson = new Gson();
        Object object = gson.fromJson(jsonString1, Object.class);
        Map<String, String> stringMap = (Map<String, String>) object;
        Result myResult = new Result();
        Iterator entries = stringMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry entry = (Map.Entry) entries.next();
            String key = entry.getKey().toString();
            String value = entry.getValue().toString();
            switch (key) {
                case "totalSize":
                    myResult.totalSize = (int) Double.parseDouble(entry.getValue().toString());
                    break;
                case "done":
                    myResult.done = Boolean.valueOf(entry.getValue().toString());
                    break;
                case "records":
                    try{
                        Object object1 = entry.getValue();
                        List<Object> objectList = (List<Object>) object1;
                        Map<String, Object> stringMap2 = (Map<String, Object>) objectList.get(0);
                        Map<String, String> recordMap = new HashMap<>();
                        Iterator entries2 = stringMap2.entrySet().iterator();
                        while (entries2.hasNext()) {
                            Map.Entry entry2 = (Map.Entry) entries2.next();
                            String key2 = entry2.getKey().toString();
                            String value2 = entry2.getValue().toString();
                            if (!"attributes".equals(key2)) {
                                recordMap.put(key2, value2);
                            }
                            entries2.remove();
                        }
                        myResult.records = recordMap;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
            }
            entries.remove();
        }

Classes:

课程:

public class Result {
    private int totalSize;
    private boolean done;
    private Map<String, String> records;        
}

Debug result:

调试结果:

enter image description here

在此处输入图片说明

回答by Ajeesh

Create a new POJO class for attributes,

为属性创建一个新的 POJO 类,

public class Result {
    private int totalSize;
    private boolean done;
    private List<Attributes> records;

    // Your Getters & Setters
}

public class Attributes{
    List<Map<String,String>> attributes;
    // Add other variables if necessary like AccountId, etc.,

    // Your Getters & Setters
}

回答by biology.info

1) Create a Record class object

1)创建一个Record类对象

2) Add @JsonIgnore Annotation on fields you won't

2)在你不会的字段上添加@JsonIgnore Annotation

public class Result {
    private int totalSize;
    private boolean done;
    private Record records;

[..]

}


public class Record {
    @JsonIgnore
    private Map<String, String> attributes;
    private int accountID;
    private int id;
    private int approvalID;

[..]

}

回答by Ashish Patil

I would suggest to use [Google gson API][1]'s @Expose annotation.(if that is allowed in your environment).

我建议使用[Google gson API][1] 的 @Expose 注释。(如果您的环境允许这样做)。

You can simply annotate the fields(with @Expose) which are required in your generated json file, and leave it other fields. And during generating json, use API method, excludeFieldsWithoutExposeAnnotation.

您可以简单地注释@Expose生成的 json 文件中所需的字段(使用),并将其保留为其他字段。并且在生成json时,使用API​​方法,excludeFieldsWithoutExposeAnnotation.

Sample example can be seen here.

示例示例可以在这里看到。

Note: In your example, treat your Resultas Main POJO, and recordsis another POJO which has attributes,accountIdetc fields. Then there is has-a relationship (Java composition) between them.

:在你的榜样,对待你的Result作为主要POJO,并且records是另一个POJO拥有attributesaccountId等领域。然后它们之间存在 has-a 关系(Java 组合)。

And after that, you can invoke Json to pojo conversion like below--

之后,您可以调用 Json 进行 pojo 转换,如下所示 -

com.google.gson.Gson gson = new com.google.gson.GsonBuilder()
                    .excludeFieldsWithoutExposeAnnotation().create();

 Result result= gson.fromJson(yourjsonString, Result.class);