سؤال

I've tried adding AutoBeans into our GWT app to serialize our objects out to cookies, then read them back.

However, I'm having trouble invoking a GWT RPC method call with the deserialized object after this. Can anyone provide any insight as to why the RPC call is failing?

Demonstration:

public interface Worker {
    public String getTitle();

    public void setTitle(String title);
  }

  public interface WorkerFactory extends AutoBeanFactory {
    AutoBean<Worker> createWorker();
  }

  public class MyObject implements Worker {
    private String title;

    public MyObject() {
    }

    public String getTitle() {
      return title;
    }

    public void setTitle(String title) {
      this.title = title;
    }
  }

Then run with:

  @Test
  public void testMyObject() {
    MyObject obj = new MyObject();
    obj.setTitle("titely");

    WorkerFactory factory = AutoBeanFactorySource.create(WorkerFactory.class);
    AutoBean<Worker> bean = factory.create(Worker.class, obj);
    String json = AutoBeanCodex.encode(bean).getPayload();
    System.out.println("Json is: " + json);

    bean = AutoBeanCodex.decode(factory, Worker.class, json);
    Worker newObject = bean.as();
    System.out.println("Object title is: " + newObject.getTitle());
  }

...which seems to work as expected:

Json is: {"title":"titely"} 
Object title is: titely

But now my RPC method fails, and the caught.getMessage() is null.

Service definitions:

@RemoteServiceRelativePath("workerService")
interface WorkerService {
   public void doWork(Worker worker);
}

public interface WorkerServiceAsync {
  void doWork(Worker worker, AsyncCallback<Void> callback);
}

public class WorkerServiceImpl extends RemoteServiceServlet implements WorkerService {
  @Override
  public void doWork(Worker worker) {
      // Do stuff that never gets called
    }
}

Invoked by:

WorkerServiceAsync WORKER_SERVICE = GWT.create(WorkerService.class);
WORKER_SERVICE.doWork(newObject, new AsyncCallback<Void>() {
      public void onSuccess(Void result) {
        Window.alert("Never get here!");
      }

      public void onFailure(Throwable caught) {
        Window.alert("Get here, but message is blank: " + caught.getMessage());
      }
    });

Additionally, I don't see any requests in the server logs.

Can anyone help? Thanks much

هل كانت مفيدة؟

المحلول

I found out how to make this work.

Instead of declaring the Service to accept types of the interface Worker, I changed it to accept the serialized JSON string as a parameter, then I convert it into the type I need on the server using Jackson.

This makes sense, since the object type returned by the AutoBean deserialization in GWT is simply a declared Worker interface type... the actual object type is some sort of proxy, and that proxy is apparently not itself serializable.

So the solution I'm going with here is to send the serialized JSON string from GWT on the client to the server, where the server does the deserialization to the same Worker class, using this code:

// on the server
public void doWork(String jsonString) {
    ObjectMapper jsonHelper = new ObjectMapper();
    ObjectReader reader = jsonHelper.reader(new TypeReference<MyObject>() {});
    MyObject actualHardObject;
    try {
      actualHardObject = reader.readValue(jsonString);
    } catch (IOException e) {
      log.severe("Couldn't parse json param: " + e.getMessage());
    }

    // do whatever you want with actualHardObject now
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top