No, I've been asked not to change the existing REST interface when
changing the service. No worries, though. :)

On Thu, Oct 6, 2016 at 4:00 PM, Sergey Beryozkin <sberyoz...@gmail.com> wrote:
> May be you can do /a;from=10;till=90 or
> /a;range=10;range=90
>
> In the former case you'd have
>
> @MatrixParam("from") String
> @MatrixParam("till") String
>
> in the latter
>
> @MatrixParam("range") List<String>
>
> Sergey
>
> On 06/10/16 15:27, Christian Balzer wrote:
>>
>> I wanted to avoid having to do matrixParams.getList().get(0) when all
>> I wanted was matrixParams.get(0)... :)
>> That's the only reason, really...
>>
>> I thought if I have to convert partially in my class, I can just do
>> all of the conversion in my class, and not use cxf's facility at all.
>> And I thought it would work. I'm pretty sure I saw REST URLs in the
>> past that used ;range=10,90 for example - so I was sure cxf would
>> support it somehow... :)
>>
>> Cheers,
>>
>> Christian
>>
>> On Thu, Oct 6, 2016 at 2:58 PM, Sergey Beryozkin <sberyoz...@gmail.com>
>> wrote:
>>>
>>> Hi, why would you not have
>>>
>>> class MatrixParams {
>>>     List<String> list;
>>> }
>>>
>>> @MatrixParam("a") MatrixParams
>>>
>>> Sergey
>>>
>>>
>>> On 06/10/16 14:23, Christian Balzer wrote:
>>>>
>>>>
>>>> Hello,
>>>>
>>>> Well, you just pointed out that the converters are only supposed to
>>>> work on an individual element of a collection, and cxf' code is
>>>> looking at the param type to see if it is dealing with a collection
>>>> target type (which it will create at runtime, as you pointed out), to
>>>> which it needs to add these elements. So it basically gets confused
>>>> because I've defined my own collection type. It assumes it needs to
>>>> create a collection to add elements to, but the elements I create are
>>>> my own collection. That's how I end up with
>>>> Collection<Collection<Enum>>. Short of cxf checking the actual type of
>>>> the target parameter instead of whether it implements the Collection
>>>> interface, I don't think there is any way around it?
>>>>
>>>> In other words, what I wanted to do won't work in cxf. :/
>>>>
>>>> Regards,
>>>>
>>>> Christian
>>>>
>>>> On Thu, Oct 6, 2016 at 1:41 PM, Sergey Beryozkin <sberyoz...@gmail.com>
>>>> wrote:
>>>>>
>>>>>
>>>>> Hi
>>>>>
>>>>> Looks like a linking issue,
>>>>>
>>>>> Sergey
>>>>>
>>>>> On 06/10/16 13:24, Christian Balzer wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> So, I played around a bit more, and I now have a semi-working
>>>>>> solution. Semi-working, because I do get a List of enums back, which
>>>>>> is what I was actually after.
>>>>>> Not fully working, because it now blows up in the bowels of cxf
>>>>>> (3.1.6).
>>>>>>
>>>>>> Here is the mehtod signature - as a reminder, I'm trying to call
>>>>>> /foo;d=2016-10-06;f=a,b,c - and the LocalDate conversion works just
>>>>>> fine...
>>>>>> @GET
>>>>>> @Path("foo")
>>>>>> public Response foo(@MatrixParam("d") LocalDate date,
>>>>>> @MatrixParam("f") Foo foos) {
>>>>>> //...
>>>>>>
>>>>>> Here is my ParamConverterProvider - it is registered and gets called
>>>>>> for matrix parameter f - yay!
>>>>>> public class StringListHandler implements ParamConverterProvider{
>>>>>>     @Override
>>>>>>     public <T> ParamConverter<T> getConverter(final Class<T> rawType,
>>>>>> Type genericType, Annotation[] annotations) {
>>>>>>         if(rawType == CommaSeparatedList.class) {
>>>>>>             return (ParamConverter<T>) new
>>>>>> ParamConverter<CommaSeparatedList>() {
>>>>>>                 @Override
>>>>>>                 public CommaSeparatedList fromString(String value) {
>>>>>>                     CommaSeparatedList list = new
>>>>>> CommaSeparatedList(value);
>>>>>>                     return list;
>>>>>>                 }
>>>>>>                 @Override
>>>>>>                 public String toString(CommaSeparatedList value) {
>>>>>>                     return value.toString();
>>>>>>                 }
>>>>>>             };
>>>>>>         }
>>>>>>         return null;
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> Here is my target type. It extends ArrayList - and I think that is now
>>>>>> the problem...
>>>>>> public class CommaSeparatedList extends ArrayList<Foo> {
>>>>>>     public CommaSeparatedList(String value) {
>>>>>>         List<String> list = Arrays.asList(value.split("\\s*,\\s*"));
>>>>>>         List<Foo> foos = new ArrayList<>(list.size());
>>>>>>         for (String element : list) {
>>>>>>             foos.add(Foo.valueOf(element.toUpperCase()));
>>>>>>         }
>>>>>>         addAll(foos);
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> Here is the enum I'm using:
>>>>>> public enum Foo {
>>>>>>     A, B, C
>>>>>> }
>>>>>>
>>>>>> And here are the Exception and StackTrace cxf now throws at me after I
>>>>>> return my CommaSeparatedList , i.e. ArrayList<Foo> (extending
>>>>>> Collection):
>>>>>> java.lang.IllegalArgumentException: argument type mismatch
>>>>>> argument type mismatch while invoking public javax.ws.rs.core.Response
>>>>>>
>>>>>>
>>>>>>
>>>>>> com.example.rs.MyEndpoint.foo(org.joda.time.LocalDate,com.example.common.CommaSeparatedList)
>>>>>> with params [2016-10-06, [[A, B, C]]].
>>>>>> 0 = {StackTraceElement@3424}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:166)"
>>>>>> 1 = {StackTraceElement@3425}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:140)"
>>>>>> 2 = {StackTraceElement@3426}
>>>>>> "org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189)"
>>>>>> 3 = {StackTraceElement@3427}
>>>>>> "org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)"
>>>>>> 4 = {StackTraceElement@3428}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)"
>>>>>> 5 = {StackTraceElement@3429}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)"
>>>>>> 6 = {StackTraceElement@3430}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)"
>>>>>> 7 = {StackTraceElement@3431}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)"
>>>>>> 8 = {StackTraceElement@3432}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.transport.local.LocalConduit.dispatchDirect(LocalConduit.java:191)"
>>>>>> 9 = {StackTraceElement@3433}
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.transport.local.LocalConduit.close(LocalConduit.java:156)"
>>>>>> 10 = {StackTraceElement@3434}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)"
>>>>>> 11 = {StackTraceElement@3435}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)"
>>>>>> 12 = {StackTraceElement@3436}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:652)"
>>>>>> 13 = {StackTraceElement@3437}
>>>>>>
>>>>>>
>>>>>>
>>>>>> "org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1097)"
>>>>>> 14 = {StackTraceElement@3438}
>>>>>> "org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:894)"
>>>>>> 15 = {StackTraceElement@3439}
>>>>>> "org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:865)"
>>>>>> 16 = {StackTraceElement@3440}
>>>>>> "org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:331)"
>>>>>> 17 = {StackTraceElement@3441}
>>>>>> "org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:357)"
>>>>>>
>>>>>> I think the problem is in
>>>>>> AbstractInvoker.performInvocation(performInvocation.java:172) - mainly
>>>>>> because my debugger output at that position looks like this:
>>>>>> paramArray: Object[]  = {Object[2]@3320}
>>>>>>   0 = {LocalDate@3270} "2016-10-06"
>>>>>>   1 = {ArrayList@3295}  size = 1
>>>>>>     0 = {CommaSeparatedList@3294}  size = 3
>>>>>>
>>>>>> I think what I'd actually need - to conform with the method signature
>>>>>> of my foo() method in my endpoint from above - is something that looks
>>>>>> a bit more like this (i.e. without the extra ArrayList layer):
>>>>>> paramArray: Object[]  = {Object[2]}
>>>>>> 0 = {LocalDate}
>>>>>> 1 =  {CommaSeparatedLis}  size = 3
>>>>>>
>>>>>> Any idea how I can get that sorted, please?
>>>>>>
>>>>>> Again, the goal is to convert ;f=a,b,c into List<Foo>[3] with elements
>>>>>> A, B, and C...
>>>>>>
>>>>>> Kind regards,
>>>>>> Christian
>>>>>>
>>>>>> On Thu, Oct 6, 2016 at 12:20 AM, Christian Balzer
>>>>>> <christian.at....@gmail.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Hi all,
>>>>>>>
>>>>>>> We are using cxf with Spring at work, and I have a newbie question...
>>>>>>>
>>>>>>> This is my method signature:
>>>>>>>
>>>>>>> @GET
>>>>>>> @Path("foo")
>>>>>>> public Response foo(@MatrixParam("l") List<String> myList) {
>>>>>>>
>>>>>>> From that, I want to get a list back with the initial input String
>>>>>>> (to
>>>>>>> my matrix parameter l) being split into list elements at any comma,
>>>>>>> i.e. I want e.g. ";l=a,b,c" to turn into a list of three elements: a,
>>>>>>> b and c.
>>>>>>>
>>>>>>> My converter below is registered (a breakpoint in it is triggered for
>>>>>>> myList), but instead of passing rawType as List, I get rawType as
>>>>>>> String (so it doesn’t do anything).
>>>>>>>
>>>>>>> public class StringListHandler implements ParamConverterProvider {
>>>>>>>     @Override
>>>>>>>     public <T> ParamConverter<T> getConverter(final Class<T> rawType,
>>>>>>> Type genericType, Annotation[] annotations) {
>>>>>>>         if(rawType == List.class) {
>>>>>>>             return new ParamConverter<T>() {
>>>>>>>                 @Override
>>>>>>>                 public T fromString(String value) {
>>>>>>>                     return
>>>>>>> rawType.cast(Arrays.asList(value.split("\\s*,\\s*")));
>>>>>>>                 }
>>>>>>>
>>>>>>>                 @Override
>>>>>>>                 public String toString(T value) {
>>>>>>>                     return value.toString();
>>>>>>>                 }
>>>>>>>             };
>>>>>>>         }
>>>>>>>         return null;
>>>>>>>     }
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Interestingly enough, I do get a list back. But instead of three
>>>>>>> elements a, b and c, it only seems to have one: a,b,c
>>>>>>>
>>>>>>> What piece of JAX-RS/cxf voodoo am I missing to make this work? ;-)
>>>>>>>
>>>>>>> Is it maybe because cxf comes with a default implementation for a
>>>>>>> List<String> converter so it can turn a URL like foo?l=a&l=b&l=c into
>>>>>>> a List<String> ? Does that also get called for foo;l=a;l=b;l=c ? (I
>>>>>>> thought that c would overwrite a in that situation?)
>>>>>>>
>>>>>>> Do I have to use a custom class with a List<String> property, like
>>>>>>> class MyContainer {
>>>>>>>   public List<List> l;
>>>>>>> }
>>>>>>>
>>>>>>> and change the method signature from above to
>>>>>>> public Response foo(@MatrixParam("l") MyContainer myContainer) {
>>>>>>>
>>>>>>> then check for MyContainer.class in ParamConverterProvider and change
>>>>>>> the fromString() method to
>>>>>>> public T fromString(String value) {
>>>>>>>   MyContainer mC = new MyContainer();
>>>>>>>   mc.l = Arrays.asList(value.split("\\s*,\\s*"));
>>>>>>>   return rawType.cast(mc);
>>>>>>> }
>>>>>>>
>>>>>>> Or should I create a custom argument annotation, say @CommaSeparated,
>>>>>>> and have ParamConverterProvider check for that (and
>>>>>>> rawType==String.class)?
>>>>>>> But if I do that, won't I get a List<List<String>> back?
>>>>>>>
>>>>>>> Any help much appreciated!
>>>>>>>
>>>>>>> Kind regards,
>>>>>>>
>>>>>>> Christian
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Sergey Beryozkin
>>>>>
>>>>> Talend Community Coders
>>>>> http://coders.talend.com/
>>>
>>>
>>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/

Reply via email to