Hi,

OK, Restlet newbie here, probably doing something dumb, but I've been stuck for 
a while now and no amount of googling is helping :-).

Pretty simple situation.  My restlet client is an android app, server is on 
GAE.  Both sides using 2.1M5.  Right now I'm just trying to invoke a test GET 
method, that takes an int parameter and returns an int.  

The symptom is that I'm getting a 500 error thrown from the server side, 
resulting from an IllegalArgumentException thrown inside 
ServerResource.doHandle(AnnotationInfo annotationInfo,Variant variant) when it 
calls  

resultObject = annotationInfo.getJavaMethod().invoke(this, 
parameters.toArray());


Note: earlier in that method, when it loops through the parameter types...

                for (Class<?> parameterType : parameterTypes) {
                    if (Variant.class.equals(parameterType)) {
                        parameters.add(variant);
                    } else {
                        if (getRequestEntity() != null
                                && getRequestEntity().isAvailable()
                                && getRequestEntity().getSize() != 0) {
                            // Assume there is content to be read.
                            // NB: it does not handle the case where the size is
                            // unknown, but there is no content.
                            parameter = toObject(getRequestEntity(),
                                    parameterType);

                            if (parameter == null) {
                                throw new ResourceException(
                                        
Status.CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE);
                            }
                        } else {
                            parameter = null;
                        }

                        parameters.add(parameter);
                    }
                }
... it fails the first "if" test.  getRequestEntity() returns an 
EmptyRepresentation whose media type is [application/x-java-serialized-object], 
but isAvailable() returns false because its "available" member is false, so it 
falls through to the "parameter = null;" statement.

The client side looks like this:

There's a RestletManager class that encapsulates all restlet interactions 
needed by the app.  It has a static init() method that sets things up (called 
by the application class' onCreate() method).  It also has a testGetInt() 
method, which is the one I'm having trouble with.

public class RestletManager {
      private final TestRestlet mTestRestlet = new TestRestlet();

      static public void init() {
            System.setProperty("java.net.preferIPv6Addresses", "false");

            // workaround for restlet bug in 2.1 edition for Android
            Engine.getInstance().getRegisteredClients().clear();
            Engine.getInstance().getRegisteredClients().add(new 
HttpClientHelper(null));

            Engine.getInstance().getRegisteredConverters().add(new 
JacksonConverter());
      }

      public int testGetInt(final int myInt) {
            return mTestRestlet.getInt(myInt);
      }
}

The TestRestlet class encapsulates interactions with the Test resource.

public class TestRestlet {

      private final TestRestletResource mProxy;
      private final Logger mLogger = 
LoggerFactory.getLogger(LoggingManager.TAG);
      private final NewsBotApplication mAppContext;

      TestRestlet() {
            mAppContext = NewsBotApplication.getContext();

            // Initialize the REST resource proxy.
            ClientResource testResource = new ClientResource(
                        mAppContext.getString(R.string.newsbot_server_base_url) 
+
                                    
mAppContext.getString(R.string.test_rest_resource_path));

            // Workaround for GAE servers to prevent chunk encoding for PUT and 
POST requests.
            testResource.setRequestEntityBuffering(true);
            mProxy = testResource.wrap(TestRestletResource.class);
      }

      int getInt(final int myInt) {
            int result = 0;
            try {
                  result = mProxy.getInt(myInt);
            }
            catch (Exception e) {
                  mLogger.error("TestRestlet.getInt: ", e);
            }
            return result;
      }
}

The annotated resource interface looks like this:

import org.restlet.resource.Get;
import org.restlet.resource.Put;

public interface TestRestletResource {
      @Get("json") // do I need the ("json") here? It fails the same way if 
this is present or not.
      public int getInt(int myInt);
}

In a Fragment class, when a menu item is clicked, I do this:

int result = mRestletManager.testGetInt(111);


OK, that's it for the client side.  Over on the server side, I've got an 
application class:

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.resource.Directory;
import org.restlet.routing.Router;

public class RestletServerApplication extends Application {

     @Override
     public Restlet createInboundRoot() {
          Router router = new Router(getContext());
          router.attachDefault(new Directory(getContext(), "war:///"));
          router.attach("/test", TestRestletServerResource.class);
          return router;
     }

}

and a resource class:

import org.restlet.resource.ServerResource;
import com.fizzbuzz.newsbot.model.restlet.TestRestletResource;

public class TestRestletServerResource extends ServerResource implements 
TestRestletResource {

     @Override
     public int getInt(final int myInt) {
          return myInt * 2;
     }
}


Sorry for all the detail, but I figure it might cut down on some 
back-and-forth.  OK, now I must be doing something dumb, but I don't see it.  I 
get the impression that the input parameter is not of the expected format, but 
I'm not sure why that is, since both the client and server side are sharing the 
annotated interface of the test resource.  Can you help?

-AndyD

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2847235

Reply via email to