users@jersey.java.net

Re: [Jersey] Custom Parameter Binding

From: Meeraj Kunnumpurath <mkunnumpurath_at_googlemail.com>
Date: Thu, 25 Jun 2009 23:54:34 +0100

Paul,

Couple of questions on the example ..

1. If I run within a Servlet container instead Grizzly, how do I configure
the runtime to use the ResourceParamInjector?
2. Where is the logic of injecting the value of query parameter x into the
instance variable x of MyBean?

Many thanks
Meeraj

On Thu, Jun 25, 2009 at 9:59 PM, Meeraj Kunnumpurath <
mkunnumpurath_at_googlemail.com> wrote:

> Thanks Paul, pls see my comments below.
>
> On Thu, Jun 25, 2009 at 9:25 AM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
>>
>> On Jun 24, 2009, at 10:00 PM, Meeraj Kunnumpurath wrote:
>>
>> Thanks for the quick reply Paul. Please see my comments inline ..
>>
>> On Wed, Jun 24, 2009 at 8:17 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>>
>>> Hi Meeraj,
>>>
>>> Using a MessageBodyReader is not really the write place to do this.
>>>
>>> The quick solution, using Jersey specific stuff, do the following:
>>>
>>> @Path("/myResource")
>>> public MyResource {
>>> @GET
>>> public String myMethod(@Context ResourceContext rc) {
>>> CustomType ct = rc.get(CustomType.class);
>>> }
>>> }
>>
>> Are there any convetions on CustomType? Also, can I annotate injection
>> sites within CustomType with @QueryParam, @PathParam etc?
>>
>>
>> I do not understand your question, can you present an example?
>>
> For eg, does the custom type need to follow Java beans pattern for query
> parameters, form parameters etc to be injected.
>
> public class CustomType {
> private String foo;
> private double bar;
>
> @QueryParam
> public void setFoo(String foo) {
> this.foo = foo;
> }
>
> @Formparam
> public void setBar(int bar) {
> this.bar = bar;
> }
>
> }
>
> Or does it support field level injection, constructor injection etc?
>
>>
>>>
>>> I have yet to implement injection directly for such cases, but it should
>>> not be hard to implement e.g.:
>>>
>>> @Path("/myResource")
>>> public MyResource {
>>> @GET
>>> public String myMethod(@InjectParam CustomType ct) {
>>> CustomType ct = rc.get(CustomType.class);
>>> }
>>> }
>>
>> I prefer this to the first one, as this will maintain the semantic
>> richness of the service contract.
>>
>>>
>>>
>>> It is also possible to plug in your own injection support for certain
>>> annotations, which is how the above would be implemented, deferring to
>>> ResourceContext. If you need more details on that, just say so, and i will
>>> write a very simple app to show you how it works.
>>
>> That will be hugely helpful. I have been integrating Jersey with an OSS
>> SCA container, I have been working on. We use JAX-RS as an SCA binding,
>> which means most of the JAX-RS annotations go on the interface rather than
>> the implementation class. We pass a proxy to the interface to the Jersey
>> runtime using the IOC container provider and invocations on the proxy from
>> the Jersey runtime are tunnelled back into the SCA runtime. Hence the
>> reason, I am looking at parameter based injection and not field or method
>> based injection sites as the lifecycle of the implementation class is
>> managed by the SCA container.
>>
>>
>> See attached. You may notice that ResourceContext.getResource(...) will
>> defer to any registered IoC container provider to get an instance (if it
>> supports the type) and it also validates that instance in terms of being a
>> resource class, so you will see the warning:
>>
>> WARNING: A resource class, class
>> com.sun.jersey.samples.resourceinject.Main$MyBean, does not
>> have any resource method, sub-resource method, or sub-resource locator.
>>
>> Basically ResourceContext can be used in sub-resource locators to get a
>> sub-resource with injected values that is then returned.
>>
> Thanks a lot, I will take a look tonight and get back to you if I have any
> questions.
>
>>
>>
>>>
>>> Form parameters are slightly different in that they can only be supported
>>> for a resource method that consumes a certain media type, so it would
>>> require slightly different support, there is an issue open to implement
>>> support form param beans.
>>
>> Yeah, I thought so as well. However, a uniform mechanism that can deal
>> with query and form parameters would be great.
>>
>>
>> I think a uniform mechanism is a bad idea. They are two very distinct ways
>> of encoding information (even if they encode the information using a similar
>> syntax).
>>
>> Unification encourages the view that GET with query parameters and POST
>> with an entity with form parameters are interchangeable. And thus encourages
>> the use of GET with side-effects.
>>
>> Servlet makes the mistake of unifying form and query parameters. One has
>> no easy way of knowing if a parameter belongs to the query part of a URI or
>> a form parameter. There may exist query parameters and form parameters of
>> the same name but with different semantics. It also causes all sorts of
>> problems when filters call the parameters, which can consume the request
>> entity.
>>
>> Paul.
>>
> Yeah, that is sensible. I was only thinking about someone who comes from
> the Servlet programming model, may treat everything as request.getParameter.
>
>