Search code examples
javajacksonrestlet

Restlet + Jackson - where to registerModules


I have been using the March 2.2 Snapshot of Restlet GA for a while and using Jackson to handle JSON conversion. Everything has been working fine and essentially invisibly. In particular, I never even need to instantiate an objectMapper. I have also been using Joda DateTime and that has been fine as well.

This week, I was upgrading to the latest 2.2 Snapshot, which uses Jackson 2.0.4 (rather than 1.9). In that version of Jackson, support for Joda DateTime has been moved to a module (out of the core Jackson libraries).

Now, when I run my test code, I get an error along the lines of:

WARNING: Unable to convert a [application/json,UTF-8] representation into an object of class com.fourspires.api.dto.CommitmentDTO
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "year" (class org.joda.time.DateTime), not marked as ignorable (2 known properties: , "chronology", "millis"])
 at [Source: org.restlet.engine.io.UnclosableInputStream@dcc5312; line: 1, column: 701] (through reference chain: com.fourspires.api.dto.CommitmentDTO["completeBy"]->org.joda.time.DateTime["year"])

Which leads to a 415 error when I try to do a Post().

The answer from the Jackson folks is that I must register the JodaModule that handles the conversion as follows:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JodaModule());  

This seems simple enough, but I have no idea where to put this code. My test code is calling:

commitmentsResource = 
  rootClient.getChild(SOME_PATH, CommitmentsResource.class);  
commitmentsClient = ((ClientProxy) commitmentsResource).getClientResource();
commitmentsClient.post()

On the server side, I have an interface:

public interface CommitmentsResource {
  @Get Representation represent();
  @Post("json") Representation postJson(CommitmentDTO commitment);  
  @Post("form") Representation postForm(Form commitmentForm);  
}

And then I have the CommitmentServerResource that has

@Override
public final Representation postJson(final CommitmentDTO commitmentDTO) {...}

@Override
public final Representation postForm(final Form form) {...}

So I can't see where to insert the objectMapper so that the Post() can be called. It's like I want to set the global/default object mapper, but I don't know where to find it (or if it exists).

I tried adding the two objectMapper lines of code to my createInboundRoot, but that didn't seem to make a difference.

Thanks so much for any advice as I seem to be totally stuck here....


Solution

  • I've just tried with the last snapshot of Restlet 2.2 (released in october, based on jackson 2.1.0), it just works for me.