cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Custom Reuqest Param Name for Bean Request Object
Date Thu, 12 May 2011 09:43:32 GMT
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

Mime
View raw message