You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Pat Turner <pa...@ichini.co.uk> on 2011/11/22 13:15:07 UTC

Injecting jax-rs PathParam into sub-resource fields

I've successfully used jax-rs sub-resources and can access PathParams defined
in a root resource when passed in by method.

I would like to define the path param as a field however. Is this possible
for sub-resources.

I imagine that I would need to get jax-rs to inject my sub-resource, or look
it up from a jax-rs context. Currently I just Autowire the subresource with
Spring as a 'prototype' scoped bean. I guess Spring doesn't have access to
the jax-rs context.

Any hints or clues?

Many thanks,
Pat

--
View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013364.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Pat Turner <pa...@ichini.co.uk>.
Hi Sergey,

it's not request scoped, it's a default Spring managed bean (singleton).

I've also just found this article:
http://cxf.apache.org/docs/jaxrs-services-configuration.html#JAXRSServicesConfiguration-FromSpring

I presume I have to configure the Spring integration of the jax-rs server
appropriately to benefit from @PathParam fields.

To be honest, I think your method level suggestion is looking way simpler
than this, and is the route I will take.

Thanks Sergey,
Pat

--
View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5014118.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi,
On 22/11/11 16:23, Pat Turner wrote:
> Hi Sergey,
>
> ok, that's where I was up to: Using a Spring injected component as a
> sub-resource locator, and passing path/query params through at method level.
>
> This isn't a problem and is definitely workable, but I don't think its as
> clean as using injected field, annotated with @PathParam.
>
> FYI, I just don't get the parameter injected at all, so thread safety
> doesn't even come into it :-( The Spring injected resource seems to have
> been bypassed by CXF entirely. Is that right?
>
> Actually, if @PathParam annotated fields are not thread safe for Spring
> injected resources, why is it thread safe for 'normal' root resources.
>

Injecting @PathParam into fields is only thread-safe for per-request 
root resources, those created per every new request.
Can you let me know please, how often an injected BusResource is created 
(the one which is injected into FleetResource), say by adding a println 
in its default constructor ? Does it happen on every request ?


Cheers, Sergey

> I'm still unclear as to why it should be a problem for CXF to 'lookup'
> resources, but I really appreciate your help on it.



> Cheers
> Pat
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5014021.html
> Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Pat Turner <pa...@ichini.co.uk>.
Hi Sergey,

ok, that's where I was up to: Using a Spring injected component as a
sub-resource locator, and passing path/query params through at method level.

This isn't a problem and is definitely workable, but I don't think its as
clean as using injected field, annotated with @PathParam. 

FYI, I just don't get the parameter injected at all, so thread safety
doesn't even come into it :-( The Spring injected resource seems to have
been bypassed by CXF entirely. Is that right?

Actually, if @PathParam annotated fields are not thread safe for Spring
injected resources, why is it thread safe for 'normal' root resources. 

I'm still unclear as to why it should be a problem for CXF to 'lookup'
resources, but I really appreciate your help on it.
Cheers
Pat



--
View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5014021.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Pat

On 22/11/11 14:53, Pat Turner wrote:
> Hi Sergey,
>
> I have two root resources: Fleet and Bus. I want to be able to list all
> Buses or all Busses by Fleet. I had expected to expose URLs such as:
>
> #All Busses
> /busses
> # Busses by Fleet
> /fleets/{fleet_id}/busses
>
> My Bus resource looks like this:
>
> @Path("/busses")
> @Component
> public class BusResource {
>
> 	@PathParam(fleet_id)
> 	private String fleetId;
>
> 	public List<Bus>  getBusses() {
> 		//sercice call: lookup busses for fleetId, or all if none provided
> 	}
> }
>
>
> My Fleet resource looks like this:
>
> @Path("/fleets")
> @Component
> public class FleetResource {
>
> 	//TODO inject/lookup with jax-rs context resources
> 	@Autowired
> 	BusResource busResource
>
> 	@Path("/{fleet_id}/busses")
> 	public Object getBusses() {
> 		return busResource
> 	}
> }
>
> I realise I'm actually (ab)using a root resource as a sub-resource, but I
> can't see a nice way to use the same code to access resources with and
> without context (Fleet).

Reusing a BusResource seems completely perfect to me, I'd do it the 
similar way, but I believe

 > 	@PathParam(fleet_id)
 > 	private String fleetId;

is just not thread-safe, unless you get Spring injecting a new 
BusResource instance into FleetResource per request (with request scope 
may be).

I'd just update it like this:

@Path("/busses")
@Component
public class BusResource {

  	
         @GET
         public List<Bus>  getBusses(@PathParam("fleetid") String id) {
              		
  	}
}

@Path("/fleets")
@Component
public class FleetResource {

  	//TODO inject/lookup with jax-rs context resources
  	@Autowired
  	BusResource busResource

  	@Path("/{fleet_id}/busses")
  	public BusResource getBusses() {
  		return busResource;
  	}
}

so /busses/1 and /fleets/1/busses will work equally well, all is 
thread-safe, and even cxf jaxrs proxies will be able to do

FleetResource fleet = JAXRSClientFactory.create(FleetResource.class);
List<BusResource> bus = fleet.getBusses().getBusses("1");

