【问题标题】:Getting empty JSON using Jackson [duplicate]使用杰克逊获取空 JSON [重复]
【发布时间】:2018-07-19 22:58:42
【问题描述】:

现在我正在尝试解析这种格式的传入 JSON:

{
  <email>: {
    <name>: <string>,     # setting value
     ...
  },
  ...
}

例如:

{
 "aaa@example.com": {
   "statement": true
 },
 "bbb@example.com": {
   "statement": false
 }
}

我也不知道这个 JSON 中有多少电子邮件。我有点困惑,您如何在不知道其属性名称的情况下收到杰克逊的所有这些电子邮件,我想知道这是否可能。

到目前为止,这是我的代码:

public class GDPRConsent extends Model {
@JsonIgnore
private static final String GDPR_CONSENT = "gdprConsent";

private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty
private ArrayList<String> emails;

@JsonProperty("serviceDataCollection")
private String dataCollection;

@JsonProperty("serviceDataCollection")
public String getDataCollectionConsent() {
    return dataCollection;
}

@JsonProperty
public ArrayList<String> getEmails() {
    return emails;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
    return this.additionalProperties;
}

@Override
public String getId() {
    return GDPR_CONSENT;
}

}

这是我的解析器:

public static <T> T parseObject(String sourceJson, Class<T> classToParse) {
    T parsedObject = null;
    try {
        parsedObject = sObjectMapper.readValue(sourceJson, classToParse);
    } catch (JsonParseException e) {
        LogUtils.d(LOG_TAG, "parseObject JsonParseException: " + e.toString());
    } catch (JsonMappingException e) {
        LogUtils.d(LOG_TAG, "parseObject JsonMappingException: " + e.toString());
    } catch (IOException e) {
        LogUtils.d(LOG_TAG, "parseObject IOException: " + e.toString());
    }
    return parsedObject;
}

尽管我知道 JSON 正在传入,但我目前返回的结果为空。

【问题讨论】:

  • 是否记录了任何异常?

标签: java json jackson


【解决方案1】:

如果您的 JSON 仅包含示例中给出的数据,则它对应于 TypeReference&lt;Map&lt;String, Map&lt;String, Boolean&gt;&gt;&gt;,它基本上是字符串到字符串到布尔值的映射。示例解析器如下所示(不需要额外的 POJO):

import java.io.IOException;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JSONParser {

    static final String TEST_JSON = "{"
            +" \"aaa@example.com\": {"
            +"  \"statement\": true"
            +"},"
            +"\"bbb@example.com\": {"
            +"  \"statement\": false"
            +"}"
            +"}";


    public static void main (String... args) {

        ObjectMapper mapper = new ObjectMapper();

        try {
            Map<String, Map<String, Boolean>> jsonAsNestedMap = mapper.readValue(
                    TEST_JSON, new TypeReference<Map<String, Map<String, Boolean>>>() {
            });
            System.out.println(jsonAsNestedMap);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }        
    }

}

这将打印出来

{aaa@example.com={statement=true}, bbb@example.com={statement=false}}

如果你的 JSON 最里面的值更复杂,那么你可以使用TypeReference&lt;Map&lt;String, Map&lt;String, Object&gt;&gt;&gt;:

static final String TEST_JSON = "{"
            +" \"aaa@example.com\": {"
            +"  \"statement\": true,"
            +"  \"another_property\" : \"value 1\"" 
            +"},"
            +"\"bbb@example.com\": {"
            +"  \"statement\": false,"
            +"  \"another_property\" : \"value 2\"" 
            +"}"
            +"}";    
//...    
public static void main (String... args) {
    //...
    Map<String, Map<String, Object>> jsonAsNestedMap = mapper.readValue(
                    TEST_JSON, new TypeReference<Map<String, Map<String, Object>>>() {

        });
//...
}

可以通过法线贴图迭代和访问器方法访问单个属性:

for (Entry<String, Map<String, Object>> e : jsonAsNestedMap.entrySet()) {
    System.out.println("email:" + e.getKey() + ", another_property: " 
        + e.getValue().get("another_property")); 
}

这会给

电子邮件:aaa@example.com,another_property:值 1 电子邮件:bbb@example.com,another_property:值 2

【讨论】:

  • 嘿,米克,你知道如何按照另一个答案提出的方式来做,以及我在帖子中的做法,即使用@JsonPropertys 和诸如此类的东西将它作为自己的类。有可能这样做吗?
  • 你可以看看this questionJsonAnySetter 方法(Andreas 也提到过)。今天晚些时候我可以尝试提出另一个完整的示例。
【解决方案2】:

我正在尝试解析这种格式的传入 JSON

正如您在duplicate question 中已经解释的那样,您可以解析为Map

public class EmailData {
    private boolean statement;
    public boolean isStatement() {
        return this.statement;
    }
    public void setStatement(boolean statement) {
        this.statement = statement;
    }
    @Override
    public String toString() {
        return "EmailData[statement=" + this.statement + "]";
    }
}

测试

String json = "{" +
                "\"aaa@example.com\": {" +
                  "\"statement\": true" +
                "}," +
                "\"bbb@example.com\": {" +
                  "\"statement\": false" +
                "}" +
              "}";

ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, EmailData>> typeRef = new TypeReference<>() {/**/};
HashMap<String, EmailData> emails = mapper.readValue(json, typeRef);
System.out.println(emails);

输出

{aaa@example.com=EmailData[statement=true], bbb@example.com=EmailData[statement=false]}

如果您更喜欢@JsonAnySetter 方法,您可以这样做:

public class Content {
    private List<EmailData> emailData = new ArrayList<>();
    @JsonAnySetter
    public void addEmail(String name, EmailData value) {
        value.setEmail(name);
        this.emailData.add(value);
    }
    @Override
    public String toString() {
        return this.emailData.toString();
    }
}
public class EmailData {
    private String email;
    private boolean statement;
    @JsonIgnore
    public String getEmail() {
        return this.email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public boolean isStatement() {
        return this.statement;
    }
    public void setStatement(boolean statement) {
        this.statement = statement;
    }
    @Override
    public String toString() {
        return "EmailData[email=" + this.email + ", statement=" + this.statement + "]";
    }
}

测试

String json = "{" +
                "\"aaa@example.com\": {" +
                  "\"statement\": true" +
                "}," +
                "\"bbb@example.com\": {" +
                  "\"statement\": false" +
                "}" +
              "}";

ObjectMapper mapper = new ObjectMapper();
Content content = mapper.readValue(json, Content.class);
System.out.println(content);

输出

[EmailData[email=aaa@example.com, statement=true], EmailData[email=bbb@example.com, statement=false]]

【讨论】:

    猜你喜欢
    • 2015-03-20
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多