-1

I have a Java class and i want to serialize it into CSV using jackson. In addition i want to exclude from the csv a single field base on a external property.

I have tried using all features provides by jackson like Feature.IGNORE_UNKNOWN=true or @JsonIgnoreProperties(ignoreUnknown = true) on my data class, csvMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) but none of them works. I still receive the exception column not found in schema when not all columns are declared in the schema. Code works fine in the other case.

Here i upload my implementation

    public class MyClass{
        @JsonProperty("A")
        private string a;
    
        @JsonProperty("B")
        private string b;
    
        @JsonProperty("C")
        private string c;  
    }

CsvMapper mapper = new CsvMapper();
mapper.configure(Feature.IGNORE_UNKNOWN, true);
CsvSchema csvSchema;
if (disable = true) {
    schema = CsvSchema.builder()
      .addColumn("A")
      .addColumn("C")
      .build()
} else {
    schema = CsvSchema.builder()
      .addColumn("A")
      .addColumn("B")
      .addColumn("C")
      .build()
}

ObjectWriter ow = mapper.writer(schema);
String csv = ow.writeValueAsString(list);
Sabbullo
  • 1
  • 3

2 Answers2

0

use @JsonIgnore on top of property. Ex:

import com.fasterxml.jackson.annotation.JsonIgnore;
@Validated
@Data
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class MyResponseModel {
...
        @JsonIgnore
        private String createBy;
        ...
}
0

Using Feature.IGNORE_UNKNOWN=true or @JsonIgnoreProperties(ignoreUnknown = true) will help when you want to deserialize JSON into your Java class.

For example, this will be useful when you're implementing the REST API and in the POST method dedicated to creating new objects, you want to ignore all invalid/incorrect fields sent to you by the user and process only the valid ones instead of returning the 400/500 error.

In your case, you just need to put the @JsonIgnore annotation on the field in your Java class, which you want to exclude during the serialization. This is an example of excluding the «a» property:

public class MyClass {
    @JsonIgnore
    @JsonProperty("A")
    private String a;

    @JsonProperty("B")
    private String b;

    @JsonProperty("C")
    private String c;
}

This should also be useful in cases when you want to exclude some private and sensitive information from application logs, like passwords, PII, PHI, etc.

Updated:

This is the working solution for your case:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MyClass {

    @JsonProperty("A")
    private String a;

    @JsonProperty("B")
    private String b;

    @JsonProperty("C")
    private String c;
}

public String test() throws JsonProcessingException {
    boolean disable = false;
    CsvMapper mapper = new CsvMapper();
    mapper.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true);
    CsvSchema csvSchema;

    List<MyClass> list = List.of(MyClass.builder()
            .a("a1")
            .b("b1")
            .c("c1")
            .build()
    );

    if (disable) {
        csvSchema = CsvSchema.builder()
                .addColumn("A")
                .addColumn("C")
                .build();
    } else {
        csvSchema = CsvSchema.builder()
                .addColumn("A")
                .addColumn("B")
                .addColumn("C")
                .build();
    }

    ObjectWriter ow = mapper.writer(csvSchema);
    String csv = ow.writeValueAsString(list);

    return csv;
}

Dependency, which I've been using for tests and verification of the above code:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-csv</artifactId>
    <version>2.13.3</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
</dependency>
  • Even with this solution i still get the error unrecognised column, not on the json property tag A but on the var name a – Sabbullo Sep 02 '22 at 07:34
  • @Sabbullo I've done a bit more research and figured out that you need to specify `mapper.configure(Feature.IGNORE_UNKNOWN, true)` when using `CsvMapper` for serialization. Please check my updated answer and see if it works for you. After fixing several mistakes in your initial code, I was able to get it working and serialize your class with both two and all three columns. – Alexander Golovnya Sep 02 '22 at 09:41
  • Yeah thanks. I found what was the problem, you are right with this answer. Additionally i have to upgrade jackson version to 2.7.0 - this feature have been provided by that version – Sabbullo Sep 02 '22 at 09:45
  • 1
    @Sabbullo Great, I'm glad that this worked for you. Please don't forget to update your question with the resulting solution and mark answers as useful and accepted to make it easy for others to find a solution to similar issues. – Alexander Golovnya Sep 02 '22 at 10:40