The mandatory output format of any date in a JSON string is:
{
"element": [
"~#date",
[
"2013-05-31"
]
],
...
}
I have to adhere to this specific format.
Building an object with an array of objects will not work. I get something like this:
{
"element": [
{
"~#date": "2024-09-17"
}
],
...
}
I could write a Serializer for LocalDate printing the ‘[…]’. That feels like cheating. Notice that the number of dates is always 1.
Is there a standard way of doing this?
This is what I did so far:
The object contains:
@JsonProperty("aDate")
private MyMDate[] myDate = null;
With ‘MyDate’ being:
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MyDate {
@JsonProperty("~#date")
@JsonSerialize(using = LocalDateArraySerializer.class)
private LocalDate[] date;
}
And the serializer:
public class LocalDateArraySerializer extends JsonSerializer<LocalDate[]> {
private final DateTimeFormatter format = DateTimeFormatter.ofPattern( "yyyy-MM-dd");
@Override
public void serialize(LocalDate[] values, JsonGenerator gen, SerializerProvider serializers) throws IOException {
String seperator = "";
for ( LocalDate ld: values) {
gen.writeString( seperator + ld.format(format));
seperator = ",";
}
}
}
This gives the actual output: an array with an object. That is not the requested output.
7
You can archive this with something like:
public class Awkward implements Serializable {
private static final long serialVersionUID = 1L;
private Object[] element;
public Awkward() {
super();
element = new Object[2];
String awkwardDate = "~#date";
element[0] = awkwardDate;
String[] awkwardValue = new String[1];
awkwardValue[0] = "2013-05-31";
element[1] = awkwardValue;
}
...
Jackson will serialize this as:
{
"element": [
"~#date",
["2013-05-31"]
]
}
This is not intended to be a effective solution, just a way to show how JSON structure should be obtained in Java implementation.
Important part is:
- an object with
- a member named “element” whith
- an array of values composed by
- a string value “~#date”
- a array of values composed by
- a string value from a date formated as ‘YYYY-MM-DD’
- an array of values composed by
- others irrelevant members…
- a member named “element” whith
Forgive the fun. 😉
2
You just need these lines :
public class CustomLocalDateSerializer extends StdSerializer<LocalDate> {
public CustomLocalDateSerializer() {
super(LocalDate.class);
}
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartArray(); // start outer array
gen.writeString("~#date");
gen.writeStartArray(); // start inner array
gen.writeString(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); //date format
gen.writeEndArray(); // end inner array
gen.writeEndArray(); // end outer array
}
}
@JsonSerialize(using = CustomLocalDateSerializer.class)
public class DateHolder {
private LocalDate date;
public DateHolder(LocalDate date) {
this.date = date;
}
// getters and setters
}
and then call the custom serializer
ObjectMapper mapper = new ObjectMapper();
DateHolder dateHolder = new DateHolder(LocalDate.of(2013, 5, 31));
String json = mapper.writeValueAsString(dateHolder); //serialize
System.out.println(json);
3