检索 ArrayList 时出现 GWT-RPC 无法解释的 500 状态错误

Posted

技术标签:

【中文标题】检索 ArrayList 时出现 GWT-RPC 无法解释的 500 状态错误【英文标题】:GWT-RPC Unexplained 500status error when retrieving an ArrayList 【发布时间】:2013-06-24 08:21:04 【问题描述】:

我正在使用 GWT-RPC 开发一个 GWT 客户端-服务器 webapp;大多数情况下它似乎工作正常,但我在检索 IsSerializable 类型的 ArrayList 时遇到错误。

这是服务器端方法的代码:

    public GWTInvoiceList listInvoices(String enterpriseID, int selection) 
    try
        logger.log("ISI getting a listy of invoices "+selection);
        PlataccsUser pxuser =  (PlataccsUser) getSession().getAttribute(PlataccsConstants.USER);
        Enterprise enterprise= pxuser.getEnterprise(enterpriseID);
        Clerk clerk= pxuser.getClerk(enterprise);
         int i=0;
         List<Invoice> invoices =Invoice.getInvoices(enterprise, clerk, selection);
         GWTInvoiceList gwinvoices = new GWTInvoiceList();
         Iterator<Invoice> it = invoices.iterator();
         while (it.hasNext())
             Invoice invoice = it.next();
             logger.log("ISI-listInvoices converting invoice "+invoice.getSystemInvoiceNumber());
             gwinvoices.add(convert(invoice, clerk));
         
         logger.log("ISI-lI, the invoice list is now ready and it lists "+gwinvoices.size()+" invoices");
        return gwinvoices;
    catch(Exception px)
        logger.log("ISI propblem getting invoice list", px);
        return null;
    

此代码执行时不会引发任何异常。 GWTInvoiceList 返回类型是 ArrayList 的简单包装器,并且已知 GWTInvoice 类型可以在其他调用中成功序列化。客户端代码是:

    public InvoiceList(PlataxTabPanel parent, GWTEnterprise gwtEnterprise, int list_selection_type) 
    super(parent, gwtEnterprise.getName());
     topLabel.setText("List of Invoices");
     subHeader.setText("blah blah");
     invoiceService.listInvoices(gwtEnterprise.getEnterpriseID(), list_selection_type, invoiceListCallBack);

     //table headers:
     table.setWidget(0, 0, new ColumnHeaderLabel(LabelText.LIST_INVOICE_NUMBER_HEADER));
     table.setWidget(0, 1, new ColumnHeaderLabel(LabelText.LIST_INVOICE_CUSTOMER_HEADER));
     table.setWidget(0, 2, new ColumnHeaderLabel(LabelText.LIST_INVOICE_VALUE_DATE_HEADER));
     table.setWidget(0, 3, new ColumnHeaderLabel(LabelText.LIST_INVOICE_DUE_DATE_HEADER));
     table.setWidget(0, 4, new ColumnHeaderLabel(LabelText.LIST_INVOICE_STATUS_HEADER));
     table.setWidget(0, 5, new MoneyColumnHeaderLabel(LabelText.LIST_INVOICE_NET_HEADER));
     table.setWidget(0, 6, new MoneyColumnHeaderLabel(LabelText.LIST_INVOICE_TAX_HEADER));
     table.setWidget(0, 7, new MoneyColumnHeaderLabel(LabelText.LIST_INVOICE_TOTAL_HEADER));




