2013-01-16 13 views
14

Sto sviluppando un webservice REST in primavera MVC. Ho bisogno di cambiare il modo in cui serialò jackson 2 serializza oggetti mongodb. Non sono sicuro di cosa fare perché ho trovato la documentazione parziale per Jackson 2, quello che ho fatto è quello di creare un serializzatore personalizzato:Spring 3.2 e Jackson 2: aggiunta object mapper personalizzato

public class ObjectIdSerializer extends JsonSerializer<ObjectId> { 


    @Override 
    public void serialize(ObjectId value, JsonGenerator jsonGen, 
      SerializerProvider provider) throws IOException, 
      JsonProcessingException { 
     jsonGen.writeString(value.toString()); 
    } 
} 

Creare un ObjectMapper

public class CustomObjectMapper extends ObjectMapper { 

    public CustomObjectMapper() { 
     SimpleModule module = new SimpleModule("ObjectIdmodule"); 
     module.addSerializer(ObjectId.class, new ObjectIdSerializer()); 
     this.registerModule(module); 
    } 

} 

e quindi registrare il mapper

<mvc:annotation-driven> 
    <mvc:message-converters register-defaults="true"> 
     <bean 
      class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="objectMapper"> 
       <bean class="my.package.CustomObjectMapper"></bean> 
      </property> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

mio CustomConverter non viene mai chiamato. Penso che la definizione di CustomObjectMapper sia errata, l'ho adattata da qualche codice per jackson 1.x

Nei miei controller sto usando @ResponseBody. Dove sto sbagliando? Grazie

+2

Serializer e registrazione mi sembrano corretti, quindi penso che il problema risieda nella configurazione xml. – StaxMan

+1

Sì, grazie per il suggerimento, avevo un tag vuoto attorno al file. Funziona ora – alex

+0

FYI i documenti dicono di usare StdSerializer invece: http://fasterxml.github.io/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/ser/std/StdSerializer.html – testing123

risposta

0

Come vorrei fare questo è:

creare un'annotazione di dichiarare i vostri serializzatori personalizzati:

@Target({ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface MyMessageConverter{ 
} 

Impostare scansione componente per questo nel file mvcconfiguration

<context:include-filter expression="package.package.MyMessageConverter" 
      type="annotation" /> 

e creare una classe che implementa HttpMessageConverter<T>.

@MyMessageConverter 
public MyConverter implements HttpMessageConverter<T>{ 
//do everything that's required for conversion. 
} 

Creare una classe che extends AnnotationMethodHandlerAdapter implements InitializingBean.

public MyAnnotationHandler extends AnnotationMethodHandlerAdapter implements InitializingBean{ 
    //Do the stuffs you need to configure the converters 
    //Scan for your beans that have your specific annotation 
    //get the list of already registered message converters 
    //I think the list may be immutable. So, create a new list, including all of the currently configured message converters and add your own. 
    //Then, set the list back into the "setMessageConverters" method. 
    } 

Credo che questo sia tutto ciò che è necessario per il tuo obiettivo.

Cheers.

+0

Credo che il modo in cui stai andando su questo, è più del "modo Jersey". – ninnemannk

+0

Questa risposta ha così tanta complessità non necessaria. OP sta facendo nel modo corretto. – Bart

2

È necessario annotare il campo modello corrispondente con @JsonSerialize annontation. Nel tuo caso potrebbe essere:

public class MyMongoModel{ 
    @JsonSerialize(using=ObjectIdSerializer.class) 
    private ObjectId id; 
} 

Ma a mio parere, dovrebbe meglio non utilizzare modelli di entità come VO. Il modo migliore è avere diversi modelli e mapparli tra loro. Puoi trovare my example project here (ho usato la serializzazione della data con Spring 3 e Jackson 2 come esempio).

0

Non è necessario creare object mapper. Aggiungi jackson-core-2.0.0.jar e jackson-annotations-2.0.0.jar al tuo progetto.

Ora, aggiungere le seguenti righe di codice al controller mentre consegna il servizio:

@RequestMapping(value = "students", method = RequestMethod.POST, headers = "Accept=application/json", consumes = "application/json") 

public HashMap<String, String> postStudentForm(
      @RequestBody Student student, HttpServletResponse response) 

Non perdere nessuna delle annotazioni.

Problemi correlati