I've been trying to serialize an object to a CSV String
but the object contains a List
and @JsonUnwrapped
doesn't work on List
objects.
Expected sample output:
color,part.name\n
red,gearbox\n
red,door\n
red,bumper
Actual output:
com.fasterxml.jackson.core.JsonGenerationException: Unrecognized column 'name':
Here is my code: (Most of it is the 2 POJO's)
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import java.io.IOException;
import static java.util.Arrays.asList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class NestedWrapping {
@JsonRootName("Car")
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonPropertyOrder({"color"})
public static class Car {
@JsonProperty("color")
private String color;
@JsonFormat(shape = JsonFormat.Shape.STRING)
@JacksonXmlElementWrapper(useWrapping = false)
private List<Part> parts;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public List<Part> getParts() {
return parts;
}
public void setParts(List<Part> parts) {
this.parts = parts;
}
}
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonPropertyOrder({
"name"
})
public static class Part {
@JsonProperty("name")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String args[]) {
try {
Car car = new Car();
car.setColor("red");
Part part1 = new Part();
part1.setName("geabox");
Part part2 = new Part();
part2.setName("door");
Part part3 = new Part();
part3.setName("bumper");
car.setParts(asList(part1, part2, part3));
System.out.println("serialized: " + serialize(car, Car.class, true));
} catch (IOException ex) {
Logger.getLogger(NestedWrapping.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static final synchronized String serialize(final Object object, final Class type, final Boolean withHeaders) throws IOException {
CsvMapper csvMapper = new CsvMapper();
CsvSchema csvSchema;
if (withHeaders) {
csvSchema = csvMapper.schemaFor(type).withHeader();
} else {
csvSchema = csvMapper.schemaFor(type).withoutHeader();
}
return csvMapper.writer(csvSchema).writeValueAsString(object);
}
}
Nothing I try seems to work, I've read every post on stackoverflow and github about the topic but I can't find a working solution.
Sorry about any pointless annotations that I've left behind for no reason and if you answer with code, please feel free to remove them.
From the error, I would like to believe that it has something to do with your schema for a
Car
, which has the columns of{"color"}
taken from@JsonPropertyOrder
onCar
and not a"name"
value.You probably want to add
"parts"
in there, but you would get the same error that"name"
is not part of that schema.After a few changes to your code, I was able to serialize and deserialize a
Car
object.Part
Here, after some other changes it needed a constructor with a single String value, so add that
Car
Here, you will need to implement a method that will convert the
List<Part>
into a CSV-readable format manually.Such a method would look like this
Also, don't forget to fix the schema at the top of the class
serialize
You can change your
serialize
method to take the type of the class as a generic type parameter instead of an explicitClass
like so.main - writer
Now, if you serialize a
Car
, you should seemain - reader
And reading that CSV string and looping over the
Car.getParts()
Full working CSV Serialize & Deserialize solution: