【问题标题】:Trying to create json object in Java but getting nested array? How to do it in a better way?试图在 Java 中创建 json 对象但得到嵌套数组?如何以更好的方式做到这一点?
【发布时间】:2018-12-31 14:02:22
【问题描述】:

我正在尝试得到这个输出:

{
   "columnNames":[
      "fruit"
   ],
   "values":[
      [
         "Apple is green"
      ]
   ],
   "time":"2017-12-11T00:00:00Z"
}

但我最终得到以下...

{
   "columnNames":[
      "fruit"
   ],
   "values":[
      [
         {
            "stringValue":"Apple is green",
            "intValue":0,
            "booleanValue":false
         }
      ]
   ],
   "time":null
}

这是我的代码(到目前为止),如果您能告诉我哪里出错了,我将不胜感激?

public static void main(String[] args) {
    List<String> columnNames = new ArrayList<>();
    columnNames.add("fruit");
    List<List<ResponseValues>> responseValues = new ArrayList<>();
    List<ResponseValues> values = Collections.singletonList(new ResponseValues("Apple is green"));
    responseValues.add(values);

    String expectedResult = createAJson(columnNames, responseValues);
    System.out.println(expectedResult);
}


public static String createAJson(List<String> columnNames, List<List<ResponseValues>> values) {
    String jsonBlock = "";
    repBuilder repBuilder = new repBuilder();
    ObjectMapper mapper = new ObjectMapper();

    repBuilder.setColumnNames(columnNames);
    repBuilder.setValues(values);

    try {
        jsonBlock = mapper.writeValueAsString(repBuilder);
    }
    catch (JsonProcessingException e) {
        e.printStackTrace();
    }
    return jsonBlock;
}

还有一些用于创建响应值部分的样板代码:

@JsonPropertyOrder({
"columnNames",
"values",
"time"
})

public class RepBuilder {

    public List<String> columnNames;
    public List<List<ResponseValues>> values;
    private String time;

    @JsonProperty("columnNames")
    public List<String> getColumnNames() {
        return columnNames;
    }

    @JsonProperty("columnNames")
    public void setColumnNames(List<String> columnNames) {
        this.columnNames = columnNames;
    }

    @JsonProperty("values")
    public List<List<ResponseValues>> getValues() {
        return values;
    }

    @JsonProperty("values")
    public void setValues(List<List<ResponseValues>> values) {
        this.values = values;
    }

    @JsonProperty("time")
    public String gettime() {
        return time;
    }

    @JsonProperty("time")
    public void settime(String time) {
        this.time = time;
    }

}

还有响应值:这样做是为了让我可以设置 STRING 或 INTEGER 或 BOOLEAN 并添加到列表中?

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseValues {

    private String stringValue;
    private int intValue;
    private boolean booleanValue;

    public ResponseValues(String stringValue) {
        this.stringValue = stringValue;
    }

    public ResponseValues(int intValue) {
        this.intValue = intValue;
    }

    public ResponseValues(boolean booleanValue) {
        this.booleanValue = booleanValue;
    }

    public String getStringValue() {
        return stringValue;
    }

    public void setStringValue(String stringValue) {
        this.stringValue = stringValue;
    }

    public int getIntValue() {
        return intValue;
    }

    public void setIntValue(int intValue) {
        this.intValue = intValue;
    }

    public boolean getBooleanValue() {
        return booleanValue;
    }

    public void setBooleanValue(boolean booleanValue) {
        this.booleanValue = booleanValue;
    }
}

谁能指出我错过了什么?我也尝试使用@JsonProperty(access = JsonProperty.Access.WRITE_ONLY),但这对我不起作用,还有其他想法吗? 如果您在回答的上下文中使用我的代码,我将不胜感激(因为我仍在学习 java)

【问题讨论】:

  • 你从来没有设置时间,所以它是空的。你有一个 List> 虽然你想要一个 List>。所以你最终在 JSON 中作为一个包含对象数组的数组而不是包含字符串数组的数组。

标签: java arrays json list jackson


【解决方案1】:

ResponseValues自定义一个序列化器,例如:

public class ResponseSerializer extends JsonSerializer<ResponseValues>{ 

    @Override
    public void serialize(ResponseValues responseValues, JsonGenerator gen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {

        gen.writeString(responseValues.getStringValue());
    }

}

并将其与注释一起使用:

@JsonSerialize(using = ResponseSerializer.class)
public class ResponseValues

更新

如果需要按顺序检查,可以这样:

@Override
public void serialize(ResponseValues responseValues, JsonGenerator gen,
        SerializerProvider provider) throws IOException,
        JsonProcessingException {

    String stringValue = responseValues.getStringValue();
    if (stringValue != null) {
        gen.writeString(responseValues.getStringValue());
        return; // if string value is valid, write it and return
    }

    int intValue = responseValues.getIntValue();
    // let's suppose 0 is not a valid status
    if (intValue != 0) { 
        gen.writeNumber(intValue);
        return;
        // also you can use gen.writeString(String.valueOf(intValue)); if you need a String
    }

    boolean booleanValue = responseValues.getBooleanValue();
    gen.writeBoolean(booleanValue);

}

【讨论】:

  • 确实做到了这一点,但对于 columnNames 和 values 却没有得到任何值?{ "columnNames":[ ], "values":[ ], "time":null }
  • @Saffik 真的吗?我得到{"columnNames":["fruit"],"values":[["Apple is green"]],"time":null}
  • 是的,我得到空值,如果我选择不使用getStringValue 而是选择getIntValuegetBooleanValue,这也可以工作
  • @Saffik 您发布的代码无法编译。看来你应该用responseValues.add(values); 替换values.add(values); 并使createAJson 静态。所以它编译并输出{"columnNames":["fruit"],"values":[["Apple is green"]],"time":null}
  • 好的 - 根据您的建议,它会起作用。不过还有一件事.. 如果我在 main 方法中执行以下操作:List&lt;ResponseValues&gt; values = Collections.singletonList(new ResponseValues(4)); - 这行不通?因为 ResponseSerializer 只写 getStringValue?知道如何使它适用于 getIntValue 和 getBooleanValue 吗?
【解决方案2】:
private int intValue;
private boolean booleanValue;

这些(int,boolean)是原语,因此默认情况下它们分别使用默认值 0 和 false 进行初始化。你可以使用

private Integer intValue;
private Boolean booleanValue;

并配置 writer 忽略空值。 另外,我看不到您在哪里设置“时间”。由于它是 String 类型,因此在您的输出中默认为 null。

由于你正在学习java,最后来建议,

  • 类名以大写字母开头。更改repBuilder -&gt; RepBuilder
  • 我喜欢您的 Collections.singletonList() 并且您的努力在您的问题中显而易见。继续成长!

【讨论】:

  • 我会的,谢谢你的推荐。不过有一件事,我如何告诉作家忽略空值?我用@JsonInclude(JsonInclude.Include.NON_NULL)吗?
  • 没错!此外,你有一个 List> 虽然你想要一个 List> 正如@JB Nizet 在 cmets 中提到的那样
  • 阿汉。上面忽略空值,我仍然得到com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException)
  • 请发布您得到的完整异常
  • 好的 - 现在看看。尝试一些事情...... :)
猜你喜欢
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 2021-09-19
  • 2010-12-08
相关资源
最近更新 更多