Question

I'm currently working on a project which allows users to book (via the web) the use of a chosen resource for a given period of time. In this program I am trying to keep with Spring's philosophy (and the general best practice) of programming to interfaces and as such I try to use interfaces anywhere where functionality is repeated among concrete classes.

One interface I have created is called a BookableResourceController which specifies the methods needed by a controller to handle the minimum required functionality for any type of resource to be booked. I also make use of a second interface, BookableResource, which identifies which objects model a resource that is allowed to be booked through the application.

The problem I am currently running into is that a few of the methods defined by BookableResourceController use the @RequestBody mapping to convert a JSON object into a method parameter, and since Jackson can only convert JSON into "SimpleType" objects, I receive an error if I specify the input parameter to be a BookableResource.

@RequestMapping(value="/delete.html", method = RequestMethod.POST)  
public ModelAndView processDeleteResource(
    @RequestBody BookableResource resource); 

Can not construct instance of org.codehaus.jackson.map.type.SimpleType, problem: abstract types can only be instantiated with additional type information

From what I can tell this error means that I will need to define a specific implementation of BookableResource, meaning I will most likely need to exclude these methods from the interface even though any controller that is to be used for this purpose will require those methods.

What I am asking is if anyone knows a way to define an interface as the object that is expected from an @RequestBody mapping using JSON, or does anyone have any suggestions of how to structure my contoller interface in order to include these methods?

Cheers

Was it helpful?

Solution

I'm not sure it would work, but you can try to make it generic:

public interface BookableResourceController<R extends BookableResource> {
    @RequestMapping(value="/delete.html", method = RequestMethod.POST)
    public ModelAndView processDeleteResource(@RequestBody R resource); 
}

OTHER TIPS

Additional way to go that can be used is to annotate interface with Jackson annotation:

@JsonDeserialize(as=BookableResourceImp.class)

(possibly using mix-in annotations if one does not want to add it directly in interface class)

EDIT: Another possibility is to use SimpleModule method addAbstractTypeMapping() to specify implementation type. This avoids linkage from interface to implementation, and may (or may not) be more convenient way to register this aspect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top