杰克逊序列化csv属性订单

时间:2016-04-29 11:16:36

标签: java csv serialization jackson fasterxml

我们有一个包含350多列的表格。生成pojo类并且getter命令搞砸了。试图使用来自jackson的csvmapper,但它会根据getter顺序生成csv。 @JsonPropertyOrder因许多列而无法使用。我们在xml中维护列排序,并且可以在运行时生成字段顺序数组。我们可以在运行时覆盖为属性排序提供字段名数组吗?我们可以使用注释introspector进行自定义吗?

4 个答案:

答案 0 :(得分:2)

以防万一,您要在2020年到达这里,直接来自documentation

那么,如何获得要使用的CSV模式实例?有3种方法:

  • 基于Java类创建架构
  • 手动构建模式。
  • 使用CSV文档的第一行获取Schema的名称(无类型) 是上述情况的代码:
// Schema from POJO (usually has @JsonPropertyOrder annotation)
CsvSchema schema = mapper.schemaFor(Pojo.class);

// Manually-built schema: one with type, others default to "STRING"
CsvSchema schema = CsvSchema.builder()
        .addColumn("firstName")
        .addColumn("lastName")
        .addColumn("age", CsvSchema.ColumnType.NUMBER)
        .build();

// Read schema from the first line; start with bootstrap instance
// to enable reading of schema from the first line
// NOTE: reads schema and uses it for binding
CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
ObjectMapper mapper = new CsvMapper();
mapper.readerFor(Pojo.class).with(bootstrapSchema).readValue(json);

答案 1 :(得分:1)

我相信你唯一的选择是uniVocity-parsers,因为它允许你选择要写的列和顺序:

CsvWriterSettings settings = new CsvWriterSettings();
// Sets the file headers (used for selection only, these values won't be written automatically)
settings.setHeaders("Year", "Make", "Model", "Description", "Price");

// Selects which fields from the input should be written. In this case, fields "make" and "model" will be empty
// The field selection is not case sensitive
settings.selectFields("description", "price", "year");

//configures the writer process java beans with annotations (assume TestBean has a few annotated fiedls)
settings.setRowWriterProcessor(new BeanWriterProcessor<TestBean>(TestBean.class));

// Creates a writer with the above settings;
CsvWriter writer = new CsvWriter(new File("/path/to/output.csv"), settings);

// Writes the headers specified in the settings
writer.writeHeaders();

//creates a bean instance for writing
TestBean bean = new TestBean();
bean.setPrice(new BigDecimal("500.33"));
bean.setDescription("Blah,blah");
bean.setYear(1997);

//writes it
writer.processRecord(bean);

writer.close();

希望它有所帮助。

披露:我是这个图书馆的作者,它是开源和免费的(Apache 2.0许可证)

答案 2 :(得分:0)

请注意,@JsonPropertyOrder不一定要包含所有属性,只需要包含序列化属性。但要指明要序列化的内容,您可能需要结合使用@JsonProperty(表示要序列化的属性)和包含的不同可见性(默认情况下通过ObjectMapper.setVisibility()@JsonAutoDetect对于每个POJO)。

但假设您不想使用@JsonPropertyOrder,您可以:

  1. 覆盖注释注释的JacksonAnnotationIntrospector中的方法,提供使用其他来源的自己的实现(根本不需要来自注释)
  2. 如果使用Jackson 2.8.0,有一种新方法可以指定某些内容的每类默认值(请参阅ObjectMapper.configOverride()对象),包括属性顺序
  3. 同样,如果要使用自定义条件进行包含/排除,则可以覆盖查找@JsonPropertyfindNameForDeserialization()和/或findNameForSerialization())的方法。 还有其他包含/排除机制,如JSON视图(@JsonView),JSON过滤器。

答案 3 :(得分:0)

您要寻找的东西称为MappingFeature。您需要禁用默认的字母数字属性排序:

CsvMapper mapper = new CsvMapper();
mapper.disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

有关此的更多信息,您可以在这里找到:Add a feature in CsvSchema to allow definition of ordering #42