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/ >
