Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Jackson将Java列表序列化为XML和JSON_Java_Json_Xml_Jackson_Restlet - Fatal编程技术网

使用Jackson将Java列表序列化为XML和JSON

使用Jackson将Java列表序列化为XML和JSON,java,json,xml,jackson,restlet,Java,Json,Xml,Jackson,Restlet,在我基于Restlet的API中,使用Restlet-Jackson扩展,我试图将Java对象序列化为XML和JSON,但无法使用嵌套列表或多维数组获得我期望的格式(现有API已经发布) 以下是生成正确JSON的POJO: @JacksonXmlRootElement( localName = "table") @JsonInclude( JsonInclude.Include.NON_NULL) public class TableResponse { protected List da

在我基于Restlet的API中,使用Restlet-Jackson扩展,我试图将Java对象序列化为XML和JSON,但无法使用嵌套列表或多维数组获得我期望的格式(现有API已经发布)

以下是生成正确JSON的POJO:

@JacksonXmlRootElement( localName = "table")
@JsonInclude( JsonInclude.Include.NON_NULL)
public class TableResponse {

  protected List data;
  protected String[] columns;

  public TableResponse( String[] columns, List<List<String>> data ) {
    this.columns = columns;
    this.data = data;
  }

  @JacksonXmlElementWrapper(localName = "data")
  @JacksonXmlProperty(localName = "row")
//@CanIAddSomeAnnotationHereForNestedListElements?
  public List<List<String>> getData() {
    return data;
  }

  @JacksonXmlElementWrapper(localName = "columns")
  @JacksonXmlProperty(localName = "column")
  public String[] getColumns() {
    return columns;
  }
}
我希望能够像这样生成XML:

{
  "data": [
    [
      "Row 1 Cell A",
      "Row 1 Cell B"
    ],
    [
      "Row 2 Cell A",
      "Row 2 Cell B"
    ],
    [
      "Row 3 Cell A",
      "Row 3 Cell B"
    ]
  ],
  "columns": [
    "Column 1",
    "Column 2"
  ]
}
<table>
    <data>
        <row>
          <value>Row 1 Cell A</value>
          <value>Row 1 Cell B</value>
        </row>
        <row>
          <value>Row 2 Cell A</value>
          <value>Row 2 Cell B</value>
        </row>
        <row>
          <value>Row 3 Cell A</value>
          <value>Row 3 Cell B</value>
        </row>
    </data>
    <columns>
        <column>Column 1</column>
        <column>Column 2</column>
    </columns>
</table>
我的项目中的一些依赖项包括:

  • dataformat:jackson-dataformat-xml:2.5.3
  • org.restlet.jee:org.restlet:2.3.5
  • org.restlet.jee:org.restlet.ext.jackson:2.3.5
  • org.restlet.jee:org.restlet.ext.json:2.3.5
有没有一种方法可以让嵌套列表以我所期望的方式在第一个POJO结构的JSON和XML之间工作?多维JSON数组比包装每个列表的对象更易于使用,并且是此API的现有已发布规范


顺便说一句,我在中也尝试了这个建议,但没有让我的XmlAdapter/@XmlJavaTypeAdapter在这里与restlet一起使用。

仅使用Jackson注释似乎很难处理这两种格式。对于您的用例,我认为您需要实现一个单独处理JSON和XML的自定义序列化程序

此序列化程序如下所示:

public class TableResponseSerializer extends StdSerializer<TableResponse> {
    private MediaType mediaType;

    public TableResponseSerializer(MediaType mediaType) {
        super(TableResponse.class);
        this.mediaType = mediaType;
    }

    private void serializeJson(TableResponse swe, 
            JsonGenerator jgen,
            SerializerProvider sp) throws IOException, JsonGenerationException {
        (...) 
    }

    private void serializeXml(TableResponse swe, 
            JsonGenerator jgen,
            SerializerProvider sp) throws IOException, JsonGenerationException {
       (...)        
    }

    @Override
    public void serialize(TableResponse swe, 
                          JsonGenerator jgen,
                          SerializerProvider sp) throws IOException, JsonGenerationException {
        if (mediaType.equals(MediaType.APPLICATION_JSON)) {
            serializeJson(swe, jgen, sp);
        } else if (mediaType.equals(MediaType.TEXT_XML)) {
            serializeXml(swe, jgen, sp);
        }
    }
}
然后是
CustomJacksonConverter
类,该类将在必要时使用这种表示:

public class CustomJacksonConverter extends JacksonConverter {
    protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) {
        return new CustomJacksonRepresentation<T>(mediaType, source);
    }

    protected <T> JacksonRepresentation<T> create(Representation source,
             Class<T> objectClass) {
        return new CustomJacksonRepresentation<T>(source, objectClass);
    }
}

这样,您将根据内容协商(
Accept
header)获得XML和JSON所需的输出内容。

