Sunday, October 19, 2014

Getting Crazy with Restlet: Method Not Allowed (405)

Are you getting crazy with Restlet in your recent project?


You have a Java SE project and you decided to give it a shoot at Restlet? Well that a nice choice besides some defects in their current documentation. But if you found yourself facing errors with "Method Not Allowed" here goes some solutions that worked for me.

  1. Include this function on your Application class:

       private static Form configureRestForm(Response response) {
            Form responseHeaders = (Form) response.getAttributes().get("org.restlet.http.headers");
    
            if (responseHeaders == null) {
                responseHeaders = new Form();
                response.getAttributes().put("org.restlet.http.headers", responseHeaders);
            }
    
            responseHeaders.add("Access-Control-Allow-Origin", "*");
            responseHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS");
            responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
            responseHeaders.add("Access-Control-Allow-Credentials", "false");
            responseHeaders.add("Access-Control-Max-Age", "60");
    
            return responseHeaders;
        }
    


    Then on your ServerResource class on the first line call it like this configureRestForm(getResponse()).

  2. Secondly and most important, if you are using Restlet current version (2.2), do not be creative like I did trying to use Java 1.8, if you do so, this is what going to happen:

    1. For Stand Alone Servers, it will work just fine;

    2. For Servers using a Component with your Application Class, that contain the createInboundRoute method overridden, your ServerResources will not be accessible.

      This happens because there is some kind of incompatibility between the way Restlet gets your annotated methods (@Get, @Post, @Put, ...) and Java 1.8.

      And so, if you debug Restlet code you will be able to see that on the class ServerResource on the get() method, Restlet is not capable of detecting your annotated methods!

      So, just switch to Java 1.7 and everything will automagically work!
      By the way I found this when stopping for a break after some hours trying to figure out the problem, and then it hit me, annotations must be related with the Java version... I hope Restlet fixes this in future, but for now, I'll have to stick with Java 1.7.

Hope this helped you figuring out a solution.

Alternatively you can look at my code here on bitbucket (look for rest package).