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/