我习惯于处理GSON以创建JSON字符串,因此我只能就此发言。根据我的经验,我不得不对各种数据类型进行大量实验,以获得我想要的数据,并发现HashMaps或LinkedHashMaps以及ArrayList的组合效果最好。您可能需要对这些进行实验,以查看jackson的结果。嗨,Thierry,我能问一下如何强制Restlet使用XStream而不是jackson吗?
{
  "data": [
    {
      "values": [
        "Row 1 Cell A",
        "Row 1 Cell B"
      ]
    },
    {
      "values": [
        "Row 2 Cell A",
        "Row 2 Cell B"
      ]
    },
    {
      "values": [
        "Row 3 Cell A",
        "Row 3 Cell B"
      ]
    }
  ],
  "columns": [
    "Column 1",
    "Column 2"
  ]
}
public class TableResponseSerializer extends StdSerializer<TableResponse> {
    private MediaType mediaType;

    public TableResponseSerializer(MediaType mediaType) {
        super(TableResponse.class);
        this.mediaType = mediaType;
    }

    private void serializeJson(TableResponse swe, 
            JsonGenerator jgen,
            SerializerProvider sp) throws IOException, JsonGenerationException {
        (...) 
    }

    private void serializeXml(TableResponse swe, 
            JsonGenerator jgen,
            SerializerProvider sp) throws IOException, JsonGenerationException {
       (...)        
    }

    @Override
    public void serialize(TableResponse swe, 
                          JsonGenerator jgen,
                          SerializerProvider sp) throws IOException, JsonGenerationException {
        if (mediaType.equals(MediaType.APPLICATION_JSON)) {
            serializeJson(swe, jgen, sp);
        } else if (mediaType.equals(MediaType.TEXT_XML)) {
            serializeXml(swe, jgen, sp);
        }
    }
}
private void serializeJson(TableResponse swe, 
        JsonGenerator jgen,
        SerializerProvider sp) throws IOException, JsonGenerationException {
    jgen.writeStartObject();      

    // Data
    jgen.writeArrayFieldStart("data");
    for (List<String> row : swe.getData()) {
        jgen.writeStartArray();
        for (String rowElt : row) {
            jgen.writeString(rowElt);
        }
        jgen.writeEndArray();
    }
    jgen.writeEndArray();

    // Columns
    jgen.writeArrayFieldStart("columns");
    for (String column : swe.getColumns()) {
        jgen.writeString(column);
    }
    jgen.writeEndArray();

    jgen.writeEndObject();
}
private void serializeXml(TableResponse swe, 
        JsonGenerator jgen,
        SerializerProvider sp) throws IOException, JsonGenerationException {

    jgen.writeStartObject();      

    // Data
    jgen.writeObjectFieldStart("data");
    jgen.writeArrayFieldStart("row");
    for (List<String> row : swe.getData()) {
        jgen.writeStartObject();
        jgen.writeArrayFieldStart("value");
        for (String rowElt : row) {
            jgen.writeString(rowElt);
        }
        jgen.writeEndArray();
        jgen.writeEndObject();
    }
    jgen.writeEndArray();
    jgen.writeEndObject();

    // Columns
    jgen.writeObjectFieldStart("columns");
    jgen.writeArrayFieldStart("column");
    for (String column : swe.getColumns()) {
        jgen.writeString(column);
    }
    jgen.writeEndArray();
    jgen.writeEndObject();

    jgen.writeEndObject();
}
public class CustomJacksonRepresentation<T> extends JacksonRepresentation<T> {
    public CustomJacksonRepresentation(MediaType mediaType, T object) {
        super(mediaType, object);
    }

    public CustomJacksonRepresentation(Representation representation,
                         Class<T> objectClass) {
        super(representation, objectClass);
    }

    public CustomJacksonRepresentation(T object) {
        super(object);
    }

    @Override
    protected ObjectMapper createObjectMapper() {
        ObjectMapper objectMapper = super.createObjectMapper();

        if (getObjectClass().equals(TableResponse.class)) {
            SimpleModule mod = new SimpleModule("");    
            mod.addSerializer(new TableResponseSerializer(getMediaType())); 
            objectMapper.registerModule(mod);
        }

        return objectMapper;
    }
}
public class CustomJacksonConverter extends JacksonConverter {
    protected <T> JacksonRepresentation<T> create(MediaType mediaType, T source) {
        return new CustomJacksonRepresentation<T>(mediaType, source);
    }

    protected <T> JacksonRepresentation<T> create(Representation source,
             Class<T> objectClass) {
        return new CustomJacksonRepresentation<T>(source, objectClass);
    }
}
List<ConverterHelper> converters = Engine.getInstance().getRegisteredConverters();
JacksonConverter jacksonConverter = new JacksonConverter();
for (ConverterHelper converter : converters) {
    if (converter instanceof JacksonConverter) {
        jacksonConverter = (JacksonConverter) converter;
        break;
    }
}

if (jacksonConverter!=null) {
    converters.remove(jacksonConverter);
    converters.add(new CustomJacksonConverter());
}