当前位置:  开发笔记 > 编程语言 > 正文

通过GWT RPC传递类对象的问题

如何解决《通过GWTRPC传递类对象的问题》经验,为你挑选了1个好方法。

我已经通过谷歌网页工具包运行的StockWatcher教程使用的Eclipse和谷歌插件,和我试图做给它一些基本的变化,使我能够更好地了解RPC框架.

我已经在StockServiceImpl服务器端类上修改了"getStocks"方法,以便它返回Stock对象的数组而不是String对象.应用程序编译完美,但Google Web Toolkit返回以下错误:

"没有源代码可用于com.google.gwt.sample.stockwatcher.server.Stock类型;您是否忘记继承所需的模块?"

Google Web Toolkit托管模式http://i44.tinypic.com/a47r83.jpg

似乎客户端类无法找到Stock对象的实现,即使已导入该类.作为参考,这是我的包层次结构的屏幕截图:

Eclipse包层次结构http://i43.tinypic.com/14tr5gk.jpg

我怀疑我在web.xml中遗漏了一些内容,但我不知道它是什么.谁能指出我正确的方向?

编辑:忘了提到Stock类是可持久的,所以它需要留在服务器端.



1> Templar..:

经过多次试验和错误,我设法找到了一种方法来做到这一点.它可能不是最好的方式,但它有效.希望这篇文章可以为其他人节省大量的时间和精力.

这些说明假定您已完成基本StockWatcher教程和Google App Engine StockWatcher修改.

创建Stock类的客户端实现

关于GWT有几点要记住:

    服务器端类可以导入客户端类,但反之亦然(通常).

    客户端无法导入任何Google App Engine库(即com.google.appengine.api.users.User)

由于上述两个项目,客户端永远不能实现我们在com.google.gwt.sample.stockwatcher.server中创建的Stock类.相反,我们将创建一个名为StockClient的新客户端Stock类.

StockClient.java:

package com.google.gwt.sample.stockwatcher.client;

import java.io.Serializable;
import java.util.Date;

public class StockClient implements Serializable {

  private Long id;
  private String symbol;
  private Date createDate;

  public StockClient() {
    this.createDate = new Date();
  }

  public StockClient(String symbol) {
    this.symbol = symbol;
    this.createDate = new Date();
  }

  public StockClient(Long id, String symbol, Date createDate) {
    this();
    this.id = id;
    this.symbol = symbol;
    this.createDate = createDate;
  }

  public Long getId() {
      return this.id;
  }

  public String getSymbol() {
      return this.symbol;
  }

  public Date getCreateDate() {
      return this.createDate;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public void setSymbol(String symbol) {
      this.symbol = symbol;
  }
}

修改客户端类以使用StockClient []而不是String []

现在我们对客户端类进行一些简单的修改,以便他们知道RPC调用返回StockClient []而不是String [].

StockService.java:

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.sample.stockwatcher.client.NotLoggedInException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("stock")
public interface StockService extends RemoteService {
  public Long addStock(String symbol) throws NotLoggedInException;
  public void removeStock(String symbol) throws NotLoggedInException;
  public StockClient[] getStocks() throws NotLoggedInException;
}

StockServiceAsync.java:

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.sample.stockwatcher.client.StockClient;
import com.google.gwt.user.client.rpc.AsyncCallback;

public interface StockServiceAsync {
  public void addStock(String symbol, AsyncCallback async);
  public void removeStock(String symbol, AsyncCallback async);
  public void getStocks(AsyncCallback async);
}

StockWatcher.java:

添加一个导入:

import com.google.gwt.sample.stockwatcher.client.StockClient;

除了addStock,loadStocks和displayStocks之外,所有其他代码保持不变:

private void loadStocks() {
    stockService = GWT.create(StockService.class);
    stockService.getStocks(new AsyncCallback() {
        public void onFailure(Throwable error) {
            handleError(error);
        }

        public void onSuccess(String[] symbols) {
            displayStocks(symbols);
        }
    });
}

private void displayStocks(String[] symbols) {
    for (String symbol : symbols) {
        displayStock(symbol);
    }
}

private void addStock() {
    final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
    newSymbolTextBox.setFocus(true);

    // Stock code must be between 1 and 10 chars that are numbers, letters,
    // or dots.
    if (!symbol.matches("^[0-9a-zA-Z\\.]{1,10}$")) {
        Window.alert("'" + symbol + "' is not a valid symbol.");
        newSymbolTextBox.selectAll();
        return;
    }

    newSymbolTextBox.setText("");

    // Don't add the stock if it's already in the table.
    if (stocks.contains(symbol))
        return;

    addStock(new StockClient(symbol));
}

private void addStock(final StockClient stock) {
    stockService.addStock(stock.getSymbol(), new AsyncCallback() {
        public void onFailure(Throwable error) {
            handleError(error);
        }

        public void onSuccess(Long id) {
            stock.setId(id);
            displayStock(stock.getSymbol());
        }
    });
}

修改StockServiceImpl类以返回StockClient []

最后,我们修改StockServiceImpl类的getStocks方法,以便在返回数组之前将服务器端Stock类转换为客户端StockClient类.

StockServiceImpl.java

import com.google.gwt.sample.stockwatcher.client.StockClient;

我们需要稍微更改addStock方法,以便返回生成的ID:

public Long addStock(String symbol) throws NotLoggedInException {
  Stock stock = new Stock(getUser(), symbol);
  checkLoggedIn();
  PersistenceManager pm = getPersistenceManager();
  try {
    pm.makePersistent(stock);
  } finally {
    pm.close();
  }
  return stock.getId();
}

除getStocks外,所有其他方法保持不变:

public StockClient[] getStocks() throws NotLoggedInException {
  checkLoggedIn();
  PersistenceManager pm = getPersistenceManager();
  List stockclients = new ArrayList();
  try {
    Query q = pm.newQuery(Stock.class, "user == u");
    q.declareParameters("com.google.appengine.api.users.User u");
    q.setOrdering("createDate");
    List stocks = (List) q.execute(getUser());
    for (Stock stock : stocks)
    {
       stockclients.add(new StockClient(stock.getId(), stock.getSymbol(), stock.getCreateDate()));
    }
  } finally {
    pm.close();
  }
  return (StockClient[]) stockclients.toArray(new StockClient[0]);
}

摘要

上面的代码在部署到Google App Engine时非常适合我,但在Google Web Toolkit托管模式下触发错误:

SEVERE: [1244408678890000] javax.servlet.ServletContext log: Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract com.google.gwt.sample.stockwatcher.client.StockClient[] com.google.gwt.sample.stockwatcher.client.StockService.getStocks() throws com.google.gwt.sample.stockwatcher.client.NotLoggedInException' threw an unexpected exception: java.lang.NullPointerException: Name is null

如果您遇到同样的问题,请告诉我.它在Google App Engine中运行的事实似乎表明托管模式中存在错误.


这是DTO方法.我不喜欢这种模式,因为它迫使开发人员为一个实体保留两个类.但遗憾的是,似乎更容易使持久性对象与GWT一起工作......
推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有