You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Gabriel Guardincerri <gg...@gmail.com> on 2009/07/13 19:18:03 UTC

Re: Problem with matrix params, works with one, but not with two (or more) params

On Mon, Jul 13, 2009 at 5:54 AM, Sergey Beryozkin <sb...@progress.com>wrote:

>
>
> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>
> so "/__services/bridging/widgets/" is an extra bit which was not available
> at the URITemplate creation time and it would explain why the match is
> failing.
>


Nice catch!


>
> Can you please post a sample root resource class, as well as the value of
> jaxrs:server/@address.
> Is it something like this :
>


More or less, we don't have a class path, just

public class Widgets {

    @GET

 @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
    WSWidget renderWidget2(@PathParam("widgetID") Long widgetID,
            @PathParam("widgetType") Integer widgetType,
            @PathParam("size") Long containerSize,
            @PathParam("locale") String locale,
            @PathParam("properties") PathSegment props)
            throws RemoteBridgeException;

}



>
> and jaxrs:server/@adress="/bridging"
>

it is /bridging/widgets


>
> and CXFServlet url pattern is "/__services/*"  ?
>

yes that's the pattern


> Or is it jaxrs:server/@adress="__services/bridging" and CXFServlet url
> pattern = "/*" ?
>
> What are absolute working/broken URIs (lets assume 'webAppName' is the name
> of the web application, and localhost:8080), is it something like :
>
> working :
> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
> broken :
> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>


We are testing without webAppName just

http://localhost:8080/__services/...

And both absolute URIs have the same beginning.


>
> By the way is it a double underscore in '__services' ?
>

I just a way to be sure that we won't have conflicts with other URIs that
the server may have



> thanks, Sergey
>
>
>> Hi Sergey,
>>
>> I'm sorry again for the delay.
>>
>> Debugging it I couldn't understand why it isn't working. But here is what
>> I
>> found:
>>
>> With the working URL
>>
>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1":
>>
>> 1) At line 144 of URITemplate
>>
>> 143 Matcher m = templateRegexPattern.matcher(uri);
>> 144        if (!m.matches()) {
>> 145            if (uri.contains(";")) {
>>
>> The value of the variables are:
>>
>> uri =
>> /renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>> m =
>>
>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>> region=0,73
>>
>> lastmatch=/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1]
>> template =
>>
>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>> templateRegexPattern =
>>
>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>
>> And m.matches() returns true, so that if is skipped and the method returns
>> true. After that our implementation of the service is called.
>>
>> With the NOT working URL
>>
>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar":
>>
>> At that same line 144, the variable values are:
>>
>> uri =
>>
>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>> m =
>>
>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>> region=0,109 lastmatch=]
>> template =
>>
>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>> templateRegexPattern =
>>
>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>
>> But m.matches() returns false. So we enter in the if. We also enter in the
>> if of line 145 "if (uri.contains(";"))".
>> Then the uri is rebuilded, and at line 162:
>>
>> 160                uri = sb.toString();
>> 161                m = templateRegexPattern.matcher(uri);
>> 162                if (!m.matches()) {
>> 163                    return false;
>>
>> The value of the variables are:
>>
>> uri =
>>
>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>> m =
>>
>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>> region=0,109 lastmatch=]
>>
>> That are the same values that we had at the beginning. So again
>> m.matches()
>> returns false, so we enter to that if on line 162, and the method returns
>> false.
>>
>> I really don't know which is the problem, since as far as I can see both
>> uri
>> should match the pattern. Also I don't know what that first if should do,
>> since we get the same uri.
>>
>> I hope that this help, if you need any other test, please feel free to
>> ping
>> me.
>>
>> Best,
>>
>> Gabriel
>>
>>
>> Sergey Beryozkin-2 wrote:
>>
>>>
>>> I did few more tests today (with/without CXFServlet, with PathSegments)
>>> and I still can't reproduce it so I will give up for a
>>> moment.
>>> But I'm still nervous you managed to hit a problem somehow - can you
>>> please give me a favor and help to get to the bottom of it ?
>>> It should take 30 mins max of your time, download
>>>
>>> http://www.apache.org/dyn/closer.cgi?path=%2Fcxf%2F2.2.2%2Fapache-cxf-2.2.2-src.zip
>>>
>>> and put a breakpoint in URITemplate.match()
>>>
>>> A better news is that after trying to reproduce it,  I added a new method
>>> to WebClient  which can make it simpler for users to deal
>>> with template parameters, such that they can avoid dealing with
>>> UriBuilder
>>> directly.
>>> So you can do
>>> WebClient client = WebClient.create("http://widgets");
>>>
>>> cleint.path("("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
>>>                idValue, widgetTypeValue, 1, "en_US",
>>> "properties;1=2").get(Widget.class)
>>>
>>> cheers, Sergey
>>>
>>>
>>> ----- Original Message ----- From: "Gabriel Guardincerri" <
>>> gguardin@gmail.com>
>>> To: <us...@cxf.apache.org>
>>> Sent: Wednesday, July 01, 2009 10:35 PM
>>> Subject: Problem with matrix params, works with one, but not with two (or
>>> more) params
>>>
>>>
>>>
>>>> Hello,
>>>>
>>>> I'm having a problem where matrix parameters are not recognized past the
>>>> first parameter.  When I have one matrix parameter, the method below is
>>>> invoked and the PathSegment.getMatrixParameters() returns the single
>>>> result.
>>>>
>>>> However, if I append a second matrix parameter (or more), the service
>>>> method is not invoked at all and I receive the following error message:
>>>>
>>>> "No operation matching request".
>>>>
>>>> Service interface:
>>>>
>>>> @GET
>>>>
>>>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>>>   WSWidget renderWidget(@PathParam("widgetID") Long widgetID,
>>>>           @PathParam("widgetType") Integer widgetType,
>>>>           @PathParam("size") Long containerSize,
>>>>           @PathParam("locale") String locale,
>>>>           @PathParam("properties") PathSegment props)
>>>>           throws RemoteBridgeException;
>>>>
>>>> Working
>>>> URL:
>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>>
>>>> Broken:
>>>> URL:
>>>>
>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>
>>>> The reason I'm trying to use matrix parameters is that I have an
>>>> arbitrary map of name/value for a widget class.  I can't try to parse
>>>> them out individually using @MatrixParam, because they vary by widget
>>>> class and are not known at the service level.
>>>>
>>>> Thanks for your help.
>>>> --
>>>> View this message in context:
>>>>
>>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24297533.html
>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>
>>>>
>>>
>>>
>>>
>> --
>> View this message in context:
>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24413449.html
>> Sent from the cxf-user mailing list archive at Nabble.com.
>>
>>
>

