14

I'm developing a REST webservice in spring MVC. I need to change how jackson 2 serialize mongodb objectids. I'm not sure of what to do because I found partial documentation for jackson 2, what I did is to create a custom serializer:

public class ObjectIdSerializer extends JsonSerializer<ObjectId> { @Override public void serialize(ObjectId value, JsonGenerator jsonGen, SerializerProvider provider) throws IOException, JsonProcessingException { jsonGen.writeString(value.toString()); } } 

Create a ObjectMapper

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

and then register the 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> 

My CustomConverter is never called. I think the CustomObjectMapper definition is wrong,I adapted it from some code for jackson 1.x

In my controllers I'm using @ResponseBody. Where am I doing wrong? Thanks

8
  • 2
    Serializer and registration look correct to me, so I think the problem lies in xml configuration. Commented Jan 16, 2013 at 21:18
  • 1
    Yep, thanks for the suggestion, I had an empty <mvc:annotation-driven> tag around the file. It's working now Commented Jan 16, 2013 at 21:52
  • FYI the docs say to use StdSerializer instead: fasterxml.github.io/jackson-databind/javadoc/2.0.0/com/… Commented Jun 5, 2013 at 5:29
  • I'm having a similar issue. Can you please post your final working solution? Commented Dec 19, 2013 at 19:51
  • In my project we extends StdSerializer instead of JsonSerializer, but that is not the problem. Be sure that you use com.fasterxml.* classes and not old org.codehaus.* classes? Commented Mar 12, 2014 at 13:03

3 Answers 3

4

You should annotate corresponding model field with @JsonSerialize annontation. In your case it may be:

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

But in my opinion, it should better don't use entity models as VOs. Better way is to have different models and map between them. You can find my example project here (I used date serialization with Spring 3 and Jackson 2 as example).

Sign up to request clarification or add additional context in comments.

Comments

0

How I would do this is:

Create an annotation to declare your custom serializers:

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

Set up component scan for this in your mvcconfiguration file

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

and create a class that implements HttpMessageConverter<T>.

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

Create a class that 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. } 

I believe this is everything that is required for your goal.

Cheers.

2 Comments

I believe the way that you're going about this, is more of the "Jersey way".
This answer has so much unnecessary complexity. OP is doing it the correct way.
0

There is no need to create object mapper. Add jackson-core-2.0.0.jar and jackson-annotations-2.0.0.jar to your project.

Now, add the following lines of code to your controller while handing the service:

@RequestMapping(value = "students", method = RequestMethod.POST, headers = "Accept=application/json", consumes = "application/json") public HashMap<String, String> postStudentForm( @RequestBody Student student, HttpServletResponse response) 

Do not miss any of the annotations.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.