« Return to Thread: Problem with matrix params, works with one, but not with two (or more) params

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

by Sergey Beryozkin-2 :: Rate this Message:

Reply to Author | View in Thread

Hi Gabriel

I've done few more URITemplate unit tests and it's working fine so it appears that the fault is elsewhere, perhaps at the
CXFServlet/ServletController layer.

In the case when it's not working I can see that the URI value is

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

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

@Path("/widgets")
public class Widgets {
    @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;
}

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

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

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

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

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@...>
>> To: <users@...>
>> 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.
>

 « Return to Thread: Problem with matrix params, works with one, but not with two (or more) params