Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jackson serialize csv property order

we have a table with 350+ columns. pojo class is generated and getters order get messed up. trying to use csvmapper from jackson, but it generates csv based on getter order. @JsonPropertyOrder is also not use feasible because of many columns.we maintain column ordering in xml and can generate field order array at runtime. can we override at runtime to provide array of fieldnames for property ordering? can we customize using annotation introspector?

like image 899
user2598799 Avatar asked Apr 29 '16 11:04

user2598799


3 Answers

Just in case you get here in 2020, this comes straight from the documentation.

So how do you get a CSV Schema instance to use? There are 3 ways:

  • Create schema based on a Java class
  • Build schema manually.
  • Use the first line of CSV document to get the names (no types) for Schema Here is code for above cases:
// 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);
like image 183
Peter Catalin Avatar answered Nov 16 '22 02:11

Peter Catalin


What you are looking for is called a 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

like image 22
Vladyslav Baidak Avatar answered Nov 16 '22 03:11

Vladyslav Baidak


Note that @JsonPropertyOrder does not necessarily have to include all properties, just ones you are to include for serialization. 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).

But assuming you do not want to use @JsonPropertyOrder, you can:

  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)
  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

Similarly you could override method that looks for @JsonProperty (findNameForDeserialization() and/or findNameForSerialization()) if you want to use custom criteria for inclusion/exclusion. There are other mechanisms for inclusion/exclusion as well, like JSON Views (@JsonView), JSON Filters.

like image 1
StaxMan Avatar answered Nov 16 '22 03:11

StaxMan