简体   繁体   English

jackson 序列化 csv 属性顺序

[英]jackson serialize csv property order

we have a table with 350+ columns.我们有一个包含 350 多列的表。 pojo class is generated and getters order get messed up.生成了 pojo 类并且 getter 的顺序被搞乱了。 trying to use csvmapper from jackson, but it generates csv based on getter order.尝试使用 jackson 的 csvmapper,但它根据 getter 顺序生成 csv。 @JsonPropertyOrder is also not use feasible because of many columns.we maintain column ordering in xml and can generate field order array at runtime. @JsonPropertyOrder 也不能使用,因为有很多列。我们在 xml 中维护列排序,并且可以在运行时生成字段顺序数组。 can we override at runtime to provide array of fieldnames for property ordering?我们可以在运行时覆盖以提供用于属性排序的字段名数组吗? can we customize using annotation introspector?我们可以使用注释内省器进行自定义吗?

What you are looking for is called a MappingFeature.您正在寻找的称为 MappingFeature。 You need to disable alphanumeric sorting of properties, which is enabled by default:您需要禁用属性的字母数字排序,默认情况下启用:

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

More on this you can find here: Add a feature in CsvSchema to allow definition of ordering #42有关更多信息,您可以在此处找到: CsvSchema添加一个功能以允许定义排序 #42

Just in case you get here in 2020, this comes straight from the documentation .以防万一您在 2020 年到达这里,这直接来自文档

So how do you get a CSV Schema instance to use?那么如何获得一个 CSV Schema 实例来使用呢? There are 3 ways:有3种方式:

  • Create schema based on a Java class基于 Java 类创建模式
  • Build schema manually.手动构建架构。
  • Use the first line of CSV document to get the names (no types) for Schema Here is code for above cases:使用 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);

I believe your only choice here is uniVocity-parsers , as it allows you to choose which columns to write and in what order:我相信您在这里唯一的选择是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();

Hope it helps.希望它有帮助。

Disclosure: I'm the author of this libary, it's open-source and free (Apache 2.0 License)披露:我是这个库的作者,它是开源和免费的(Apache 2.0 许可证)

Note that @JsonPropertyOrder does not necessarily have to include all properties, just ones you are to include for serialization.请注意, @JsonPropertyOrder不一定必须包含所有属性,只需包含要用于序列化的属性即可。 But to indicate what is to be serialized you may need to use combination of @JsonProperty (to indicate properties to serialize) and different visibility for inclusion (either via ObjectMapper.setVisibility() for defaults, or via @JsonAutoDetect for per-POJO).但是要指示要序列化的内容,您可能需要结合使用@JsonProperty (以指示要序列化的属性)和不同的可见性以进行包含(通过ObjectMapper.setVisibility()表示默认值,或通过@JsonAutoDetect表示每个 POJO)。

But assuming you do not want to use @JsonPropertyOrder , you can:但假设您不想使用@JsonPropertyOrder ,您可以:

  1. Override method in JacksonAnnotationIntrospector that reads the annotation, provide your own implementation that uses other sources (does not need to come from annotations at all)覆盖JacksonAnnotationIntrospector中读取注释的方法,提供您自己的使用其他来源的实现(根本不需要来自注释)
  2. If using Jackson 2.8.0, there is new way to specify per-class defaults for some things (see ObjectMapper.configOverride() object), including property order如果使用 Jackson 2.8.0,则有一种新方法可以为某些内容指定每个类的默认值(请参阅ObjectMapper.configOverride()对象),包括属性顺序

Similarly you could override method that looks for @JsonProperty ( findNameForDeserialization() and/or findNameForSerialization() ) if you want to use custom criteria for inclusion/exclusion.同样,如果您想使用自定义标准进行包含/排除,您可以覆盖查找@JsonProperty@JsonProperty ( findNameForDeserialization()和/或findNameForSerialization() )的方法。 There are other mechanisms for inclusion/exclusion as well, like JSON Views ( @JsonView ), JSON Filters.还有其他包含/排除机制,如 JSON 视图( @JsonView )、JSON 过滤器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM