Return-Path: X-Original-To: apmail-cxf-dev-archive@www.apache.org Delivered-To: apmail-cxf-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DA25C555A for ; Thu, 12 May 2011 20:51:52 +0000 (UTC) Received: (qmail 16399 invoked by uid 500); 12 May 2011 20:51:52 -0000 Delivered-To: apmail-cxf-dev-archive@cxf.apache.org Received: (qmail 16340 invoked by uid 500); 12 May 2011 20:51:52 -0000 Mailing-List: contact dev-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list dev@cxf.apache.org Received: (qmail 16332 invoked by uid 99); 12 May 2011 20:51:52 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 May 2011 20:51:52 +0000 X-ASF-Spam-Status: No, hits=4.0 required=5.0 tests=FREEMAIL_FROM,FREEMAIL_REPLY,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,SPF_PASS,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of biju74techie@gmail.com designates 209.85.220.169 as permitted sender) Received: from [209.85.220.169] (HELO mail-vx0-f169.google.com) (209.85.220.169) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 May 2011 20:51:47 +0000 Received: by vxk20 with SMTP id 20so1878020vxk.0 for ; Thu, 12 May 2011 13:51:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type; bh=y+S98b/YlCJ377pydlXjQ6XQdSrT7NmrynMemo0EIAY=; b=NeFBKPvBw0NjXsD1/T9eRvBkJ1g8v/xIFOfZFCcxWDnCLZg+3PmapRKz48U/9rnykp 2/ExDULKgmG//WN/j5sXolXrKujme/UJ2Vpzv08QQrC7cC9tPrK2BFmZINfaQglaj0Q+ aTZ8Zn14HBaoQDwqr7LMnzw1HpReMsZXROEM8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=OHs+NYjGgRlp7AApLCwhol8BZNu+BPtomJtitGOYYY1Js+tsEy9AVI+tlaKUFvy6e1 Lwmi8CBKrb3F9BZtWHGV0ztCE1kbEajqEqK+dM8qniIiiPw/dNAY6RdOawHQQ+7T0HrA Y+VDAznhb8HDwoacM7i4q1PAQGSf3nwWLLDDw= MIME-Version: 1.0 Received: by 10.52.107.195 with SMTP id he3mr974835vdb.12.1305233485176; Thu, 12 May 2011 13:51:25 -0700 (PDT) Received: by 10.52.165.97 with HTTP; Thu, 12 May 2011 13:51:25 -0700 (PDT) In-Reply-To: References: Date: Thu, 12 May 2011 13:51:25 -0700 Message-ID: Subject: Re: Custom Reuqest Param Name for Bean Request Object From: Biju Nair To: dev@cxf.apache.org Content-Type: multipart/alternative; boundary=bcaec548a0c53ba06604a31a5a61 --bcaec548a0c53ba06604a31a5a61 Content-Type: text/plain; charset=ISO-8859-1 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 wrote: > Hi > > On Thu, May 12, 2011 at 8:21 PM, Biju Nair wrote: > > Just to clarify, > > > > the user bean will be something like, > > class User{ > > Map 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¶ms.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 >wrote: > > > >> Hi > >> > >> On Thu, May 12, 2011 at 5:55 PM, Biju Nair > 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= and in second parameter new TestAddress object is > >> > creates and put into map as testAddress=. > >> > > >> > 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¶ms.k2=v2 > >> > >> where a User bean has Map 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 > >> 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 > --bcaec548a0c53ba06604a31a5a61--