使用杰克逊获取空的JSON

时间:2018-07-19 22:58:42

标签: java json jackson

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

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

例如:

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

我也不知道这个JSON中会有多少封电子邮件。对于您如何在不知道其属性名称的情况下如何通过Jackson接收所有这些电子邮件,我有些困惑,我想知道是否有可能。

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

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,我目前仍返回空结果。

2 个答案:

答案 0 :(得分:1)

如果JSON仅包含示例中给出的数据,则它对应于TypeReference<Map<String, Map<String, Boolean>>>,它基本上是字符串的映射到字符串到布尔的映射。解析器示例如下所示(不需要额外的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<Map<String, Map<String, Object>>>

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")); 
}

那会给

email:aaa@example.com, another_property: value 1
email:bbb@example.com, another_property: value 2

答案 1 :(得分:0)

  

我正在尝试解析这种格式的传入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]]