Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 1C7DB200BA8 for ; Mon, 24 Oct 2016 11:10:46 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 1B129160AEB; Mon, 24 Oct 2016 09:10:46 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 12632160AE1 for ; Mon, 24 Oct 2016 11:10:44 +0200 (CEST) Received: (qmail 2950 invoked by uid 500); 24 Oct 2016 09:10:44 -0000 Mailing-List: contact users-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@cxf.apache.org Delivered-To: mailing list users@cxf.apache.org Received: (qmail 2938 invoked by uid 99); 24 Oct 2016 09:10:43 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 24 Oct 2016 09:10:43 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 2A92AC05D3 for ; Mon, 24 Oct 2016 09:10:43 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.879 X-Spam-Level: X-Spam-Status: No, score=0.879 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_REPLY=1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=disabled Authentication-Results: spamd1-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id TuceCAyKTRde for ; Mon, 24 Oct 2016 09:10:40 +0000 (UTC) Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTPS id 208695FC14 for ; Mon, 24 Oct 2016 09:10:40 +0000 (UTC) Received: by mail-wm0-f50.google.com with SMTP id f193so104346973wmg.0 for ; Mon, 24 Oct 2016 02:10:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding; bh=+2SstOOsIGnpKejRNporjPH+jhU6exgeESVaszyoKwA=; b=PUO+CLkFmTr24I9QWlNWNf+HmnXaNVhDKViYj2VkVC99JHyVdiqAfpkVW2NkifTdsp G/U5ZuFJlmuCjBa1m2gx1Qwix375xQfzRY+nShF4TdRbWv+tuJ32PjgOIQrZ43M6sAxz 3JHDUMwCj3J8tyZCMz6isbTkelbUjhdJ4biT4ecE6k44ioYXt/R74/vnU3Y1V7OChKGx J3BczT/6168S04Z4owlCS16BeMSu7XcW1+o9T5nJMfsczWqZ39FUkb2h+aINs4ud/Mpe XilnM2sgfyO07/Zz6ci9YB+JuVc4c0Au9MH3nSJHq3RCgO3yBHwzZxr66HsSnNk0dvRA YP9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=+2SstOOsIGnpKejRNporjPH+jhU6exgeESVaszyoKwA=; b=koZwXSSnjIf/ZmZUsPhRPdA0s7lHP9Yv6An6n0Xc2YxBXd8p1GiLrlQbRIgww7nFQG otOAqfJKO2XRTPvIaRqFH8VUMf+HpXLxppvuYsWFZTL/3EDXAOK0tkKnxeGTfvyqGC3b DnqegGYRp8Hd/PzVkUSZFNqIh8/tVsNKHIBQdCiR4tW5cAUaZkGSv0sFC14PI8OtMvgV CdXGVEuon32js6H3CizT81G9SdMD9LCDG6NT30ON66uDWKV+PpoiC74bhTay8g+VGbsC 081C3bClHB5X4z67gyXUCFtYcdGsl5OAb9//EPSmNS2Z86wQkcNkC6VQao+S5nUCEvZf 9nhA== X-Gm-Message-State: AA6/9RnN6y1JbN/IuHR6i1aPf4Uk0jhfk5fln98aRYs6LrudFm/A+S9PMHbx16OLHlTqBA== X-Received: by 10.28.150.134 with SMTP id y128mr15134226wmd.6.1477300235409; Mon, 24 Oct 2016 02:10:35 -0700 (PDT) Received: from [192.168.2.7] ([79.97.121.181]) by smtp.googlemail.com with ESMTPSA id 194sm15213250wmj.0.2016.10.24.02.10.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Oct 2016 02:10:34 -0700 (PDT) Subject: Re: ParamCoverter, List, CSV query parameters To: users@cxf.apache.org References: <8002e0d4-1bfb-a098-cf67-9cf9f2897bc4@gmail.com> <8ebbae4a-a947-b480-ee6f-b94ae5ce900b@gmail.com> <2fef6a74-edc0-c29f-10e1-ad891a5495a6@gmail.com> <10ba1cdf-9e06-3cf4-8728-c2cb2250c8f6@gmail.com> <594889ac-5005-aa28-035b-25237cd4b262@gmail.com> From: Sergey Beryozkin Message-ID: <72ebff53-540e-2648-2217-94ff1a58d398@gmail.com> Date: Mon, 24 Oct 2016 10:10:24 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit archived-at: Mon, 24 Oct 2016 09:10:46 -0000 Hi Diego Hope you've had enough time to recover before a new working day :-) Here are the reasons I won't agree with it before either JAX-RS 2.1 or future TCK will force CXF to do it: 1. Minor: IMHO it is wrong to expect a custom param converter to guarantee it parses all of the query component string correctly. And what about @MatrixParam List where a given matrix parameter can be expected to be spread across multiple path segments, should the runtime pass all the relative request URI for the custom converter to parse it all, I don't think it makes sense. Can you try '/a;m=1/b;m=2' with Jersey where 'm' has two values, 1 and 2 ? 2. Major: The service code which types List *must* see all the multiple values from a standard HTTP multi-value query. It is completely wrong for the runtime to depend on the user provider to guarantee it. If the runtime can not guarantee it it just breaks JAX-RS in a little way. And from what I've understood, having List will simply not work for a standard multi-value query in Jersey even with its current undocumented and undiscussed (on the specs list) algorithm where it simply drops all but a first value which it passes to ParamConverter>. The reason it fails is because when you have ?a=1&a=2 @GET public Response get(@QueryParam("a") List list) {} where 'A' is a custom class which can be initialized only with the help of ParamConverter then as we already know Jersey drops 'a=2', but without ParamConverter the runtime will be unable to convert 'a' values to A. Even if you have '@QueryParam("a") List list' where '1' & '2' values require some decoration, it won't work with Jersey. The last thing JAX-RS needs is a 'feature' like this one, in addition to some of the selection algorithm issues. So, in Jersey, when a service expects List and a user registers ParamConverter> - it works if a query is typed '?a=1,2' where '1,2' is a single query property value but fails if it is a typical multi-value property '?a=1&a=2' or even '?a=1,2&a=3' (i.e the service code loses the 2nd/etc values - not acceptable) in CXF, when a service expects List and a user registers ParamConverter - it works if a query is typed as a typical multi-value property '?a=1&a=2' but does not for 'a=1,2' *unless* a property (which you mentioned earlier) is set up requiring the runtime to treat 'a=1,2' as a multi-value property. Even if you look at say https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/javax/ws/rs/QueryParam.html, note a point "5. Be List, Set, SortedSet where *T* satisfies 2, 3, 4' where '4' is about having a ParamConverterProvider for *T*, not List/Set I recommend you to open a Jersey bug. Unless it works correctly for 'a=1&a=2' if you only have ParamConverter with the service expecting List ? Thanks, Sergey On 23/10/16 23:44, Diego Ruotolo wrote: > I have to say that I don't understand your objection (in my defense: here > is almost 1:00 AM... :-) ), could you please clarify? > > Probably the best solution will be to have a kinda > MultipleParamConverter interface in JAX-RS 2.1 specs defining two > methods: > T fromStrings(String[] values); > String[] toStrings(T value); > > The fromStrings() method will build the object used as argument in the > requested resource method. > But I'll let people more expert than me discuss on this. > > Thanks, > > Diego > > 2016-10-24 0:30 GMT+02:00 Sergey Beryozkin : > >> I can't agree to this. So a user registering a custom List provider breaks >> the runtime ensuring the service code sees all the multiple values. >> >> I can try and work with spec leads on clarifying it for JAX-RS 2.1. >> >> Thanks, Sergey >> >> >> On 23/10/16 23:27, Diego Ruotolo wrote: >> >>> Hi, >>> >>> - when using multiple-value parameters passed in the URI in an HTTP >>> >>>> compliant-way (PARAM=V1&PARAM=V2&PARAM=V3), the ParamConverter takes only >>>>> the first value, hence if the ParamConverter builds a list, it will be a >>>>> list of only one value >>>>> >>>>> >>>> Are you saying this loses V2 & V3 ? >>>> >>>> >>> Yes, in this case it loses V2 & V3. AFAIK the only way in Jersey to get a >>> correct parsing of a multiple-valued query parameter is not to write a >>> custom ParamConverter. >>> >>> Cheers, >>> >>> Diego >>> >>> >>> >>> Thanks, Sergey >>>> >>>> >>>> - when not using a custom ParamConverter, the multiple-value parameter >>>> >>>>> parsing (the example above) works correctly >>>>> >>>>> Therefore what I am trying to achieve (CSV query parameter) can be done >>>>> on >>>>> Jersey by developing a custom ParamConverter, without explicitly write >>>>> an >>>>> Jersey extension, because it is a single value that generates a List >>>>> that >>>>> will be passed as a whole as argument of the requested resource method. >>>>> >>>>> Hope that this clarify, >>>>> >>>>> cheers, >>>>> >>>>> Diego >>>>> >>>>> 2016-10-17 17:37 GMT+02:00 Sergey Beryozkin : >>>>> >>>>> Hi >>>>> >>>>>> >>>>>> In the JAX-RS users thread which I referred to below I did ask about >>>>>> and >>>>>> I >>>>>> don't think I got a +1 from one the spec leads on having >>>>>> ParamConverterProvider supporting List, please check the archives. >>>>>> And as I said IMHO the converters should not deal with interpreting for >>>>>> ex >>>>>> the whole query component value. >>>>>> But can you investigate please how Jersey handles it ? >>>>>> >>>>>> In Pre-match you can figure out if a given CSV value is a multi-value >>>>>> or >>>>>> not based on the current request URI (the relative parts), I agree it >>>>>> will >>>>>> be less safe compared to the use of annotations >>>>>> >>>>>> Cheers, Sergey >>>>>> >>>>>> >>>>>> On 17/10/16 15:56, Diego Ruotolo wrote: >>>>>> >>>>>> Hi Sergey, >>>>>> >>>>>>> >>>>>>> I think you are definitively right when you say you don't want to >>>>>>> introduce >>>>>>> a CXF specific extension at a standard JAX-RS interface level. But >>>>>>> taking >>>>>>> a >>>>>>> look at the JAX-RS specs it is not specified that ParamConverter >>>>>>> should >>>>>>> handle just single values in a collection and not the whole >>>>>>> collection: >>>>>>> I >>>>>>> think that both interpretations are valid, but maybe I am missinig >>>>>>> something. >>>>>>> >>>>>>> Regarding the use of a @PreMatch filter, I don't think it is >>>>>>> possible: I >>>>>>> can't read annotations on a method parameter in a @PreMatch filter >>>>>>> since >>>>>>> the server resource is not bound yet, and I can't change parameter >>>>>>> values >>>>>>> in a post-match filter since it is impossible to change the URI (by >>>>>>> specs). >>>>>>> Furthermore, in a post-match filter the server resource is bound but >>>>>>> not >>>>>>> yet "filled" with values. >>>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> Diego >>>>>>> >>>>>>> diego.ruotolo@gmail.com >>>>>>> >>>>>>> 2016-10-17 16:28 GMT+02:00 Sergey Beryozkin : >>>>>>> >>>>>>> Hi Diego >>>>>>> >>>>>>> >>>>>>>> But that would introduce a CXF specific extension at a standard >>>>>>>> JAX-RS >>>>>>>> interface level. In general I'm quite open to adding new extensions >>>>>>>> but >>>>>>>> I'd rather not to in this case...Besides, IMHO, it really should be >>>>>>>> the >>>>>>>> job for the JAX-RS runtime, to parse the multivalued query/matrix >>>>>>>> properties. >>>>>>>> What you might want to experiment with is to add a prematch request >>>>>>>> filter >>>>>>>> which will reset a query string if needed to have List >>>>>>>> working >>>>>>>> for >>>>>>>> either a=1&a=2 or a=1,2, etc >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Thanks, Sergey >>>>>>>> >>>>>>>> On 17/10/16 12:46, Diego Ruotolo wrote: >>>>>>>> >>>>>>>> Hi Sergey, >>>>>>>> >>>>>>>> >>>>>>>>> thanks for your answer. >>>>>>>>> I think a good solution could be to pass the ParamConverter a string >>>>>>>>> containing all the values of a multi-valued query parameter, and let >>>>>>>>> the >>>>>>>>> user build the collection object. >>>>>>>>> So, if I have a query string like: >>>>>>>>> MY_PARAM=VALUE_1&FOO=BAR&MY_PARAM=VALUE_2, the ParamConvert should >>>>>>>>> receive >>>>>>>>> the string MY_PARAM=VALUE_1&MY_PARAM=VALUE_2, and the user should >>>>>>>>> build >>>>>>>>> the >>>>>>>>> collection in in the fromString() method. In this way the user can >>>>>>>>> deal >>>>>>>>> with both the whole collection and its single values. >>>>>>>>> I also suggest this behaviour should be activated through a property >>>>>>>>> in >>>>>>>>> order not to break backward compatibility. >>>>>>>>> What do you think? >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> >>>>>>>>> Diego >>>>>>>>> >>>>>>>>> 2016-10-17 11:47 GMT+02:00 Sergey Beryozkin : >>>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> >>>>>>>>> Thanks for this query, let me redirect to the CXF users list. >>>>>>>>>> >>>>>>>>>> FYI, CXF JAX-RS runtime prepares a List itself and only expects >>>>>>>>>> ParamConverters if any to convert individual values. >>>>>>>>>> >>>>>>>>>> I believe RI (Jersey) will also act the same way - but I may be >>>>>>>>>> wrong >>>>>>>>>> now. >>>>>>>>>> You can check a "ParamConverter and Collections" thread on the >>>>>>>>>> jaxrs >>>>>>>>>> users >>>>>>>>>> list. My understanding there was no any agreement reached. >>>>>>>>>> >>>>>>>>>> Cheers, Sergey >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On 16/10/16 23:48, Diego Ruotolo wrote: >>>>>>>>>> >>>>>>>>>> Hi everybody, >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> this is my first post to this mailing list. >>>>>>>>>>> I am using Apache CXF and I have the following problem: I need to >>>>>>>>>>> read a >>>>>>>>>>> multiple-value query parameter that is written in a >>>>>>>>>>> comma-separated-values (CSV) format, hence non standard HTTP way. >>>>>>>>>>> I know that this will be fixed in versions 3.1.8 and 3.2.0 with >>>>>>>>>>> the >>>>>>>>>>> contextual property "parse.query.value.as.collection", as written >>>>>>>>>>> here: >>>>>>>>>>> https://issues.apache.org/jira/browse/CXF-6941 >>>>>>>>>>> but the above solution works for ALL query parameters, I want to >>>>>>>>>>> be >>>>>>>>>>> selective, for instance I just want query parameters annotated >>>>>>>>>>> with >>>>>>>>>>> @MyAnnotation to be parsed as CSV collection, other query >>>>>>>>>>> parameters >>>>>>>>>>> may >>>>>>>>>>> accept commas as a value. >>>>>>>>>>> Therefore I've written a ParamConverter provided by a >>>>>>>>>>> ParamConverterProvider: the latter reads the annotation and >>>>>>>>>>> returns >>>>>>>>>>> the >>>>>>>>>>> appriopriate ParamConverter that converts a String into a List. >>>>>>>>>>> But >>>>>>>>>>> this >>>>>>>>>>> is not working since the returned List is used as first element of >>>>>>>>>>> the >>>>>>>>>>> linked method parameter, so in the end I have a List of List. >>>>>>>>>>> >>>>>>>>>>> Example: >>>>>>>>>>> >>>>>>>>>>> Query parameter: MY_PARAM=VALUE_1,VALUE_2,VALUE_3 >>>>>>>>>>> Method parameter: List myParam; // Here I put "?" instead of >>>>>>>>>>> "String" >>>>>>>>>>> as generic type in order to explain this example >>>>>>>>>>> ParamConverter fromString() method: return >>>>>>>>>>> Arrays.asList(value.split(",")); //returns a List >>>>>>>>>>> Expected result: myParam is a List, a list of 3 elements >>>>>>>>>>> (VALUE_1, VALUE_2, VALUE_3) >>>>>>>>>>> Actual result: myParam is a List>, a list with one >>>>>>>>>>> element, >>>>>>>>>>> this single element is a list of 3 elements (VALUE_1, VALUE_2, >>>>>>>>>>> VALUE_3) >>>>>>>>>>> >>>>>>>>>>> It seems that when used in conjuction with a List (a Collection?) >>>>>>>>>>> method >>>>>>>>>>> parameter, a ParamConverter works per-element, not for the whole >>>>>>>>>>> list. >>>>>>>>>>> Is this the correct behaviour? Do you know some work-around that I >>>>>>>>>>> could >>>>>>>>>>> use without writing an Apache CXF Interceptor (I don't want to be >>>>>>>>>>> bound >>>>>>>>>>> to an implementation of JAX-RS) ? >>>>>>>>>>> I've noticed that Jersey has a similar issue too: >>>>>>>>>>> https://java.net/jira/browse/JERSEY-2763 >>>>>>>>>>> >>>>>>>>>>> Thanks in advice, >>>>>>>>>>> >>>>>>>>>>> best regards >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> >>>>>>>>>> Sergey Beryozkin >>>>>>>>>> >>>>>>>>>> Talend Community Coders >>>>>>>>>> http://coders.talend.com/ >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>> -- >>>>>> Sergey Beryozkin >>>>>> >>>>>> Talend Community Coders >>>>>> http://coders.talend.com/ >>>>>> >>>>>> >>>>>> >>>>> >>>> -- >>>> Sergey Beryozkin >>>> >>>> Talend Community Coders >>>> http://coders.talend.com/ >>>> >>>> >>> >> >