Jackson and JAX-RS: Type of Abstract Types Based on @PathParam

Suppose it Animalis an abstract class in my project, and I have a REST resource (on a JAX-RS server using Jackson for (de) serialization) PUTto manage animals that are stored in my database. They have specific types, and the REST resource indicates the type in the request path:

@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{entityType}/{id: \\d+}")
public <T extends Animal> void putAnimal(@PathParam("entityType") String entityType, @PathParam("id") String id, Animal input) throws IOException {
    //...
}

I want to use entityTypeto select a specific class for deserialization ( Dogor Cator something else, for entityTypewill Dogor Cator something else). For reasons that are too complicated to explain here, I cannot put the type information in the JSON input itself.

So, AIUI annotating Animalwith custom TypeIdResolveror something like this cannot help me because the type information will not be in the JSON itself (and that all the information that the type recognizer will receive). I planned to use a custom one MessageBodyReader, but, as far as I can tell, it does not get other parameter values ​​from the body passed in its method readValue, so I will not know what is needed for deserialization.

What am I missing? If this approach does not work, how can I accomplish what I want without specifying endpoints for specific animals (which leads to a lot of duplication of code, as well as loss of generality), now I can add a subclass Animaland this code will just work which is very pleasant.)

+5
source
2

JAX-RS (5.2.2 URI URI) , UriInfo MessageBodyReader URL- .

UriInfo @Context an-notation. UriInfo , , URI .

, UriInfo, , , (MessageBodyReader).

entityType path UriInfo MessageBodyReader Animal.

+4

, , AnimalResource, , DogResource, CatResource , , AnimalResource. Animal JSON .

, . :

public class AnimalResource<T extends Animal>
{
    private final transient AnimalService<T> service;

    public AnimalResource(final AnimalService<T> service)
    {
        this.service = service;
    }

    @Get
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public T getbyId(@PathParam("id") final String id)
    {
        return this.service.findById(id);
    }

    // Other CRUD methods go here
}

, , , :

@Path("/cats")
public class CatResource extends AnimalResource<Cat>
{
    public CatResource(final CatService catService)
    {
        super(catService);
    }
}

@Path("/dogs")
public class DogResource extends AnimalResource<Dog>
{
    public DogResource(final DogService dogService)
    {
        super(dogService);
    }
}

. CRUD , , , - *Resource.

0

All Articles