GWT场景下如何反序列化服务器返回的LinkedHashMap<String,Date>响应?
没问题,我来帮你搞定这个反序列化的事儿!首先咱们得明确:你的服务器应该是把这个LinkedHashMap序列化成JSON格式返回的(毕竟是HTTP接口),所以下面的方案都是基于JSON响应来展开的。
方法一:用GWT自带工具手动解析(简单直接)
GWT自带了JSON处理类,适合这种简单的键值对场景,步骤如下:
1. 发起HTTP请求获取响应
先通过RequestBuilder发送请求拿到服务器返回的JSON字符串:
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "/你的接口路径/testHMap"); try { builder.sendRequest(null, new RequestCallback() { @Override public void onResponseReceived(Request request, Response response) { if (Response.SC_OK == response.getStatusCode()) { String jsonResponse = response.getText(); // 拿到JSON后开始解析 LinkedHashMap<String, Date> dateMap = parseDateMap(jsonResponse); // 这里就可以用这个map做你要的操作啦 } else { // 处理请求失败的情况,比如打印错误信息 System.out.println("请求失败,状态码:" + response.getStatusCode()); } } @Override public void onError(Request request, Throwable exception) { // 处理网络错误 exception.printStackTrace(); } }); } catch (RequestException e) { e.printStackTrace(); }
2. 解析JSON成目标Map
写个解析方法,把JSON字符串转成LinkedHashMap<String, Date>:
private LinkedHashMap<String, Date> parseDateMap(String jsonStr) { LinkedHashMap<String, Date> resultMap = new LinkedHashMap<>(); // 把JSON字符串转成JSONObject JSONObject jsonObj = JSONParser.parseStrict(jsonStr).isObject(); // 遍历所有键值对 for (String key : jsonObj.keySet()) { JSONValue value = jsonObj.get(key); if (value.isString() != null) { String dateStr = value.isString().stringValue(); // 用GWT的DateTimeFormat解析ISO格式的日期字符串 Date date = DateTimeFormat.getFormat(PredefinedFormat.ISO_8601).parse(dateStr); resultMap.put(key, date); } } return resultMap; }
这里要注意:服务器必须把Date序列化成ISO 8601格式的字符串(比如2024-05-20T14:30:00Z),这样GWT的DateTimeFormat才能正确解析。记得导入com.google.gwt.i18n.client.DateTimeFormat和com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat。
方法二:用AutoBean实现类型安全反序列化(更优雅)
如果你的场景比较复杂,或者想要类型安全的处理,可以用GWT的AutoBean框架:
1. 定义Bean接口
AutoBean需要接口来生成序列化/反序列化代码,咱们先定义两个接口:
import com.google.gwt.autobean.shared.AutoBean; import com.google.gwt.autobean.shared.AutoBeanFactory; import com.google.gwt.autobean.shared.AutoBeanProperty; import java.util.Date; import java.util.LinkedHashMap; // 代表日期Map的Bean接口 public interface DateMapBean { @AutoBeanProperty LinkedHashMap<String, Date> getDateMap(); void setDateMap(LinkedHashMap<String, Date> map); } // AutoBean工厂接口 interface DateMapBeanFactory extends AutoBeanFactory { AutoBean<DateMapBean> dateMapBean(); }
2. 用AutoBeanCodex解析JSON
import com.google.gwt.autobean.shared.AutoBeanCodex; private LinkedHashMap<String, Date> parseWithAutoBean(String jsonStr) { DateMapBeanFactory factory = GWT.create(DateMapBeanFactory.class); // 解析JSON成AutoBean AutoBean<DateMapBean> autoBean = AutoBeanCodex.decode(factory, DateMapBean.class, jsonStr); DateMapBean bean = autoBean.as(); return bean.getDateMap(); }
这里要注意:服务器返回的JSON需要包裹在dateMap字段里,比如:
{"dateMap": {"AA": "2024-05-20T14:30:00Z", "BB": "2024-05-20T14:31:00Z"}}
如果服务器直接返回Map的JSON(没有外层字段),可以调整接口定义,直接用Map<String, Date>的适配接口,不过AutoBean对Map的支持需要额外注意,建议先按外层包裹的方式来做。
方法三:用GSON(如果项目已经引入)
如果你的项目已经用了GWT兼容的GSON库,那用它来反序列化会更省事:
import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; private LinkedHashMap<String, Date> parseWithGson(String jsonStr) { Gson gson = new Gson(); // 用TypeToken来指定泛型类型 TypeToken<LinkedHashMap<String, Date>> typeToken = new TypeToken<LinkedHashMap<String, Date>>() {}; return gson.fromJson(jsonStr, typeToken.getType()); }
注意要使用GWT专用的GSON版本,普通的GSON在客户端可能有不兼容的API。
几个关键注意点
- 日期格式要统一:服务器必须把
Date转成客户端能解析的格式,ISO 8601是最稳妥的选择,避免因格式不一致导致解析失败。 - GWT客户端类限制:确保你用的类(比如
java.util.Date)是GWT客户端支持的,有些Java核心类在GWT客户端是被裁剪过的。 - 响应头要正确:服务器返回的
Content-Type必须是application/json,这样客户端能正确识别为JSON数据。
内容的提问来源于stack exchange,提问作者Borș Nicolae

