如何在GWT中使用autobean将json转换为java类

如何在GWT中使用autobean将json转换为java类,java,gwt,json-deserialization,autobean,Java,Gwt,Json Deserialization,Autobean,我在gwt中有一个类Person,我已经发送了一个Person的实例,其中servlet使用Gson从服务器转换到客户端。但是在客户端,我似乎不能使用Gson。从我在论坛上读到的内容来看,最好的方法似乎是再次使用AutoBeans将Json转换为objectPerson 但是在AutoBeans中,我只能使用接口。如果有人能帮我写,我将不胜感激 我从服务器上得到一个json示例,希望再次转换为Person类: {“姓名”:“aaa”,“家庭”:“fff”,“用户名”:“uuu”,“年龄”:20,

我在
gwt
中有一个类
Person
,我已经发送了一个
Person
的实例,其中servlet使用
Gson
从服务器转换到客户端。但是在客户端,我似乎不能使用Gson。从我在论坛上读到的内容来看,最好的方法似乎是再次使用
AutoBeans
Json
转换为object
Person

但是在
AutoBeans
中,我只能使用接口。如果有人能帮我写,我将不胜感激

我从服务器上得到一个
json
示例,希望再次转换为
Person
类:

{“姓名”:“aaa”,“家庭”:“fff”,“用户名”:“uuu”,“年龄”:20,“电话”:[{“id”:0,“电话号码”:“0911111”}],“亲属”:[null]}

public类Person实现可序列化{
私有字符串名称;
私弦家庭;
私有字符串用户名;
私人互联网;
私人名单电话;
私人名单亲属;
公众人士(){
}
公众人物(字符串名称、字符串族、字符串用户名、整数、电话列表、亲属列表){
this.name=名称;
这个家庭=家庭;
this.username=用户名;
这个。年龄=年龄;
这个。电话=电话;
this.relatives=new ArrayList();
这个。亲戚=亲戚;
}
公用电话(电话p){
电话。加(p);
}
公共字符串getName(){
返回此.name;
}
公共字符串getFamily(){
归还这个家庭;
}
公共整数getAge(){
返回这个年龄;
}
公共字符串getUsername(){
返回此用户名;
}
公共列表getNumbers(){
归还这个电话;
}
公共列表{
把这个还给我的亲戚;
}
公共字符串getAllNumbers(){
返回Phone.convertPhonesToText(电话);
}
公共静态Person findPerson(列表personList,字符串用户名){
// .....
}
公共静态列表转换器TextToPersons(列表personList,字符串PersonText){
// .....
}
公共字符串convertPersonsToText(){
// ....
}
}

是的,正如Tobika所评论的,另一个答案表明AutoBeans需要一个接口。如果在客户端和服务器端都使用AutoBeans,并且将所有模型定义为接口,则AutoBeans会感觉更好

如果您想使用您的类模型,可以使用GWT Jackson,它与AutoBeans非常相似,但它使用您的模型,将json绑定到您的模型(如其他服务器端库;Jackson、gson等):

公共静态接口PersonMapper扩展ObjectMapper{}
@重写moduleload()上的公共void{
PersonMapper=GWT.create(PersonMapper.class);
String json=mapper.write(newperson(“John”,“Doe”));
GWT.log(json);//>{“firstName”:“John”,“lastName”:“Doe”}
Person=mapper.read(json);
log(person.getFirstName()+“”+person.getLastName());
}
或者,您可以将普通GWT与JsInterop一起使用。这有很多限制,但即使有这个限制,它也是一个非常好的选择。如果可以避免DTO中的继承,这是我最喜欢的选项。但这具有超轻量级的巨大优势(实际上是零开销映射开销和零代码开销,因为它使用本机解析,并且不复制,直接访问解析后的json对象)。限制:无法使用继承,“断开类型系统”(SomeDtoType的所有X instanceof SomeDtoType始终返回true,因为所有dto都是Object类型,这是有意义的,因为我们实际上使用的是解析后的JSON),不能仅使用集合本机数组(但多亏了java8 Stream,这应该不会是一个问题,不管您想用Stream.of(arr)开始做什么),并且只支持双精度和布尔装箱类型(不支持Date或BigInteger等任何奇特类型,不支持long/long…)

@JsType(isNative=true,package=GLOBAL,name=“Object”)最终类人物{
//您可以使用getter/setter,但由于这个类是final,所以DTO不会增加任何值
公共字符串名;公共字符串名;公共Phome[]编号;
//您可以添加一些助手方法,不要忘记跳过序列化!
public final@JsOverlay@JsonIgnore List getNumberList(){
返回流.of(number).collect(collector.toList());
}
}
@JsType(isNative=true,package=GLOBAL,name=“Object”)最终类电话{
公共字符串号;
}
@JsMethod(namespace=“JSON”)公共静态本机T解析(字符串文本);
@重写moduleload()上的公共void{
Person-Person=parse(“{\“firstName\”:“John\”,“lastName\”:“Doe\”);
GWT.log(person.firstName+“”+person.lastName);
}
这些简单且有限的DTO与其说是一种类型,不如说是一种DTO方案。但有一个很大的优势,这种DTO可以与大多数服务器端解析器一起开箱即用。Jackson和GSON将在不进行任何配置的情况下进行编码和解析。

可能存在重复的DTO
public class Person implements Serializable {
   private String name;
   private String family;
   private String username;
   private int age;
   private List<Phone> phones;
   private List<Person> relatives;

   public Person() {
   }

   public Person(String name, String family, String username, int age, List<Phone> phones, List<Person> relatives) {
      this.name = name;
      this.family = family;
      this.username = username;
      this.age = age;
      this.phones = phones;
      this.relatives = new ArrayList<Person>();
      this.relatives = relatives;
   }

   public void addPhone(Phone p) {
      phones.add(p);
   }

   public String getName() {
      return this.name;
   }

   public String getFamily() {
      return this.family;
   }

   public int getAge() {
      return this.age;
   }

   public String getUsername() {
      return this.username;
   }

   public List<Phone> getNumbers() {
      return this.phones;
   }

   public List<Person> getRelatives() {
      return this.relatives;
   }

   public String getAllNumbers() {
      return Phone.convertPhonesToText(phones);
   }

   public static Person findPerson(List<Person> personList, String username) {
      // .....
   }

   public static List<Person> convertTextToPersons(List<Person> personList, String personsText) {
      // .....
   }

   public String convertPersonsToText() {
      // ....
   }
}
public static interface PersonMapper extends ObjectMapper<Person> {}

@Override public void onModuleLoad() {
    PersonMapper mapper = GWT.create(PersonMapper.class);

    String json = mapper.write(new Person("John", "Doe"));
    GWT.log( json ); // > {"firstName":"John","lastName":"Doe"}

    Person person = mapper.read(json);
    GWT.log(person.getFirstName() + " " + person.getLastName());
}
@JsType(isNative=true, package=GLOBAL, name="Object") final class Person {
    // you can use getter/setter but as this class is final DTO adds no value
    public String firstName; public String lastName; public Phome[] numbers;
    // you can add some helper methods, don't forget to skip serialization!
    public final @JsOverlay @JsonIgnore List<Phone> getNumberList() {
        return Stream.of(numbers).collect(Collectors.toList());
    }
}

@JsType(isNative=true, package=GLOBAL, name="Object) final class Phone {
    public String number;
}

@JsMethod(namespace = "JSON") public static native <T> T parse(String text);

@Override public void onModuleLoad() {
    Person person = parse("{\"firstName\":\"John\",\"lastName\":\"Doe\"}");
    GWT.log(person.firstName + " " + person.lastName);
}