cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Biju Nair <biju74tec...@gmail.com>
Subject Re: Custom Reuqest Param Name for Bean Request Object
Date Thu, 12 May 2011 20:51:25 GMT
Which version of CXF you are working on?

I was working with 2.3.1.

On Thu, May 12, 2011 at 1:08 PM, Sergey Beryozkin <sberyozkin@gmail.com>wrote:

> Hi
>
> On Thu, May 12, 2011 at 8:21 PM, Biju Nair <biju74techie@gmail.com> wrote:
> > Just to clarify,
> >
> > the user bean will be something like,
> > class User{
> >   Map<String, String> params;
> > }
> >
> > Request Data will be user.params.k1=v1&*user.*params.k2=v2
>
> Yes if User is a nested bean, otherwise just
> params.k1=v1&params.k2=v2
>
> if we have FormParam("") User
>
> >
> > Finally, the params map will have [{k1=v1},{k2=v2}]
> >
> > Right?
> Yes
>
> >
> > I will check this and let you know.
> >
> Ok, thanks. By the way I'm planning to have this code reused for
> handling more involved FIQL queries, ex, one can do
>
> /books?_s=id=gt=1
>
> "Find all books with id greater than 1"
>
> but we can't express the same query if Book happens to have a nested
> ID bean, etc:
>
> /books?_s=id=gt=id.1
>
> Cheers, Sergey
>
> > Biju B
> >
> > On Thu, May 12, 2011 at 10:52 AM, Sergey Beryozkin <sberyozkin@gmail.com
> >wrote:
> >
> >> Hi
> >>
> >> On Thu, May 12, 2011 at 5:55 PM, Biju Nair <biju74techie@gmail.com>
> wrote:
> >> > Yes I understood that we don't need two solution for same problem :).
> >> >
> >> > Just want you let know, if you try to put something like
> >> > "testaddress.City=Pleasanton&testAddress.stateName=CA"
> >> > testAddress.stateName will not be populated. What I saw in your code
> is,
> >> for
> >> > first parameter the TestAddress instance is created and put into map
> as
> >> > testaddress=<object> and in second parameter new TestAddress object
is
> >> > creates and put into map as testAddress=<object>.
> >> >
> >> > Code Says ==> parsedValues.put(beanKey, value);
> >> >
> >> I see, I checked the actual property name, such as "set+ 'stateName'"
> >> is checked against available methods (and I guess fields) in a
> >> case-insensitive way...
> >>
> >> > Anyway thanks for the discussion.
> >> >
> >> cool, thanks for starting it up
> >>
> >> > Can you elaborate on "Maps are not supported for example" - Let me see
> >> > whether I can contribute?
> >> >
> >> Awhile back, a user asked about it but I recall I just did not get to
> >> doing it, example
> >>
> >> user.params.k1=v1&params.k2=v2
> >>
> >> where a User bean has Map<String, String> property, which can be handy
> >> in some cases too.
> >> have a look please if you get a chance
> >>
> >> Cheers, Sergey
> >>
> >> > Biju B
> >> >
> >> > On Thu, May 12, 2011 at 2:43 AM, Sergey Beryozkin <
> sberyozkin@gmail.com
> >> >wrote:
> >> >
> >> >> Hi
> >> >>
> >> >> On Wed, May 11, 2011 at 5:34 PM, Biju Nair <biju74techie@gmail.com>
> >> wrote:
> >> >> > Thanks for the reply.
> >> >> >
> >> >> > Just for clarification,
> >> >> > If I have a Employee bean as follows,
> >> >> > class Employee{
> >> >> >    String name;
> >> >> >    Address homeAddress;
> >> >> >   //getters and setters are there
> >> >> > }
> >> >> >
> >> >> > class Address{
> >> >> >    String line1;
> >> >> >   String line2;
> >> >> >   //getters and setters are there
> >> >> > }
> >> >> > there is a rest service as String update(@FormParam("") Employee
> >> >> employee)
> >> >> >
> >> >> > In the current approach, we need to pass request data as *
> >> >> > name=Joe&homeAddress.line1=MyLocation&homeAddress.line2=MyStreet*
> >> >> >
> >> >> > which means we need to have homeAddress as case sensitive right?
> and
> >> it
> >> >> > won't work with "homeaddress.line1" right?
> >> >>
> >> >> No, the comparison is case-insensitive.
> >> >>
> >> >> > Also later if we try to change the variable names we need to ask
> all
> >> the
> >> >> > clients to change the request params. Am I right or something
> missing
> >> >> here.
> >> >> >
> >> >>
> >> >> I guess some care has to be taken with regard to refactoring the bean
> >> >> class which is meant to capture the input from
> >> >> remote clients.
> >> >>
> >> >> If you have a User.setAddress() method which is meant to capture an
> an
> >> >> 'address' property then yes, if you go ahead and remove it or rename
> >> >> it to setUserAddress then yes, "address" property won't be injected
-
> >> >> but customers does not have to be affected in such cases - replacing
> >> >> the form submission payload can be easily done on the server side,
> ex,
> >> >> at the RequestFilter level or better yet, by providing a custom
> >> >> MessageBodyReader which extends CXF FormEncodingProvider and
> overrides
> >> >> its populateMap method - let superclass to read the data and then
> just
> >> >> replace the key 'address' with say 'customerAddress'
> >> >>
> >> >> Look, as I tried to say in the previous email, it's basically not
> >> >> about CXF solution is better then yours, etc :-). I just don't think
> >> >> we should have two solutions for this case 'shipped' with CXF. The
> CXF
> >> >> one may not be ideal but it has its benefits too, one of them is that
> >> >> WADLGenerator can understand such beans when generating query or form
> >> >> parameters, etc, the other one is that JAX-RS proxies understand how
> >> >> to deal with them, etc.
> >> >>
> >> >> I'd encourage you to help us to improve the existing solution if you
> >> >> find some drawbacks. Maps are not supported for example.
> >> >>
> >> >> Thanks, Sergey
> >> >>
> >> >> Cheers, Sergey
> >> >>
> >> >> > Please confirm.
> >> >> >
> >> >> > Biju B
> >> >> >
> >> >> >
> >> >> >
> >> >> > On Wed, May 11, 2011 at 1:45 AM, Sergey Beryozkin <
> >> sberyozkin@gmail.com
> >> >> >wrote:
> >> >> >
> >> >> >> Hi
> >> >> >>
> >> >> >> On Tue, May 10, 2011 at 10:07 PM, Biju Nair <
> biju74techie@gmail.com>
> >> >> >> wrote:
> >> >> >> > Thanks for the reply.
> >> >> >> >
> >> >> >> > But in the first approach the client users has to follow
Java
> >> naming
> >> >> >> > conventions (espc a non-java client) right?
> >> >> >> Clients use "user.name" or "user.address.value" if they need
to,
> the
> >> >> >> difference between the two approaches
> >> >> >> in that with your annotations you can selectively point to
a
> >> >> >> particular field and say this is what "user.name" has to be
> mapped
> >> to,
> >> >> >> while with the default approach one has to make sure nested
beans
> are
> >> >> >> available.
> >> >> >>
> >> >> >> >
> >> >> >> > Regarding the MultiValueMap, i like the idea, but not
for Bean
> >> based.
> >> >> >> Here
> >> >> >> > the developers need to convert the map to Bean right?
> >> >> >> >
> >> >> >> > I still prefer to use *@FormParam("") object*, because
this
> looks
> >> like
> >> >> >> > standard in CXF for primitive type arguments.
> >> >> *@FormParam("identifier")
> >> >> >> id.*
> >> >> >>
> >> >> >> I like @FormParam("") too, it's a  CXF extension (using ""),
but
> it
> >> >> >> allows for capturing many values while still allowing for
some
> >> >> >> flexibility re property types  as opposed to using  MultiValuedMap
> >> >> >> (which is JAX-RS compliant).
> >> >> >>
> >> >> >> > **
> >> >> >> > I think you can ask the same contributer to include the
> annotation
> >> >> >> approach
> >> >> >> > or some custom way of declaring user-defined names, rather
than
> >> java
> >> >> >> > variables.
> >> >> >> >
> >> >> >>
> >> >> >> As I said the problem is how to have "user.a.b.c" mapped to
a
> >> >> >> particular property. CXF has one solution for it which I think
is
> >> good
> >> >> >> enough. Your solution is also interesting but I'm not sure
CXF
> should
> >> >> >> multiple solutions for this particular issue
> >> >> >>
> >> >> >> Thanks, Sergey
> >> >> >>  > Biju B
> >> >> >> >
> >> >> >> > On Tue, May 10, 2011 at 1:22 PM, Sergey Beryozkin <
> >> >> sberyozkin@gmail.com
> >> >> >> >wrote:
> >> >> >> >
> >> >> >> >> Hi
> >> >> >> >>
> >> >> >> >> Please see comments inline
> >> >> >> >>
> >> >> >> >> On Tue, May 10, 2011 at 8:29 PM, Biju Nair <
> >> biju74techie@gmail.com>
> >> >> >> wrote:
> >> >> >> >> > Hi Team,
> >> >> >> >> >
> >> >> >> >> > Currently I was helping a team in building rest
based
> services
> >> >> using
> >> >> >> CXF.
> >> >> >> >> I
> >> >> >> >> > noticed that for bean based service arguments
(*Ex. String
> >> >> >> >> > getData(@FormParam("") TestObj tObj)*)
> >> >> >> >> > you have to include @FormParam with empty qualifer
name and
> the
> >> >> >> request
> >> >> >> >> > parameter should follow bean property naming
conventions. Say
> >> >> example
> >> >> >> >> > if TestObj has a property 'userName' (which
is java style)
> then
> >> the
> >> >> >> >> request
> >> >> >> >> > parameter should be userName=Joe.
> >> >> >> >> > But in our requirement (mostly everywhere) the
request
> >> parameters
> >> >> need
> >> >> >> >> not
> >> >> >> >> > use the Java Style. Here we were asked to use
'user.name'.
> >> >> >> >> >
> >> >> >> >> > I know for non-bean based parameters CXF supports
this as
> >> >> @FormParam("
> >> >> >> >> > user.name") String userName, Is this possible
for Bean Based
> >> also?
> >> >> >> >> >
> >> >> >> >> > As part of providing solution to team, I wrote
a CXF Request
> >> >> Handler,
> >> >> >> >> > which transforms all the request based parmeters
to bean
> based.
> >> >> >> >> > Now the TestObj will looks like,
> >> >> >> >> > class TestObject {
> >> >> >> >> >       @RequestParam("user.name")
> >> >> >> >> >       String userName;
> >> >> >> >> > ...
> >> >> >> >> > }
> >> >> >> >> > Using the @ReuestParam I will be identifying
the actual
> request
> >> >> param.
> >> >> >> >> > The component I wrote supports primitives, nested
beans and
> >> >> >> collections
> >> >> >> >> > also.
> >> >> >> >> >
> >> >> >> >> That is interesting, however I think your requirement
can
> already
> >> be
> >> >> >> >> handled:
> >> >> >> >>
> >> >> >> >> public class TestObject {
> >> >> >> >>    public User getUser() {
> >> >> >> >>         return new User();
> >> >> >> >>    }
> >> >> >> >>    public void setUser(User user) {}
> >> >> >> >> }
> >> >> >> >>
> >> >> >> >> public class User {
> >> >> >> >>    public String getName() {
> >> >> >> >>         return name;
> >> >> >> >>    }
> >> >> >> >>    public void setName(String name) {}
> >> >> >> >> }
> >> >> >> >>
> >> >> >> >> That is more verbose that your solution but the user
who
> >> contributed
> >> >> >> >> the patch earlier on did a lot of work for nested
beans to
> work,
> >> with
> >> >> >> >> collections supported as well. And no extra annotations
is
> >> required.
> >> >> >> >>
> >> >> >> >> Another option is just use MultivaluedMap in case
of form
> >> submissions
> >> >> >> >> or explicit FormParam("user.name")
> >> >> >> >>
> >> >> >> >> What do you think ?
> >> >> >> >>
> >> >> >> >>
> >> >> >> >> Cheers, Sergey
> >> >> >> >>
> >> >> >> >> > *My Suggestion is can you include this feature
in next
> version
> >> of
> >> >> CXF?
> >> >> >> >> and
> >> >> >> >>  > Can I contribute my code?*
> >> >> >> >> >
> >> >> >> >> > Biju B
> >> >> >> >> >
> >> >> >> >>
> >> >> >> >>
> >> >> >> >>
> >> >> >> >> --
> >> >> >> >> Sergey Beryozkin
> >> >> >> >>
> >> >> >> >> Application Integration Division of Talend
> >> >> >> >> http://sberyozkin.blogspot.com
> >> >> >> >>
> >> >> >> >
> >> >> >>
> >> >> >>
> >> >> >>
> >> >> >> --
> >> >> >>  Sergey Beryozkin
> >> >> >>
> >> >> >> Application Integration Division of Talend
> >> >> >> http://sberyozkin.blogspot.com
> >> >> >>
> >> >> >
> >> >>
> >> >>
> >> >>
> >> >> --
> >> >>  Sergey Beryozkin
> >> >>
> >> >> Application Integration Division of Talend
> >> >> http://sberyozkin.blogspot.com
> >> >>
> >> >
> >>
> >>
> >>
> >> --
> >>  Sergey Beryozkin
> >>
> >> Application Integration Division of Talend
> >> http://sberyozkin.blogspot.com
> >>
> >
>
>
>
> --
>  Sergey Beryozkin
>
> Application Integration Division of Talend
> http://sberyozkin.blogspot.com
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message