在GWT中序列化/反序列化Json

JSON和GWT

最近, GWT用户小组中进行了有趣的讨论 ,涉及在客户端对JSON进行序列化/反序列化的最佳实践。 这篇文章旨在突出其重点。 到目前为止,在GWT中有三种将对象转换为JSON并从客户端转换回JSON的方法:

gwt-jackson框架:

gwt-jackson包装了著名的杰克逊图书馆的某些功能。 它允许使用称为ObjectMapper的接口转换对象。 使用gwt-jackson的优势在于,它可以序列化诸如Collections和Maps之类的复杂对象。 它还允许使用@JsonProperty和@JsonCreator之类的注释进行花式转换。 gwt-jackson的唯一遗憾是它使用了Generators ,在GWT 3.0版中将弃用该工具。 还值得注意的是RestyGWT使用了gwt-jackson,这是从客户端发出HTTP请求的替代方法之一。

可以在Github页面上找到示例: https : //github.com/nmorel/gwt-jackson/tree/master/examples

使用JavaScriptObject:

这是传统方法之一。 JavaScriptObject利用JSNI创建一个普通的JS对象。 它可以扩展并具有cast()方法,该方法允许将对象“安全”投射到其子类型。 可以使用JsonUtils.stringify()方法将JavaScriptObject转换为JSON字符串,也可以使用JsonUtils.safeEval()将其转换回JSON字符串。 JavaScriptObject与代表JavaScriptObject集合的JsArray协同工作,并扩展了JavaScriptObject。 该方法的唯一缺点是与创建对象相关联的样板。 例如:

public class Person extends JavaScriptObject {
	 //Constructor needs to be protected and zero-arguments
	  protected Person() { }

          // JSNI is used for setting/getting properties 
	  public final native String getFirstName() /*-{ return this.FirstName; }-*/;
	  public final native String getLastName()  /*-{ return this.LastName;  }-*/;
	  
	  public final native void setFirstName(String firstName) /*-{ this.FirstName = firstName; }-*/;
	  public final native void setLastName(String lastName)  /*-{ this.LastName = lastName; }-*/;
}

然后:

Person person = JavaScriptObject.createObject().cast();
				        JsArray array = JavaScriptObject.createArray().cast();
				        
				        person.setFirstName("first Name");
				        person.setLastName("last Name");
				        
				        array.push(person);
				        
				       
				        
				        GWT.log(JsonUtils.stringify(person));
				        GWT.log(JsonUtils.stringify(array));

结果:

{"FirstName":"first Name","LastName":"last Name"}
[{"FirstName":"first Name","LastName":"last Name"}]

使用JsInterop批注:

JsInterop批注允许将Java类型/类视为Javascript对象,并允许向/从应用程序Js环境导出或导入功能。 一些GWT项目成员( Thomas BroyerJens Nehlmeier )推荐使用JsInterop,因为JsInterop是GWT未来的重要组成部分,它将成为处理GWT中Javascript对象的主要方式。 使用JsInterop的唯一缺点是Elemental 2仍处于实验阶段,因此直到它变得稳定为止。 开发人员最好将自己的代码片段用于本地Javascript实用程序(例如Json类),例如:

@JsType(isNative=true, namespace=GLOBAL)
public class JSON {
	
	public native static String stringify(Object obj);
	
	public native static Object parse(String obj);

}

如果我们的对象看起来像:

@JsType(isNative=true, namespace=GLOBAL, name="Object")
public class Record {
	
	String id;
	String date;
	String data;
	
	public Record() {
		
	}
	
}

然后 :

Record record = new Record();
  record.id = "1";
  record.date = "20";
  record.data = "30";

String json = JSON.stringify(recod);

 GWT.log(json);
// Result: {"id":"1","date":"20","data":"30"}

autorest -gwt (也是进行HTTP调用的选项之一)使用JsInterop在发出HTTP请求之前对对象进行序列化/序列化。

重要的是要注意 ,地图不是由JSON.stringify()方法处理的,尝试对地图进行字符串化会引发以下错误:

Map mapTest = new HashMap();
				        mapTest.put("v1", "v2");
				        mapTest.put("v3", "v4");
 GWT.log(JSON.stringify(mapTest));
Uncaught TypeError: Converting circular structure to JSON

转换诸如ArrayList之类的Collection不会引发任何错误,但是会创建开发人员希望摆脱的其他JSON字段:

List test2 = new ArrayList();
				       
				       test2.add(record2);
				       test2.add(record);
 GWT.log(JSON.stringify(test2));

结果:

{"array_3_g$":[{"id":"1","date":"50","data":"90"},{"id":"1","date":"20","data":"30"}]}

GWT编译器出于某种原因添加了“ array_3_g $”,因此用户需要找到一种方法来将其删除以进行干净的转换,例如:

{[{"id":"1","date":"50","data":"90"},{"id":"1","date":"20","data":"30"}]}

到目前为止,Plain Arrays是唯一可以正确转换的结构。

带走

在这三种方法中,JsInterop似乎是处理JSON的最可行方法。 目前主要关注的是处理诸如Collections和Maps之类的对象,这些对象需要开发人员进行进一步的手动处理。 Plain Arrays是目前唯一可以正确转换的结构,因此开发人员可以尝试简化或转换为Plain Arrays进行干净转换。

JavaScriptObject提供了自己的使用JsArray处理“列表”的方式。 现在,gwt-jackson仍然是提供开箱即用的“收藏夹”和“地图”转换的唯一选项。

翻译自: https://www.javacodegeeks.com/2017/07/serializingdeserializing-json-gwt.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值