Re: Problem with matrix params, works with one, but not with two (or more) params

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Gabriel

This is really helpful - thanks for spending your time on it.

So let me clarify one thing. In the case when it does not work, when we have queries like

http://localhost:8080/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar

you said that 'pathInfo' was equal to

"__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1"

?

The thing that the only place in that function where pathInfo gets initialized is here :

>        String pathInfo = request.getPathInfo() == null ? "" :

So it appears it is HttpServletRequest drops the the last matrix parameter ?

can you confirm it please ?

thanks, Sergey

> Hi Sergey,
> Sorry, I've just seen this post.
>
> I did that change, that as far as I can see is just to add "@Path("/")" to
> the class, but it didn't work. Anyway the problem seems to be here:
>
>    private String getBaseURL(HttpServletRequest request) {
>        String reqPrefix = request.getRequestURL().toString();
>        String pathInfo = request.getPathInfo() == null ? "" :
> request.getPathInfo();
>        //fix for CXF-898
>        if (!"/".equals(pathInfo) || reqPrefix.endsWith("/")) {
>            // needs to be done given that pathInfo is decoded
>            // TODO : it's unlikely servlet path will contain encoded values
> so we're most
>            // likely safe however we need to ensure if it happens then this
> code works properly too
>            reqPrefix = UrlUtils.pathDecode(reqPrefix);
>            // pathInfo drops matrix parameters attached to a last path
> segment
>            int offset = 0;
>            int index = getMatrixParameterIndex(reqPrefix,
> pathInfo.length());
>            if (index >= pathInfo.length()) {
>                offset = reqPrefix.length() - index;
>            }
>            reqPrefix = reqPrefix.substring(0, reqPrefix.length() -
> pathInfo.length() - offset); // MARK 1
>        }
>        return reqPrefix;
>    }
>
>    private int getMatrixParameterIndex(String reqPrefix, int
> pathInfoLength) {
>        int index = reqPrefix.lastIndexOf(';');
>        int lastIndex = -1;
>        while (index >= pathInfoLength) {
>            lastIndex = index;
>            reqPrefix = reqPrefix.substring(0, index);
>            index = reqPrefix.lastIndexOf(';');
>        }
>        return lastIndex;
>    }
>
> At "// MARK 1" the values are
>
> reqPrefix =
> http://localhost:8080/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar
> pathInfo
> = /bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1
> offset = 21
> index = 101
>
> And the result of executing that line is:
>
> reqPrefix = http://localhost:80
>
> So there's the problem.
>
> On the other breakpoint
>
> rawPath
> = /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar
>
> And when I entered into "HttpUtils.getPathToMatch(message, true)" I get to:
>
>    public static String getPathToMatch(String path, String address, boolean
> addSlash) {
>
>        int ind = path.indexOf(address);
>        if (ind == 0) {
>            path = path.substring(ind + address.length());
>        }
>        if (addSlash && !path.startsWith("/")) {
>            path = "/" + path;
>        }
>
>        return path;
>    }
>
> The value of "ind" is != 0, so it doesn't enter into the first if and the
> result is:
>
> path
> = /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar
>
> With one param the at the first breakpoint I get this
>
> reqPrefix = http://localhost:8080/__services
> pathInfo
> = /bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties
>
> And at the second one:
>
> It enters into the if since "ind == 0" and
>
> rawPath = /renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1
>
> Hope this helps,
>
> Best,
>
> Gabriel
>
> On Tue, Jul 14, 2009 at 10:27 AM, Sergey Beryozkin <sb...@progress.com>wrote:
>
>> Hi Gabriel
>>
>> I'd like to ask you for one more favor and do a bit more debugging.
>>
>> here's what I did.
>>
>> Service class :
>>
>> @Path("/")
>>
>> public class WidgetsService {
>>
>>
>> @GET
>>
>>
>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>
>> public int getWidgetId(@PathParam("widgetID") Long widgetID,
>>
>> @PathParam("widgetType") Integer widgetType,
>>
>> @PathParam("size") Long containerSize,
>>
>> @PathParam("locale") String locale,
>>
>> @PathParam("properties") PathSegment props) {
>>
>> return 1;
>>
>> }
>>
>>
>>
>> }
>>
>>
>> Client code :
>>
>> @Test
>>
>> public void testgetWidgetIdWithTwoMatrixParam() {
>>
>> WebClient wc = WebClient.create("
>> http://localhost:9081/__services/bridging/widgets");
>>
>> wc.accept("text/plain");
>>
>>
>> wc.path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
>>
>> 1, 2, 3, "en_US", "props").matrix("a", "b").matrix("c", "d");
>>
>> int status = wc.get(Integer.class);
>>
>> assertEquals(1, status);
>>
>> }
>>
>> cxfservlet : /__services/*
>>
>> jaxrs:server/@address= "/bridging/widgets"
>>
>> It all works nicely, request URI looks like this :
>>
>> GET
>> /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/en_US/props;a=b;c=d
>>
>> Would it be possible for you, whenever you get a chnace, to put 2
>> breakpoints, one in
>>
>> org.apache.cxf.transport.servlet.ServletController.getBaseURL();
>>
>> and another one in
>>
>> JAXRSInInterceptor, on the line which reads
>>
>> String rawPath = HttpUtils.getPathToMatch(message, true);
>>
>> and let me know at what point of time '/__services/bridging/widgets/' gets
>> in the way...Hopefully we can get to the botom of it :-)
>>
>> thanks, Sergey
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> ----- Original Message ----- From: "Gabriel Guardincerri" <
>> gguardin@gmail.com>
>> To: <us...@cxf.apache.org>
>> Sent: Monday, July 13, 2009 6:18 PM
>> Subject: Re: Problem with matrix params, works with one, but not with two
>> (or more) params
>>
>>
>>
>>  On Mon, Jul 13, 2009 at 5:54 AM, Sergey Beryozkin <sberyozk@progress.com
>>> >wrote:
>>>
>>>
>>>>
>>>>
>>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>
>>>> so "/__services/bridging/widgets/" is an extra bit which was not
>>>> available
>>>> at the URITemplate creation time and it would explain why the match is
>>>> failing.
>>>>
>>>>
>>>
>>> Nice catch!
>>>
>>>
>>>
>>>> Can you please post a sample root resource class, as well as the value of
>>>> jaxrs:server/@address.
>>>> Is it something like this :
>>>>
>>>>
>>>
>>> More or less, we don't have a class path, just
>>>
>>> public class Widgets {
>>>
>>>   @GET
>>>
>>>
>>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>>   WSWidget renderWidget2(@PathParam("widgetID") Long widgetID,
>>>           @PathParam("widgetType") Integer widgetType,
>>>           @PathParam("size") Long containerSize,
>>>           @PathParam("locale") String locale,
>>>           @PathParam("properties") PathSegment props)
>>>           throws RemoteBridgeException;
>>>
>>> }
>>>
>>>
>>>
>>>
>>>> and jaxrs:server/@adress="/bridging"
>>>>
>>>>
>>> it is /bridging/widgets
>>>
>>>
>>>
>>>> and CXFServlet url pattern is "/__services/*"  ?
>>>>
>>>>
>>> yes that's the pattern
>>>
>>>
>>>  Or is it jaxrs:server/@adress="__services/bridging" and CXFServlet url
>>>> pattern = "/*" ?
>>>>
>>>> What are absolute working/broken URIs (lets assume 'webAppName' is the
>>>> name
>>>> of the web application, and localhost:8080), is it something like :
>>>>
>>>> working :
>>>>
>>>> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>> broken :
>>>>
>>>> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>
>>>>
>>>
>>> We are testing without webAppName just
>>>
>>> http://localhost:8080/__services/...
>>>
>>> And both absolute URIs have the same beginning.
>>>
>>>
>>>
>>>> By the way is it a double underscore in '__services' ?
>>>>
>>>>
>>> I just a way to be sure that we won't have conflicts with other URIs that
>>> the server may have
>>>
>>>
>>>
>>>  thanks, Sergey
>>>>
>>>>
>>>>  Hi Sergey,
>>>>>
>>>>> I'm sorry again for the delay.
>>>>>
>>>>> Debugging it I couldn't understand why it isn't working. But here is
>>>>> what
>>>>> I
>>>>> found:
>>>>>
>>>>> With the working URL
>>>>>
>>>>>
>>>>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1":
>>>>>
>>>>> 1) At line 144 of URITemplate
>>>>>
>>>>> 143 Matcher m = templateRegexPattern.matcher(uri);
>>>>> 144        if (!m.matches()) {
>>>>> 145            if (uri.contains(";")) {
>>>>>
>>>>> The value of the variables are:
>>>>>
>>>>> uri =
>>>>>
>>>>> /renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>>> m =
>>>>>
>>>>>
>>>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>> region=0,73
>>>>>
>>>>>
>>>>> lastmatch=/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1]
>>>>> template =
>>>>>
>>>>>
>>>>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>>>>> templateRegexPattern =
>>>>>
>>>>>
>>>>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>>
>>>>> And m.matches() returns true, so that if is skipped and the method
>>>>> returns
>>>>> true. After that our implementation of the service is called.
>>>>>
>>>>> With the NOT working URL
>>>>>
>>>>>
>>>>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar":
>>>>>
>>>>> At that same line 144, the variable values are:
>>>>>
>>>>> uri =
>>>>>
>>>>>
>>>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>> m =
>>>>>
>>>>>
>>>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>> region=0,109 lastmatch=]
>>>>> template =
>>>>>
>>>>>
>>>>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>>>>> templateRegexPattern =
>>>>>
>>>>>
>>>>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>>
>>>>> But m.matches() returns false. So we enter in the if. We also enter in
>>>>> the
>>>>> if of line 145 "if (uri.contains(";"))".
>>>>> Then the uri is rebuilded, and at line 162:
>>>>>
>>>>> 160                uri = sb.toString();
>>>>> 161                m = templateRegexPattern.matcher(uri);
>>>>> 162                if (!m.matches()) {
>>>>> 163                    return false;
>>>>>
>>>>> The value of the variables are:
>>>>>
>>>>> uri =
>>>>>
>>>>>
>>>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>> m =
>>>>>
>>>>>
>>>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>> region=0,109 lastmatch=]
>>>>>
>>>>> That are the same values that we had at the beginning. So again
>>>>> m.matches()
>>>>> returns false, so we enter to that if on line 162, and the method
>>>>> returns
>>>>> false.
>>>>>
>>>>> I really don't know which is the problem, since as far as I can see both
>>>>> uri
>>>>> should match the pattern. Also I don't know what that first if should
>>>>> do,
>>>>> since we get the same uri.
>>>>>
>>>>> I hope that this help, if you need any other test, please feel free to
>>>>> ping
>>>>> me.
>>>>>
>>>>> Best,
>>>>>
>>>>> Gabriel
>>>>>
>>>>>
>>>>> Sergey Beryozkin-2 wrote:
>>>>>
>>>>>
>>>>>> I did few more tests today (with/without CXFServlet, with PathSegments)
>>>>>> and I still can't reproduce it so I will give up for a
>>>>>> moment.
>>>>>> But I'm still nervous you managed to hit a problem somehow - can you
>>>>>> please give me a favor and help to get to the bottom of it ?
>>>>>> It should take 30 mins max of your time, download
>>>>>>
>>>>>>
>>>>>> http://www.apache.org/dyn/closer.cgi?path=%2Fcxf%2F2.2.2%2Fapache-cxf-2.2.2-src.zip
>>>>>>
>>>>>> and put a breakpoint in URITemplate.match()
>>>>>>
>>>>>> A better news is that after trying to reproduce it,  I added a new
>>>>>> method
>>>>>> to WebClient  which can make it simpler for users to deal
>>>>>> with template parameters, such that they can avoid dealing with
>>>>>> UriBuilder
>>>>>> directly.
>>>>>> So you can do
>>>>>> WebClient client = WebClient.create("http://widgets");
>>>>>>
>>>>>>
>>>>>> cleint.path("("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
>>>>>>               idValue, widgetTypeValue, 1, "en_US",
>>>>>> "properties;1=2").get(Widget.class)
>>>>>>
>>>>>> cheers, Sergey
>>>>>>
>>>>>>
>>>>>> ----- Original Message ----- From: "Gabriel Guardincerri" <
>>>>>> gguardin@gmail.com>
>>>>>> To: <us...@cxf.apache.org>
>>>>>> Sent: Wednesday, July 01, 2009 10:35 PM
>>>>>> Subject: Problem with matrix params, works with one, but not with two
>>>>>> (or
>>>>>> more) params
>>>>>>
>>>>>>
>>>>>>
>>>>>>  Hello,
>>>>>>>
>>>>>>> I'm having a problem where matrix parameters are not recognized past
>>>>>>> the
>>>>>>> first parameter.  When I have one matrix parameter, the method below
>>>>>>> is
>>>>>>> invoked and the PathSegment.getMatrixParameters() returns the single
>>>>>>> result.
>>>>>>>
>>>>>>> However, if I append a second matrix parameter (or more), the service
>>>>>>> method is not invoked at all and I receive the following error
>>>>>>> message:
>>>>>>>
>>>>>>> "No operation matching request".
>>>>>>>
>>>>>>> Service interface:
>>>>>>>
>>>>>>> @GET
>>>>>>>
>>>>>>>
>>>>>>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>>>>>>  WSWidget renderWidget(@PathParam("widgetID") Long widgetID,
>>>>>>>          @PathParam("widgetType") Integer widgetType,
>>>>>>>          @PathParam("size") Long containerSize,
>>>>>>>          @PathParam("locale") String locale,
>>>>>>>          @PathParam("properties") PathSegment props)
>>>>>>>          throws RemoteBridgeException;
>>>>>>>
>>>>>>> Working
>>>>>>> URL:
>>>>>>>
>>>>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>>>>>
>>>>>>> Broken:
>>>>>>> URL:
>>>>>>>
>>>>>>>
>>>>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>>>>
>>>>>>> The reason I'm trying to use matrix parameters is that I have an
>>>>>>> arbitrary map of name/value for a widget class.  I can't try to parse
>>>>>>> them out individually using @MatrixParam, because they vary by widget
>>>>>>> class and are not known at the service level.
>>>>>>>
>>>>>>> Thanks for your help.
>>>>>>> --
>>>>>>> View this message in context:
>>>>>>>
>>>>>>>
>>>>>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24297533.html
>>>>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>  --
>>>>> View this message in context:
>>>>>
>>>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24413449.html
>>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
> 


Re: Problem with matrix params, works with one, but not with two (or more) params

Posted by Gabriel Guardincerri <gg...@gmail.com>.
Hi Sergey,
Sorry, I've just seen this post.

I did that change, that as far as I can see is just to add "@Path("/")" to
the class, but it didn't work. Anyway the problem seems to be here:

    private String getBaseURL(HttpServletRequest request) {
        String reqPrefix = request.getRequestURL().toString();
        String pathInfo = request.getPathInfo() == null ? "" :
request.getPathInfo();
        //fix for CXF-898
        if (!"/".equals(pathInfo) || reqPrefix.endsWith("/")) {
            // needs to be done given that pathInfo is decoded
            // TODO : it's unlikely servlet path will contain encoded values
so we're most
            // likely safe however we need to ensure if it happens then this
code works properly too
            reqPrefix = UrlUtils.pathDecode(reqPrefix);
            // pathInfo drops matrix parameters attached to a last path
segment
            int offset = 0;
            int index = getMatrixParameterIndex(reqPrefix,
pathInfo.length());
            if (index >= pathInfo.length()) {
                offset = reqPrefix.length() - index;
            }
            reqPrefix = reqPrefix.substring(0, reqPrefix.length() -
pathInfo.length() - offset); // MARK 1
        }
        return reqPrefix;
    }

    private int getMatrixParameterIndex(String reqPrefix, int
pathInfoLength) {
        int index = reqPrefix.lastIndexOf(';');
        int lastIndex = -1;
        while (index >= pathInfoLength) {
            lastIndex = index;
            reqPrefix = reqPrefix.substring(0, index);
            index = reqPrefix.lastIndexOf(';');
        }
        return lastIndex;
    }

At "// MARK 1" the values are

reqPrefix =
http://localhost:8080/__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar
pathInfo
= /bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1
offset = 21
index = 101

And the result of executing that line is:

reqPrefix = http://localhost:80

So there's the problem.

On the other breakpoint

rawPath
= /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar

And when I entered into "HttpUtils.getPathToMatch(message, true)" I get to:

    public static String getPathToMatch(String path, String address, boolean
addSlash) {

        int ind = path.indexOf(address);
        if (ind == 0) {
            path = path.substring(ind + address.length());
        }
        if (addSlash && !path.startsWith("/")) {
            path = "/" + path;
        }

        return path;
    }

The value of "ind" is != 0, so it doesn't enter into the first if and the
result is:

path
= /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1;foo=bar

With one param the at the first breakpoint I get this

reqPrefix = http://localhost:8080/__services
pathInfo
= /bridging/widgets/renderwidget/id/1/type/2/size/3/locale/4/properties

And at the second one:

It enters into the if since "ind == 0" and

rawPath = /renderwidget/id/1/type/2/size/3/locale/4/properties;numResults=1

Hope this helps,

Best,

Gabriel

On Tue, Jul 14, 2009 at 10:27 AM, Sergey Beryozkin <sb...@progress.com>wrote:

> Hi Gabriel
>
> I'd like to ask you for one more favor and do a bit more debugging.
>
> here's what I did.
>
> Service class :
>
> @Path("/")
>
> public class WidgetsService {
>
>
> @GET
>
>
> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>
> public int getWidgetId(@PathParam("widgetID") Long widgetID,
>
> @PathParam("widgetType") Integer widgetType,
>
> @PathParam("size") Long containerSize,
>
> @PathParam("locale") String locale,
>
> @PathParam("properties") PathSegment props) {
>
> return 1;
>
> }
>
>
>
> }
>
>
> Client code :
>
> @Test
>
> public void testgetWidgetIdWithTwoMatrixParam() {
>
> WebClient wc = WebClient.create("
> http://localhost:9081/__services/bridging/widgets");
>
> wc.accept("text/plain");
>
>
> wc.path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
>
> 1, 2, 3, "en_US", "props").matrix("a", "b").matrix("c", "d");
>
> int status = wc.get(Integer.class);
>
> assertEquals(1, status);
>
> }
>
> cxfservlet : /__services/*
>
> jaxrs:server/@address= "/bridging/widgets"
>
> It all works nicely, request URI looks like this :
>
> GET
> /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/en_US/props;a=b;c=d
>
> Would it be possible for you, whenever you get a chnace, to put 2
> breakpoints, one in
>
> org.apache.cxf.transport.servlet.ServletController.getBaseURL();
>
> and another one in
>
> JAXRSInInterceptor, on the line which reads
>
> String rawPath = HttpUtils.getPathToMatch(message, true);
>
> and let me know at what point of time '/__services/bridging/widgets/' gets
> in the way...Hopefully we can get to the botom of it :-)
>
> thanks, Sergey
>
>
>
>
>
>
>
>
>
>
>
>
> ----- Original Message ----- From: "Gabriel Guardincerri" <
> gguardin@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Monday, July 13, 2009 6:18 PM
> Subject: Re: Problem with matrix params, works with one, but not with two
> (or more) params
>
>
>
>  On Mon, Jul 13, 2009 at 5:54 AM, Sergey Beryozkin <sberyozk@progress.com
>> >wrote:
>>
>>
>>>
>>>
>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>
>>> so "/__services/bridging/widgets/" is an extra bit which was not
>>> available
>>> at the URITemplate creation time and it would explain why the match is
>>> failing.
>>>
>>>
>>
>> Nice catch!
>>
>>
>>
>>> Can you please post a sample root resource class, as well as the value of
>>> jaxrs:server/@address.
>>> Is it something like this :
>>>
>>>
>>
>> More or less, we don't have a class path, just
>>
>> public class Widgets {
>>
>>   @GET
>>
>>
>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>   WSWidget renderWidget2(@PathParam("widgetID") Long widgetID,
>>           @PathParam("widgetType") Integer widgetType,
>>           @PathParam("size") Long containerSize,
>>           @PathParam("locale") String locale,
>>           @PathParam("properties") PathSegment props)
>>           throws RemoteBridgeException;
>>
>> }
>>
>>
>>
>>
>>> and jaxrs:server/@adress="/bridging"
>>>
>>>
>> it is /bridging/widgets
>>
>>
>>
>>> and CXFServlet url pattern is "/__services/*"  ?
>>>
>>>
>> yes that's the pattern
>>
>>
>>  Or is it jaxrs:server/@adress="__services/bridging" and CXFServlet url
>>> pattern = "/*" ?
>>>
>>> What are absolute working/broken URIs (lets assume 'webAppName' is the
>>> name
>>> of the web application, and localhost:8080), is it something like :
>>>
>>> working :
>>>
>>> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>> broken :
>>>
>>> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>
>>>
>>
>> We are testing without webAppName just
>>
>> http://localhost:8080/__services/...
>>
>> And both absolute URIs have the same beginning.
>>
>>
>>
>>> By the way is it a double underscore in '__services' ?
>>>
>>>
>> I just a way to be sure that we won't have conflicts with other URIs that
>> the server may have
>>
>>
>>
>>  thanks, Sergey
>>>
>>>
>>>  Hi Sergey,
>>>>
>>>> I'm sorry again for the delay.
>>>>
>>>> Debugging it I couldn't understand why it isn't working. But here is
>>>> what
>>>> I
>>>> found:
>>>>
>>>> With the working URL
>>>>
>>>>
>>>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1":
>>>>
>>>> 1) At line 144 of URITemplate
>>>>
>>>> 143 Matcher m = templateRegexPattern.matcher(uri);
>>>> 144        if (!m.matches()) {
>>>> 145            if (uri.contains(";")) {
>>>>
>>>> The value of the variables are:
>>>>
>>>> uri =
>>>>
>>>> /renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>> m =
>>>>
>>>>
>>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>> region=0,73
>>>>
>>>>
>>>> lastmatch=/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1]
>>>> template =
>>>>
>>>>
>>>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>>>> templateRegexPattern =
>>>>
>>>>
>>>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>
>>>> And m.matches() returns true, so that if is skipped and the method
>>>> returns
>>>> true. After that our implementation of the service is called.
>>>>
>>>> With the NOT working URL
>>>>
>>>>
>>>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar":
>>>>
>>>> At that same line 144, the variable values are:
>>>>
>>>> uri =
>>>>
>>>>
>>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>> m =
>>>>
>>>>
>>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>> region=0,109 lastmatch=]
>>>> template =
>>>>
>>>>
>>>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>>>> templateRegexPattern =
>>>>
>>>>
>>>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>>
>>>> But m.matches() returns false. So we enter in the if. We also enter in
>>>> the
>>>> if of line 145 "if (uri.contains(";"))".
>>>> Then the uri is rebuilded, and at line 162:
>>>>
>>>> 160                uri = sb.toString();
>>>> 161                m = templateRegexPattern.matcher(uri);
>>>> 162                if (!m.matches()) {
>>>> 163                    return false;
>>>>
>>>> The value of the variables are:
>>>>
>>>> uri =
>>>>
>>>>
>>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>> m =
>>>>
>>>>
>>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>> region=0,109 lastmatch=]
>>>>
>>>> That are the same values that we had at the beginning. So again
>>>> m.matches()
>>>> returns false, so we enter to that if on line 162, and the method
>>>> returns
>>>> false.
>>>>
>>>> I really don't know which is the problem, since as far as I can see both
>>>> uri
>>>> should match the pattern. Also I don't know what that first if should
>>>> do,
>>>> since we get the same uri.
>>>>
>>>> I hope that this help, if you need any other test, please feel free to
>>>> ping
>>>> me.
>>>>
>>>> Best,
>>>>
>>>> Gabriel
>>>>
>>>>
>>>> Sergey Beryozkin-2 wrote:
>>>>
>>>>
>>>>> I did few more tests today (with/without CXFServlet, with PathSegments)
>>>>> and I still can't reproduce it so I will give up for a
>>>>> moment.
>>>>> But I'm still nervous you managed to hit a problem somehow - can you
>>>>> please give me a favor and help to get to the bottom of it ?
>>>>> It should take 30 mins max of your time, download
>>>>>
>>>>>
>>>>> http://www.apache.org/dyn/closer.cgi?path=%2Fcxf%2F2.2.2%2Fapache-cxf-2.2.2-src.zip
>>>>>
>>>>> and put a breakpoint in URITemplate.match()
>>>>>
>>>>> A better news is that after trying to reproduce it,  I added a new
>>>>> method
>>>>> to WebClient  which can make it simpler for users to deal
>>>>> with template parameters, such that they can avoid dealing with
>>>>> UriBuilder
>>>>> directly.
>>>>> So you can do
>>>>> WebClient client = WebClient.create("http://widgets");
>>>>>
>>>>>
>>>>> cleint.path("("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
>>>>>               idValue, widgetTypeValue, 1, "en_US",
>>>>> "properties;1=2").get(Widget.class)
>>>>>
>>>>> cheers, Sergey
>>>>>
>>>>>
>>>>> ----- Original Message ----- From: "Gabriel Guardincerri" <
>>>>> gguardin@gmail.com>
>>>>> To: <us...@cxf.apache.org>
>>>>> Sent: Wednesday, July 01, 2009 10:35 PM
>>>>> Subject: Problem with matrix params, works with one, but not with two
>>>>> (or
>>>>> more) params
>>>>>
>>>>>
>>>>>
>>>>>  Hello,
>>>>>>
>>>>>> I'm having a problem where matrix parameters are not recognized past
>>>>>> the
>>>>>> first parameter.  When I have one matrix parameter, the method below
>>>>>> is
>>>>>> invoked and the PathSegment.getMatrixParameters() returns the single
>>>>>> result.
>>>>>>
>>>>>> However, if I append a second matrix parameter (or more), the service
>>>>>> method is not invoked at all and I receive the following error
>>>>>> message:
>>>>>>
>>>>>> "No operation matching request".
>>>>>>
>>>>>> Service interface:
>>>>>>
>>>>>> @GET
>>>>>>
>>>>>>
>>>>>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>>>>>  WSWidget renderWidget(@PathParam("widgetID") Long widgetID,
>>>>>>          @PathParam("widgetType") Integer widgetType,
>>>>>>          @PathParam("size") Long containerSize,
>>>>>>          @PathParam("locale") String locale,
>>>>>>          @PathParam("properties") PathSegment props)
>>>>>>          throws RemoteBridgeException;
>>>>>>
>>>>>> Working
>>>>>> URL:
>>>>>>
>>>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>>>>
>>>>>> Broken:
>>>>>> URL:
>>>>>>
>>>>>>
>>>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>>>
>>>>>> The reason I'm trying to use matrix parameters is that I have an
>>>>>> arbitrary map of name/value for a widget class.  I can't try to parse
>>>>>> them out individually using @MatrixParam, because they vary by widget
>>>>>> class and are not known at the service level.
>>>>>>
>>>>>> Thanks for your help.
>>>>>> --
>>>>>> View this message in context:
>>>>>>
>>>>>>
>>>>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24297533.html
>>>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>  --
>>>> View this message in context:
>>>>
>>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24413449.html
>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>
>>>>
>>>>
>>>
>>
>

Re: Problem with matrix params, works with one, but not with two (or more) params

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Gabriel

I'd like to ask you for one more favor and do a bit more debugging.

here's what I did.

Service class :

@Path("/")

public class WidgetsService {


@GET

@Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")

public int getWidgetId(@PathParam("widgetID") Long widgetID,

@PathParam("widgetType") Integer widgetType,

@PathParam("size") Long containerSize,

@PathParam("locale") String locale,

@PathParam("properties") PathSegment props) {

return 1;

}



}


Client code :

@Test

public void testgetWidgetIdWithTwoMatrixParam() {

WebClient wc = WebClient.create("http://localhost:9081/__services/bridging/widgets");

wc.accept("text/plain");

wc.path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",

1, 2, 3, "en_US", "props").matrix("a", "b").matrix("c", "d");

int status = wc.get(Integer.class);

assertEquals(1, status);

}

cxfservlet : /__services/*

jaxrs:server/@address= "/bridging/widgets"

It all works nicely, request URI looks like this :

GET /__services/bridging/widgets/renderwidget/id/1/type/2/size/3/locale/en_US/props;a=b;c=d

Would it be possible for you, whenever you get a chnace, to put 2 breakpoints, one in

org.apache.cxf.transport.servlet.ServletController.getBaseURL();

and another one in

JAXRSInInterceptor, on the line which reads

String rawPath = HttpUtils.getPathToMatch(message, true);

and let me know at what point of time '/__services/bridging/widgets/' gets in the way...Hopefully we can get to the botom of it :-)

thanks, Sergey












----- Original Message ----- 
From: "Gabriel Guardincerri" <gg...@gmail.com>
To: <us...@cxf.apache.org>
Sent: Monday, July 13, 2009 6:18 PM
Subject: Re: Problem with matrix params, works with one, but not with two (or more) params


> On Mon, Jul 13, 2009 at 5:54 AM, Sergey Beryozkin <sb...@progress.com>wrote:
>
>>
>>
>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>
>> so "/__services/bridging/widgets/" is an extra bit which was not available
>> at the URITemplate creation time and it would explain why the match is
>> failing.
>>
>
>
> Nice catch!
>
>
>>
>> Can you please post a sample root resource class, as well as the value of
>> jaxrs:server/@address.
>> Is it something like this :
>>
>
>
> More or less, we don't have a class path, just
>
> public class Widgets {
>
>    @GET
>
> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>    WSWidget renderWidget2(@PathParam("widgetID") Long widgetID,
>            @PathParam("widgetType") Integer widgetType,
>            @PathParam("size") Long containerSize,
>            @PathParam("locale") String locale,
>            @PathParam("properties") PathSegment props)
>            throws RemoteBridgeException;
>
> }
>
>
>
>>
>> and jaxrs:server/@adress="/bridging"
>>
>
> it is /bridging/widgets
>
>
>>
>> and CXFServlet url pattern is "/__services/*"  ?
>>
>
> yes that's the pattern
>
>
>> Or is it jaxrs:server/@adress="__services/bridging" and CXFServlet url
>> pattern = "/*" ?
>>
>> What are absolute working/broken URIs (lets assume 'webAppName' is the name
>> of the web application, and localhost:8080), is it something like :
>>
>> working :
>> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>> broken :
>> http://localhost:8080/webAppName/__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>
>
>
> We are testing without webAppName just
>
> http://localhost:8080/__services/...
>
> And both absolute URIs have the same beginning.
>
>
>>
>> By the way is it a double underscore in '__services' ?
>>
>
> I just a way to be sure that we won't have conflicts with other URIs that
> the server may have
>
>
>
>> thanks, Sergey
>>
>>
>>> Hi Sergey,
>>>
>>> I'm sorry again for the delay.
>>>
>>> Debugging it I couldn't understand why it isn't working. But here is what
>>> I
>>> found:
>>>
>>> With the working URL
>>>
>>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1":
>>>
>>> 1) At line 144 of URITemplate
>>>
>>> 143 Matcher m = templateRegexPattern.matcher(uri);
>>> 144        if (!m.matches()) {
>>> 145            if (uri.contains(";")) {
>>>
>>> The value of the variables are:
>>>
>>> uri =
>>> /renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>> m =
>>>
>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>> region=0,73
>>>
>>> lastmatch=/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1]
>>> template =
>>>
>>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>>> templateRegexPattern =
>>>
>>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>
>>> And m.matches() returns true, so that if is skipped and the method returns
>>> true. After that our implementation of the service is called.
>>>
>>> With the NOT working URL
>>>
>>> "renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar":
>>>
>>> At that same line 144, the variable values are:
>>>
>>> uri =
>>>
>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>> m =
>>>
>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>> region=0,109 lastmatch=]
>>> template =
>>>
>>> /renderwidget2/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}
>>> templateRegexPattern =
>>>
>>> /renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>>
>>> But m.matches() returns false. So we enter in the if. We also enter in the
>>> if of line 145 "if (uri.contains(";"))".
>>> Then the uri is rebuilded, and at line 162:
>>>
>>> 160                uri = sb.toString();
>>> 161                m = templateRegexPattern.matcher(uri);
>>> 162                if (!m.matches()) {
>>> 163                    return false;
>>>
>>> The value of the variables are:
>>>
>>> uri =
>>>
>>> /__services/bridging/widgets/renderwidget2/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>> m =
>>>
>>> java.util.regex.Matcher[pattern=/renderwidget2/id/([^/]+?)/type/([^/]+?)/size/([^/]+?)/locale/([^/]+?)/([^/]+?)(/.*)?
>>> region=0,109 lastmatch=]
>>>
>>> That are the same values that we had at the beginning. So again
>>> m.matches()
>>> returns false, so we enter to that if on line 162, and the method returns
>>> false.
>>>
>>> I really don't know which is the problem, since as far as I can see both
>>> uri
>>> should match the pattern. Also I don't know what that first if should do,
>>> since we get the same uri.
>>>
>>> I hope that this help, if you need any other test, please feel free to
>>> ping
>>> me.
>>>
>>> Best,
>>>
>>> Gabriel
>>>
>>>
>>> Sergey Beryozkin-2 wrote:
>>>
>>>>
>>>> I did few more tests today (with/without CXFServlet, with PathSegments)
>>>> and I still can't reproduce it so I will give up for a
>>>> moment.
>>>> But I'm still nervous you managed to hit a problem somehow - can you
>>>> please give me a favor and help to get to the bottom of it ?
>>>> It should take 30 mins max of your time, download
>>>>
>>>> http://www.apache.org/dyn/closer.cgi?path=%2Fcxf%2F2.2.2%2Fapache-cxf-2.2.2-src.zip
>>>>
>>>> and put a breakpoint in URITemplate.match()
>>>>
>>>> A better news is that after trying to reproduce it,  I added a new method
>>>> to WebClient  which can make it simpler for users to deal
>>>> with template parameters, such that they can avoid dealing with
>>>> UriBuilder
>>>> directly.
>>>> So you can do
>>>> WebClient client = WebClient.create("http://widgets");
>>>>
>>>> cleint.path("("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}",
>>>>                idValue, widgetTypeValue, 1, "en_US",
>>>> "properties;1=2").get(Widget.class)
>>>>
>>>> cheers, Sergey
>>>>
>>>>
>>>> ----- Original Message ----- From: "Gabriel Guardincerri" <
>>>> gguardin@gmail.com>
>>>> To: <us...@cxf.apache.org>
>>>> Sent: Wednesday, July 01, 2009 10:35 PM
>>>> Subject: Problem with matrix params, works with one, but not with two (or
>>>> more) params
>>>>
>>>>
>>>>
>>>>> Hello,
>>>>>
>>>>> I'm having a problem where matrix parameters are not recognized past the
>>>>> first parameter.  When I have one matrix parameter, the method below is
>>>>> invoked and the PathSegment.getMatrixParameters() returns the single
>>>>> result.
>>>>>
>>>>> However, if I append a second matrix parameter (or more), the service
>>>>> method is not invoked at all and I receive the following error message:
>>>>>
>>>>> "No operation matching request".
>>>>>
>>>>> Service interface:
>>>>>
>>>>> @GET
>>>>>
>>>>> @Path("/renderwidget/id/{widgetID}/type/{widgetType}/size/{size}/locale/{locale}/{properties}")
>>>>>   WSWidget renderWidget(@PathParam("widgetID") Long widgetID,
>>>>>           @PathParam("widgetType") Integer widgetType,
>>>>>           @PathParam("size") Long containerSize,
>>>>>           @PathParam("locale") String locale,
>>>>>           @PathParam("properties") PathSegment props)
>>>>>           throws RemoteBridgeException;
>>>>>
>>>>> Working
>>>>> URL:
>>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1
>>>>>
>>>>> Broken:
>>>>> URL:
>>>>>
>>>>> /renderwidget/id/1007/type/1/size/1/locale/en_US/properties;numResults=1;foo=bar
>>>>>
>>>>> The reason I'm trying to use matrix parameters is that I have an
>>>>> arbitrary map of name/value for a widget class.  I can't try to parse
>>>>> them out individually using @MatrixParam, because they vary by widget
>>>>> class and are not known at the service level.
>>>>>
>>>>> Thanks for your help.
>>>>> --
>>>>> View this message in context:
>>>>>
>>>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24297533.html
>>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>> --
>>> View this message in context:
>>> http://www.nabble.com/Problem-with-matrix-params%2C-works-with-one%2C-but-not-with-two-%28or-more%29-params-tp24297533p24413449.html
>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>
>>>
>>
>