cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: ParamCoverter, List, CSV query parameters
Date Mon, 24 Oct 2016 09:10:24 GMT
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<A> 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<A> *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<A> 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<List<A>>.

The reason it fails is because when you have

?a=1&a=2

@GET
public Response get(@QueryParam("a") List<A> list) {}

where 'A' is a custom class which can be initialized only with the help 
of ParamConverter<A>

then as we already know Jersey drops 'a=2', but without 
ParamConverter<A> the runtime will be unable to convert 'a' values to A.

Even if you have '@QueryParam("a") List<String> 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<SomeType> and a user 
registers ParamConverter<List<SomeType>>

- 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<SomeType> and a user registers 
ParamConverter<SomeType>

- 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<T>, Set<T>, SortedSet<T> where *T* satisfies 2, 3, 
4' where '4' is about having a ParamConverterProvider for *T*, not 
List<T>/Set<T>


I recommend you to open a Jersey bug. Unless it works correctly for 
'a=1&a=2' if you only have ParamConverter<A> with the service expecting 
List<A> ?

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<T> 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 <sberyozkin@gmail.com>:
>
>> 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 <sberyozkin@gmail.com>:
>>>>>
>>>>> 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 <sberyozkin@gmail.com>:
>>>>>>>
>>>>>>> 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<String>
>>>>>>>> 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 <sberyozkin@gmail.com>:
>>>>>>>>>
>>>>>>>>> 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<String>
>>>>>>>>>>> Expected result: myParam is a List<String>,
a list of 3 elements
>>>>>>>>>>> (VALUE_1, VALUE_2, VALUE_3)
>>>>>>>>>>> Actual result: myParam is a List<List<String>>,
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/
>>>>
>>>>
>>>
>>
>


Mime
View raw message