final AsyncCallback<GWTInvoiceList> invoiceListCallBack= new AsyncCallback<GWTInvoiceList>()
    @Override
    public void onSuccess(GWTInvoiceList invoices)
    Iterator<GWTInvoice> gwit = invoices.iterator();
     int row = 1;
     while(gwit.hasNext())
         GWTInvoice gwinvoice = gwit.next();
         table.setWidget(row, 0, new Label(gwinvoice.getUserno()));
         table.setWidget(row, 1, new Label(gwinvoice.getCustomer().getName()));
         table.setWidget(row, 2, new Label(DateTimeFormat.getFormat(DateFormats.SHORT_DATE_FORMAT).format(gwinvoice.getValueDate())));
         table.setWidget(row, 3, new Label(DateTimeFormat.getFormat(DateFormats.SHORT_DATE_FORMAT).format(gwinvoice.getDueDate())));
         table.setWidget(row, 4, new Label(gwinvoice.getStatus()));
         table.setWidget(row, 5, new MoneyLabel(gwinvoice.getNet()));
         table.setWidget(row, 6, new MoneyLabel(gwinvoice.getTax()));
         table.setWidget(row, 7, new MoneyLabel(gwinvoice.getGross()));
         row++;
     
    

    @Override
    public void onFailure(Throwable cause) 
         //Debugging code

        StackTraceElement[] st = cause.getStackTrace();
       String error = "get invoice list failed\n";

       error = error+cause.getClass().getName()+"\n";
       if (cause instanceof StatusCodeException)
            StatusCodeException sce=(StatusCodeException) cause;
            int sc = sce.getStatusCode();
            error=error+"Status Code:"+ sc+"\n";
        
       for (int i=0; i<st.length; i++)
           error = error + st[i].toString()+ "\n";
       
        Window.alert(error);
    
;

调用总是以 500 状态码失败,因此会触发 AsyncCallback 内部类的 OnFailure 方法。

我有点不知所措,因为没有服务器端错误。

问题是服务器端的序列化之一,但我看不出它来自哪里。我已经重写了 OnAfterResponseSerialized 来探测事物并且它没有被调用 - (它被同一服务实现类中的其他方法调用,因此探测正在工作)。 从 javadocs 中,processCall() 应该抛出一个 SerializationException。我需要抓住它,看看发生了什么。

【问题讨论】:

GWTInvoiceList 实现可序列化?有默认构造函数吗?将这两个问题递归地应用于 GWTInvoiceList 上声明的所有变量。 【参考方案1】:

GWTInviceList 代码是什么样的?

我猜你没有 GWTInvoiceList 类的无参数构造函数。

【讨论】:

不,不是package uk.co.platosys.plataccs.shared.boox; import java.io.Serializable; import java.util.ArrayList; import com.google.gwt.user.client.rpc.IsSerializable; public class GWTInvoiceList extends ArrayList&lt;GWTInvoice&gt; implements Serializable, IsSerializable /** * */ private static final long serialVersionUID = 4065179521064190133L; /** * */ public GWTInvoiceList() 很抱歉代码的格式不是很漂亮。但正如您所见,它并没有缺少无参数构造函数。 你是否也尝试过调用 super();来自那个无参数的构造函数? 是的;没什么区别。该列表是在服务器上创建的, 虽然是序列化的问题;它没有在服务器上序列化,也没有调用 OnAfterResponseSerialized。【参考方案2】:

这段代码:

 /**
 * catches the SerializationException for forensic examination.
 */
@Override
public String processCall(String payload) throws SerializationException
    try
        return super.processCall(payload);
    catch(SerializationException se)
        logger.log("Xservlet serialisation excption", se);
        throw se;
    

添加到服务实现类会捕获 SerializationException,因此我可以跟踪异常对象。

【讨论】:

以上是关于检索 ArrayList 时出现 GWT-RPC 无法解释的 500 状态错误的主要内容,如果未能解决你的问题,请参考以下文章

重新审视 GWT-RPC 和臭名昭著的零星“StatusCodeException:0”异常

运行 GWT 应用程序时出现异常

通过 Parcelable 发送嵌套 ArrayList 时出现 NullPointerException

在索引处添加到 ArrayList 时出现 IndexOutOfBoundsException

尝试读取包裹 ArrayList<Object> 时出现 NullPointerException

尝试将相同的字符串添加到 ArrayList 类时出现 nullpointerexception [重复]