I can look into the runtime supporting the injection into subresources, 
but that will probably require setting a property which will indicate to 
the runtime that the injection is safe

Cheers, Sergey

>
> Thanks again,
> Pat
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013741.html
> Sent from the cxf-user mailing list archive at Nabble.com.


-- 
Sergey Beryozkin

http://sberyozkin.blogspot.com

Talend Community Coders
http://coders.talend.com/

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Pat Turner <pa...@ichini.co.uk>.
Hi Sergey,

I have two root resources: Fleet and Bus. I want to be able to list all
Buses or all Busses by Fleet. I had expected to expose URLs such as:

#All Busses
/busses
# Busses by Fleet
/fleets/{fleet_id}/busses

My Bus resource looks like this:

@Path("/busses")
@Component
public class BusResource {

	@PathParam(fleet_id)
	private String fleetId;

	public List<Bus> getBusses() {
		//sercice call: lookup busses for fleetId, or all if none provided
	}
}


My Fleet resource looks like this:

@Path("/fleets")
@Component
public class FleetResource {

	//TODO inject/lookup with jax-rs context resources
	@Autowired
	BusResource busResource

	@Path("/{fleet_id}/busses")
	public Object getBusses() {
		return busResource
	}
}

I realise I'm actually (ab)using a root resource as a sub-resource, but I
can't see a nice way to use the same code to access resources with and
without context (Fleet).

Thanks again,
Pat

--
View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013741.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Pat

On 22/11/11 13:40, Pat Turner wrote:
> Hi Sergey,
>
> thanks for replying.
>
> I'd like a way to lookup a sub-resource by Class name, and have it's jax-rs
> annotated fields injected.
>
>  From reading the Jersey docs, this is exactly what ResourceContext does. Is
> there a CXF equivalent?

I don't understand why a subresource locator needs to be looked up using 
a class name from the application code, can you post an example please ?
My own understanding is that subresource handlers are just utility 
classes which make it possible to keep the root resources simple enough 
and not having to do with all the processing.

One tricky issue is that the JAX-RS runtime can not know how the 
application code manages the subresources, for example, does it reuse a 
single subresource instance across multiple requests or not; if yes then 
the injection will be completely thread-unsafe.

>
> Btw, I don't expect this to happen as the jax-rs spec clearly states that
> sub-resources are managed by the application. But not having this festure
> makes me wonder how I can sensibly make us of sub-resources at all.
>

Let me know please how are you considering to use them. Subresources can 
have everything the root resources have except that 
@PathParam/@QueryParam have to be added to methods, not possible to get 
them injected as properties and contexts have to be manually injected.

That said, we have a long pending issue to do with supporting injecting 
the contexts into subresources - this can be tackled but we need to make 
sure it works with multiple threads too

Sergey

> Thanks again,
> Pat
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013574.html
> Sent from the cxf-user mailing list archive at Nabble.com.



Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Pat Turner <pa...@ichini.co.uk>.
Hi Sergey,

thanks for replying. 

I'd like a way to lookup a sub-resource by Class name, and have it's jax-rs
annotated fields injected.

>From reading the Jersey docs, this is exactly what ResourceContext does. Is
there a CXF equivalent? 

Btw, I don't expect this to happen as the jax-rs spec clearly states that
sub-resources are managed by the application. But not having this festure
makes me wonder how I can sensibly make us of sub-resources at all.

Thanks again,
Pat

--
View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013574.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Sergey Beryozkin <sb...@gmail.com>.
Pat,
On 22/11/11 13:09, Pat Turner wrote:
> Quick followup...
>
> I think I'm searching for a CXF equivalent of this:
> http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/api/core/ResourceContext.html

Can you clarify please what exactly do you expect CXF to do ?
Thanks, Sergey

>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013486.html
> Sent from the cxf-user mailing list archive at Nabble.com.


-- 
Sergey Beryozkin

http://sberyozkin.blogspot.com

Talend Community Coders
http://coders.talend.com/

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Pat Turner <pa...@ichini.co.uk>.
Quick followup...

I think I'm searching for a CXF equivalent of this:
http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/api/core/ResourceContext.html


--
View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013486.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Injecting jax-rs PathParam into sub-resource fields

Posted by Sergey Beryozkin <sb...@gmail.com>.
Sorry for the duplication - I've just updated the code to support it by 
default in CXF if "staticSubresourceResolution" property is set, 
starting from CXF 2.7.2 trunk

Sergey
On 22/11/11 12:15, Pat Turner wrote:
> I've successfully used jax-rs sub-resources and can access PathParams defined
> in a root resource when passed in by method.
>
> I would like to define the path param as a field however. Is this possible
> for sub-resources.
>
> I imagine that I would need to get jax-rs to inject my sub-resource, or look
> it up from a jax-rs context. Currently I just Autowire the subresource with
> Spring as a 'prototype' scoped bean. I guess Spring doesn't have access to
> the jax-rs context.
>
> Any hints or clues?
>
> Many thanks,
> Pat
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Injecting-jax-rs-PathParam-into-sub-resource-fields-tp5013364p5013364.html
> Sent from the cxf-user mailing list archive at Nabble.com.


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com