执行 RPC 时出现 GWT 序列化问题

Posted

技术标签:

【中文标题】执行 RPC 时出现 GWT 序列化问题【英文标题】:GWT serialization issue while doing RPC 【发布时间】:2012-05-22 16:11:31 【问题描述】:

我正在学习 GWT。

我收到一个关于 serilizablity 的错误。

简要描述我的问题

在自定义属性类中

package com.exp.shared;


import java.io.Serializable;
import java.util.List;

public class Customproperties implements Serializable  

    private Object value;
    private List<?> values;
          // more variable

    public Customproperties() 
        // TODO Auto-generated constructor stub
    

    public Customproperties(String propertyName, List<?>  object,
            String propertyType, boolean mulitiValued, String cardinality, Boolean required) 

        this.propertyName=propertyName;
        this.values=object;
                // more initialization
    

    public Customproperties(String propertyName,  List<?> object, String propertyType,
            boolean multiValued) 
        this.propertyName=propertyName;
        this.values=object;
                // more initialization
    

    public Object getValue() 
              return value;
    
    public List<?> getValues() 
        return values;
    
 

在 classImpl 之一的服务器包中,我正在使用 Customproperties 的对象

      if (doc.getPropertyValue("cmis:objectTypeId").toString().equals("cmis:document")) 

    customproperty=new Customproperties(p.getDefinition().getDisplayName(), p.getValue(), p.getType().toString(),p.isMultiValued());
       
else 
    customproperty=new Customproperties(p.getDefinition().getDisplayName(), p.getValues(), p.getType().toString(),p.isMultiValued(),value.getCardinality(),value.isRequired());
            

如果条件 p.getValue() 返回 Object。 并且在其他条件下 p.getValues() 返回列表。

CustomProperties class 中,当我将object variable 更改为string 时,它工作得非常好。

但我不改变它给我错误。

com.exp.shared.Customproperties' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = com.exp.shared.Customproperties@1aa5344
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:619)

我不想改变它 String 。我只想接收对象。因为这个对象有时可能是Stringdateint

请帮忙。

【问题讨论】:

【参考方案1】:

您应该阅读有关 RPC 序列化here 的 GWT 文档。

类 java.lang.Object 是不可序列化的,因此您不能期望 Object 类型的集合会通过网络进行序列化。

这就是你得到例外的原因。在您提供的代码中,您没有使用字段值。您类上的两个构造函数都只设置值列表。因此,如果您不使用字段值,只需将其删除即可。但假设这是一个错误,你确实需要使用它......

您必须了解您的值可能具有的所有不同类型。然后要么你有不同的字段,比如 intValue、dateValue、stringValue ... 或者你可以有一个字符串字段,并将你的对象序列化成这样的字符串。

public class CustomProperties 
    private String value;
    private String type;

    private void setValue(Object value, String type) 
        if (value != null) 
            this.value = value.toString();
            this.type = type;
        
    

    private Object getValue() 
        if (value != null) 
            if ("int".equals(type)) return Integer.valueOf(value);
            elseif ("date".equals(type)) return // Parse date from value here
            elseif ("string".equals(type)) return (String) value;
            // other cases
        
        return value;
    

【讨论】:

【参考方案2】:

在 GWT 中,声明容器时从不声明像 List 这样的泛型类型。 始终使用更具体的类型,例如 ArrayList

【讨论】:

:感谢您的建议,我会这样做。但这不是我的问题。我在构造函数中传递一个对象,因为我遇到了可序列化错误。如何在不将其更改为字符串或任何其他数据类型的情况下将其删除。 在 gwt 的服务器端,您可以使用任何您需要的类型 gwt 没有问题。但在客户端,您可以通过 instanceof keyward 检查可能的类型,一切都会好起来的。【参考方案3】:

在您的情况下,问题很可能是List&lt;?&gt;。 GWT 不知道您在该列表中放入了哪些可能的类型,因此它不会生成代码来序列化源路径上的每个可能的类型,它除了知道它已经需要的内容之外什么都不生成。当您尝试将其他地方不需要的东西放入其中时,会发生异常,表明 GWT 没有被告知您计划通过网络发送该对象。

这里的标准方法通常是创建一个可能实现Serializable 的标记接口,并使其成为List&lt;MyModelObjects&gt;。然后每个可以放入其中的对象都应该实现该接口。

【讨论】:

以上是关于执行 RPC 时出现 GWT 序列化问题的主要内容,如果未能解决你的问题,请参考以下文章

GWT:序列化异常

GWT:分派传入 RPC 调用时出现异常

在 GWT 中使用 RPC 时出现 IncompatibleRemoteServiceException

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

初始化 AsyncCallback 时出现 GWT RPC ClassNotFoundException

解码根据 GWT 的序列化策略生成的 *.gwt.rpc 文件