質問

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