Hi,

I investigated the behaviour of Jersey, and it acts like following.
Use case: a resource method that has a List<String> as query parameter
- the method getConverter() of ParamConverterProvider interfaces receives
as arguments: List as rawType, List<String> as type, @QueryParameter as
annotations
- the ParamConverter that converts String to List and viceversa builds the
List that would be the whole object passed as argument to the resource
method, not a single value like Apache CXF does.
- 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
- 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 <[email protected]>:

> 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
>>
>> [email protected]
>>
>> 2016-10-17 16:28 GMT+02:00 Sergey Beryozkin <[email protected]>:
>>
>> 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 <[email protected]>:
>>>>
>>>> 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/
>

Reply via email to