从.NET的角度来看,我有一个类通用的类定义..
public class SyncWrapper<T, I>
{
public IList<T> Data { get; set; }
public IList<I> DeleteIds { get; set; }
public DateTime LastSyncDateTime { get; set; }
}
我能够通过简单地调用...
从json创建这个对象的实例JsonConvert.DeserializeObject<SyncWrapper<T, Guid>>(json);
现在我已经完成了将此代码移植到Java / Android的任务。以前从未接触过Java,我需要学习很多东西!
无论如何,到目前为止,我已经尝试过Gson和Jackson从json那里获得物品,但没有任何喜悦。我认为我无法使用<T>
涉及gson.fromJson(json, SyncWrapper<T, UUID>.class)
进行调用,例如因为Erasure类型存在问题!
到目前为止,我的努力看起来像这样....
GSON
Gson gson = new Gson();
SyncWrapper<MyClass, UUID> result = gson.fromJson(json, new TypeToken<SyncWrapper<MyClass, UUID>>() { }.getType());
这会编译,但结果是一个空的SyncWrapper
杰克逊
ObjectMapper mapper = new ObjectMapper();
SyncWrapper<MyClass, UUID> result = mapper.readValue(json, new TypeReference<SyncWrapper<MyClass, UUID>>() { });
这会编译但在执行时崩溃应用程序!!!
我的Java版SyncWrapper ....
public class SyncWrapper<T, I> {
private DateTime lastSyncDateTime;
private Collection<T> data;
private Collection<I> deleteIds;
public Collection<T> getData() {
return data;
}
public void setData(Collection<T> data) {
this.data = data;
}
public Collection<I> getDeleteIds() {
return deleteIds;
}
public void setDeleteIds(Collection<I> deleteIds) {
this.deleteIds = deleteIds;
}
public DateTime getLastSyncDateTime() {
return lastSyncDateTime;
}
public void setLastSyncDateTime(DateTime lastSyncDateTime) {
this.lastSyncDateTime = lastSyncDateTime;
}
}
我被强大的力量所吸引(所有编程都是一样的不是吗?),所以任何帮助都非常感激。
我对使用哪个库(Gson,Jackson等)并不珍贵
更新
要反序列化的Json的一个例子......
{
"Data": [
{
"Name": "Company A",
"Id": "7d5d236c-c2b5-42dc-aea5-99e6752c8a52"
},
{
"Name": "Company B",
"Id": "44444444-0000-0000-0000-444444444444"
},
{
"Name": "Company C",
"Id": "249a4558-05c6-483f-9835-0056804791c9"
}
],
"DeleteIds": [
"5f7873a6-b2ee-4566-9714-1577b81384f4",
"1f224a39-16c3-441d-99de-8e58fa8f31c2"
],
"LastSyncDateTime": "\/Date(1393580073773+0000)\/"
}
..或者这个(通常,DeleteIds将为null)...
{
"Data": [
{
"Name": "Company A",
"Id": "7d5d236c-c2b5-42dc-aea5-99e6752c8a52"
},
{
"Name": "Company B",
"Id": "44444444-0000-0000-0000-444444444444"
},
{
"Name": "Company C",
"Id": "249a4558-05c6-483f-9835-0056804791c9"
}
],
"DeleteIds": null,
"LastSyncDateTime": "\/Date(1393580073773+0000)\/"
}
对于上面的json,我将映射到一个SyncWrapper,其中T是Company ...
public class Company extends ModelBase {
private String name;
public Company(UUID id, String name) {
super(id);
setName(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
答案 0 :(得分:1)
以下是问题:
您的Java类中的字段名称与JSON中的字段名称不匹配;资本化问题。这就是为什么你在解析后绝对没有回来的原因。
我会选择Gson的例子,因为我知道这是我的头脑。你可以在杰克逊做同样的事情,但我需要查看它们:
public class SyncWrapper<T, I> {
@SearializedName("LastSyncDateTime")
private DateTime lastSyncDateTime;
@SearializedName("Data")
private Collection<T> data;
@SearializedName("DeleteIds")
private Collection<I> deleteIds;
这告诉Gson Java中的哪些字段映射到JSON中的字段。您也可以改为使用字段命名策略,因为看起来您的所有字段都是上层骆驼案例:
Gson g = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
.build();
现在您的字段将匹配。下一个问题将是UUID
类。 Java中的那个类不是字符串;它是一个生成UUID的类。只需使用String
作为在Java类中保存它的类型。
DateTime
类......同样的问题。最重要的是,你的日期JSON中有一些奇怪的值。您要么也想将其存储为String
,要么您将不得不编写自定义反序列化来处理它。
随着这些变化,我觉得你很高兴。
编辑以从评论中添加:如果您确实需要Java UUID
类而不仅仅是String
表示,那么您可以编写一小块需要注意的代码这对你来说:
class UUIDDeserializer implements JsonDeserializer<UUID>
{
@Override
public UUID deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException
{
return UUID.fromString(je.getAsString());
}
}
然后你可以用Gson注册:
Gson g = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
.registerTypeAdapter(UUID.class, new UUIDDeserializer())
.build();
这将使用UUID
个实例填充您班级中的UUID
个字段。这与你那个时髦的日期值有关。
答案 1 :(得分:0)
我建议使用Jackson;它有一个更清晰的API,不需要创建一个新的类型作为Gson(你必须扩展一个类才能做到这一点)。
示例:
public static <T> T fromJsonToGenericPojo(
String json, Class<?> classType, Class<?>... genericTypes) {
JavaType javaType = TypeFactory.defaultInstance()
.constructParametricType(classType, genericTypes);
try {
return OBJECT_MAPPER.readValue(json, javaType);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
throw new IllegalArgumentException(e);
}
}