I've come up to a strange routing problem in restlet. I'm using android.

This class extends Router

This is my routing code:

    this.attach("/contacts", contactListRestlet); // To list all contacts
    this.attach("/contacts/{uid}", contactRestlet); // To show details about a specific contact
    this.attach("/contacts/similar", similarRestlet, Template.MODE_EQUALS);
    this.attach("/contact/photo/{uid}", photoRestlet); // {uid} must correspond to a valid raw contact id
    this.attach("/contact/photo/{uid}/thumbnail", photoThumbnailRestlet);
    this.attach("/import/file", fileImportRestlet);
    this.attach("/echo", echoRestlet);
    this.attach("/echo/file", echoFileRestlet);
    this.attach("/import/vcard", importVcard);
    this.attach("/logout", logoutRestlet);

    final String ROOT_URI = "file:///android_asset";
    Application application = new Application() {  
        @Override  
        public Restlet createInboundRoot() {
            //ForAssets
            DirectoryForAssets d = new DirectoryForAssets(getContext(), ROOT_URI);
            d.setTargetClass(DirectoryResourceExtension.class);
            d.setAndroidContext(context);
            return d;  
        }  
    };
    this.attach("/editor", application, Template.MODE_STARTS_WITH);

this way if I hit ip:port/contacts/similar I always get redirected to /contacts restlet (contactRestlet) and not to /contacts/similar restlet (similarRestlet) as I was expecting.

But if I change it to:

    this.attach("/contacts/similar", similarRestlet);
    this.attach("/contacts", contactListRestlet); // To list all contacts
    this.attach("/contacts/{uid}", contactRestlet); // To show details about a specific contact
    this.attach("/contact/photo/{uid}", photoRestlet); // {uid} must correspond to a valid raw contact id
    this.attach("/contact/photo/{uid}/thumbnail", photoThumbnailRestlet);
    this.attach("/import/file", fileImportRestlet);
    this.attach("/echo", echoRestlet);
    this.attach("/echo/file", echoFileRestlet);
    this.attach("/import/vcard", importVcard);
    this.attach("/logout", logoutRestlet);

    final String ROOT_URI = "file:///android_asset";
    Application application = new Application() {  
        @Override  
        public Restlet createInboundRoot() {
            //ForAssets
            DirectoryForAssets d = new DirectoryForAssets(getContext(), ROOT_URI);
            d.setTargetClass(DirectoryResourceExtension.class);
            d.setAndroidContext(context);
            return d;  
        }  
    };
    this.attach("/editor", application, Template.MODE_STARTS_WITH);

it does work! (The only difference is similarRestlet comes first than contactRestlet).

Can anyone explain me why this behaviour? What am I doing wrong?

有帮助吗?

解决方案

By default the Router matches the first available match, other matching modes including best match exist. This can be adjusted by changing setDefaultMatchingMode(int) See restlet JavaDoc for additional information. Currently at http://restlet.com/technical-resources/restlet-framework/javadocs/2.3/jse/api/org/restlet/routing/Router.html

其他提示

"/contacts/{uid}"
"/contacts/similar"

If you have this above sequence, it will use the {uid} and fill in "similar" this is because it cannot distinguish the both, and uses "similar" as a "uid".

So when you put it like this:

"/contacts/similar"
"/contacts/{uid}"

It first catches "similar", and if it is not "similar", it will use that part as a uid.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top