Hi Richard,
It is definitely not a bug in Jersey. The behaviour is enforced by JAX-RS spec.
~Jakub
On Aug 10, 2013, at 4:16 PM, Richard Sand <rsand_at_idfconnect.com> wrote:
> Hi Jakub - thanks for the reply. Removing the getVersion method allowed the PUT to go through. It seems that having individual GET methods and then a common PUT method with the pathparam just conflicts. Is this a bug?
>
> Best regards,
>
> Richard
>
>> Jakub Podlesak Thursday, August 08, 2013 6:11 PM
>> Hi Richard,
>>
>> I guess this has something to do with JAX-RS resource matching algorithm.
>> Try to remove the getVersion method (annotated with @Path("/version")).
>>
>> Does the PUT method go through now?
>>
>> To fix this, i suggest you either make all your CRUD methods generic
>> or leave all property names hardcoded.
>>
>> HTH,
>>
>> ~Jakub
>>
>>
>>
>> Richard Sand Thursday, August 08, 2013 3:14 PM
>> Hi guys -
>>
>> I've implemented a sub-resource that works perfectly for GET requests, because the sub-resource has getters for each property. Instead of creating setters for each property that commit to the database, I decided to write a single method to handle all PUT requests that can do a write/commit at the end.
>>
>> The GET requests work perfectly, but the PUT requests return 405. You can see how I'm building the requests from the JerseyTest client, its the same URI:
>>
>> String str = target("/admin/component/0999/version").request().get(String.class);
>> logger.info("Original version: {}", str);
>>
>> Entity<String> e = Entity.entity(str + ".1", MediaType.TEXT_PLAIN_TYPE);
>> Response res = target("/admin/component/0999/version").request().put(e);
>> assertEquals(HttpServletResponse.SC_OK, res.getStatus());
>>
>>
>> My sub-resource locator in the "Admin" endpoint is:
>>
>> @Path("/component/{id: [0-9]*}")
>> public LicensedComponent getComponent(@PathParam(value = "id") final String id) throws Exception {
>> return new LicensedComponent(this, id);
>> }
>>
>> Then in LicensedComponent I have a getter for each property, but attempted to make a single "update" method for all PUT requests, as follows:
>>
>> /**
>> * Get the whole object
>> */
>> @GET
>> @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
>> public LicensedComponent get() {
>> return this;
>> }
>>
>> @Override
>> @GET
>> @Path("/version")
>> public String getVersion() {
>> return super.getVersion();
>> }
>>
>> ...more getters
>>
>> @PUT
>> @Consumes(MediaType.TEXT_PLAIN)
>> @Path("/{attr}")
>> public Response update(@PathParam(value = "attr") String attr, String value) throws Exception {
>> logger.debug("PUT request for attribute {}", attr);
>> Response response = null;
>> .....stuff
>> response = Response.status(Status.OK).build();
>> return response;
>> }
>>
>> Any pointers on what I'm doing wrong?
>>
>> Thanks!
>>
>> -Richard
>>
>> Simon Roberts Thursday, August 08, 2013 7:04 AM
>> I might be misunderstanding what you're trying to do / concerned about, but your get methods for each POJO can / should be annotated in the POJO, and you would then use "sub-resources" or navigation methods in your root resource. Something like
>>
>> root resource------------------------
>>
>> @Path("base")
>> public class RootResource {
>>
>> @Path("mypojo/{id}")
>> public MyPojo findOnePojo(// inject id
>> return findMyPojoByPK(id);
>> }
>> }
>>
>> pojo ------------------------------------
>>
>> public class MyPojo {
>> @Path("")
>> @GET
>> @Produces(MediaType.APPLICATION_XML)
>> public MyPojo doGetWhole() {
>> return this;
>> }
>>
>> @Path("feature")
>> @GET
>> @Produces...
>> public Xxxx getFeature() {
>> return this.feature;
>> }
>> }
>>
>>
>> HTH
>> Simon
>> From: Richard Sand <rsand_at_idfconnect.com>