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
On Aug 8, 2013, at 9:14 PM, Richard Sand <rsand_at_idfconnect.com> wrote:
> 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>