È possibile impostare Jersey utilizzando Jackson per serializzazione/deserializzazione utilizzando più configurato ObjectMappers
?Utilizzo di Jackson in Jersey con più ObjectMappers configurati
Quello che mi piacerebbe essere in grado di fare è registrare un "default" Jackson ObjectMapper
e quindi avere la capacità di registrare un'altra caratteristica che fornisce un ObjectMapper
con qualche configurazione specializzato che, in determinate circostanze si "override" il "default" ObjectMapper
.
Ad esempio, questo ContextResolver
sarebbe per il mapper "default":
@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class JacksonMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mObjectMapper;
public JacksonMapperProvider() {
mObjectMapper = createMapper();
}
protected abstract ObjectMapper createMapper() {
ObjectMapper mapper = createMapper();
return mapper
.setSerializationInclusion(Include.ALWAYS)
.configure(JsonParser.Feature.ALLOW_COMMENTS, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mObjectMapper;
}
}
E questo ContextResolver
sarebbe quello di ignorare il mapper "default":
@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class SpecializedMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mObjectMapper;
public SpecializedMapperProvider() {
mObjectMapper = createMapper();
}
protected abstract ObjectMapper createMapper() {
ObjectMapper mapper = createMapper();
return mapper
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"))
.registerModule(new SpecializedModule1())
.registerModule(new SpecializedModule2());
}
@Override
public ObjectMapper getContext(Class<?> type) {
if(SomeType.isAssignableFrom(type)) {
return mObjectMapper;
}
return null;
}
}
vedo in JacksonJsonProvider
codice che Jackson supporta l'iniezione/risoluzione del provider ObjectMapper
. Tuttavia, in pratica, quello che vedo è che l'ordine dei fornitori sembra casuale (suppongo che non lo sia, ma non riesco a capire come controllare l'ordine). A volte il "override" viene prima del "default" e tutto funziona, ma all'avvio successivo del server l'ordine cambia.
ho cercato di farlo funzionare in diversi modi tra cui:
- Registrazione dei
ContextResolver<ObjectMapper>
implementazioni manualmente (in ordini differenti) - Registrazione dei
ContextResolver<ObjectMapper>
implementazioni tramite@Provider
annotazioni - Specifica un priorità al momento della registrazione
Sto usando il seguente:
- Jersey 2,8
- Jackson 2.3.3
Forse sto prendendo un approccio completamente errata?
Esiste un modo migliore per ottenere ciò che sto cercando di fare? Forse dovrei semplicemente definire due applicazioni JAX-RS separate e avere una singola configurazione ObjectMapper per ciascuna?
Quello che ho trovato è una volta che hai 'ObjectMapper defaultMapper = return new ObjectMapper()', non è la stessa istanza predefinita di 'JacksonJsonProvider'. Atleast non per 'JacksonJaxbJsonProvider'. – ulab