Estou construindo serviços Web RESTful usando o Java EE 7 no GlassFish 4. Ao serializar POJOs contendo objects java.util.Date
, as informações de fuso horário não são incluídas.
Como posso personalizar a serialização de objects para que java.util.Date
s tenha informações de fuso horário incluídas?
Por exemplo, em vez disso:
{ "id": 1234, "foo": "2014-05-19T13:53:49.392" }
Eu preferiria assim:
{ "id": 1234, "foo": "2014-05-19T13:53:49.392+09:30" }
Onde o fuso horário do servidor é GMT + 09:30.
Isso é causado por um bug no MOXy, que é o serializador JSON (de) padrão para o JAX-RS no GlassFish.
A solução alternativa é mudar os provedores de JSON para Jackson.
O primeiro passo é adicionar essas dependencies à construção:
org.glassfish.jersey.media jersey-media-json-jackson 2.8 provided org.codehaus.jackson jackson-mapper-asl 1.9.13 jar
Na próxima etapa, adicione JacksonFeature
como um provedor, que replaceá o MOXy como o serializador JSON:
@ApplicationPath("/api/1") public class ApplicationConfig extends Application { @Override public Set> getClasses() { Set> resources = new java.util.HashSet<>(); addRestResourceClasses(resources); // Add Jackson feature. resources.add(org.glassfish.jersey.jackson.JacksonFeature.class); return resources; } private void addRestResourceClasses(Set> resources) { // JAX-RS resource classs added here - maintained by NetBeans. } }
O comportamento padrão de Jackson é representar java.util.Date
em seus milissegundos desde a forma de época. Para mudar isso para ISO-8601:
import java.text.SimpleDateFormat; import java.util.TimeZone; import javax.ws.rs.Produces; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; @Provider @Produces("application/json") public class JacksonConfigurator implements ContextResolver { public JacksonConfigurator() { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); mapper.setDateFormat(dateFormat); mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false); } @Override public ObjectMapper getContext(Class> clazz) { return mapper; } private final ObjectMapper mapper = new ObjectMapper(); }