TheUnreal
TheUnreal

Reputation: 24472

Spring boot - date in response is not well formatted

I have the following entity column definition:

@Column(name= "time")
    @Temporal(TemporalType.TIMESTAMP)
    private java.util.Calendar time;

When I query and return my data as JSON:

modules = this.moduleStatsRepository.findAll();
JsonArray modulesArray = Application.gson.fromJson(Application.gson.toJson(modules), JsonArray.class);

 JsonObject modulesJson = new JsonObject();
 modulesJson.add("modules", modulesArray);
 modulesJson.addProperty("triggerTimeShortSec", configurationManager.startupConfig.get("stats_trigger_time_sec"));
 modulesJson.addProperty("triggerTimeLongSec", Integer.parseInt(configurationManager.startupConfig.get("stats_trigger_time_sec")) * 3);

 return Application.gson.toJson(modulesJson);

the time is returned as an object, not really ideal:

enter image description here

Is there any way to customize gson settings to parse dates as ISO 8601?

Upvotes: 3

Views: 833

Answers (2)

Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44685

Many of these things come out of the box with Jackson. With Gson it doesn't seem that there is an option to configure ISO 8601 timestamps, so you'll have to write it yourself by registering a JsonSerializer<Calendar> and perhaps also a JsonDeserializer<Calendar>.

For example, a simplified ISO 8601 string to calendar converter could look like this:

public class CalendarISO8601Serializer implements JsonSerializer<Calendar>, JsonDeserializer<Calendar> {
    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

    @Override
    public Calendar deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        try {
            Calendar instance = Calendar.getInstance();
            instance.setTime(FORMATTER.parse(jsonElement.getAsString()));
            return instance;
        } catch (ParseException e) {
            throw new JsonParseException(e);
        }
    }

    @Override
    public JsonElement serialize(Calendar calendar, Type type, JsonSerializationContext jsonSerializationContext) {
        return new JsonPrimitive(FORMATTER.format(calendar.getTime()));
    }
}

This means you can no longer rely on the default Gson object created by Spring boot since I don't think it will automatically pick up the serializer as a type adapter. To solve this, you need to create your own Gson bean and add the serializer:

@Bean
public Gson gson() {
    return new GsonBuilder()
        .registerTypeHierarchyAdapter(Calendar.class, new CalendarISO8601Serializer())
        .create();
}

But considering that you're using a public static field (Application.gson), you may want to see for yourself how you want to register that adapter.

Upvotes: 3

Francesco Iannazzo
Francesco Iannazzo

Reputation: 626

just use java.util.Date as Type in your Entity:

 @Temporal(TemporalType.TIMESTAMP)
private Date date;

Upvotes: 0

Related Questions