代码之家  ›  专栏  ›  技术社区  ›  Saffik

试图在Java中创建JSON对象,但得到嵌套数组?如何以更好的方式做到这一点?

  •  0
  • Saffik  · 技术社区  · 6 年前

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

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

    和响应值:这样做是为了设置字符串、整数或布尔值并添加到列表?

    @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),我将不胜感激。

    2 回复  |  直到 6 年前
        1
  •  1
  •   xingbin    6 年前

    为自定义序列化程序 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);
    
    }
    
        2
  •  1
  •   Mohamed Anees A    6 年前
    private int intValue;
    private boolean booleanValue;
    

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

    private Integer intValue;
    private Boolean booleanValue;
    

    并将编写器配置为忽略空值。 另外,我不知道你在哪里设定“时间”。因为它是字符串类型,所以在输出中默认为空。

    在你学习Java的最后一个建议

    • 以大写字母开头。更改 repBuilder -> RepBuilder
    • 我喜欢你的收藏。singletonlist(),你的努力在你的问题中很明显。继续成长!