通过GWT RPC传递类对象时出现问题

通过GWT RPC传递类对象时出现问题,第1张

通过GWT RPC传递类对象时出现问题

经过反复尝试,我设法找到了一种方法。这可能不是最好的方法,但它可以工作。希望这篇文章可以节省别人很多时间和精力。

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

创建股票类的客户端实现

关于GWT,需要牢记以下几点:

  1. 服务器端类可以导入客户端类,但反之亦然(通常)。
  2. 客户端无法导入任何Google App
  3. 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<Long> async);  public void removeStock(String symbol, AsyncCallback<Void> async);  public void getStocks(AsyncCallback<StockClient[]> 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<String[]>() {        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 pre 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<Long>() {        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.javaimport 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<StockClient> stockclients = new ArrayList<StockClient>();  try {    Query q = pm.newQuery(Stock.class, "user == u");    q.declareParameters("com.google.appengine.api.users.User u");    q.setOrdering("createDate");    List<Stock> stocks = (List<Stock>) 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 callcom.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中工作的事实似乎表明托管模式下存在错误。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5429210.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存