Spring JSON序列化,Gson反序列化 [英] Spring JSON serialization, Gson deserialization

查看:190
本文介绍了Spring JSON序列化,Gson反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在某些内部对象的反序列化过程中遇到了问题,在春天,我使用 @ResponseBody 来初始化所有对象,然后输出它们。

 [{id: 1,location:{id:1,... extra location data}},
{id:2,location:1}
]
location:1 指向位置对象已经在前一个对象中反序列化了。
反序列化是通过以下方法完成的:

  @Override 
public void handleReader(Reader reader){
try {
String json = readerToString(reader);
T object = getGson()。fromJson(json,returnType);
handleObject(object);
} catch(Exception e){
Sentry.captureException(e);




$ b $ p
$ b

例如,这是通过一个普通的通用类,我会使用类型 Event [] 作为 T 泛型来返回一个数组。



我怎样才能使用Gson来修复这个问题,或者让spring每次输出完整的数据呢?理想情况下,我希望修复Gson,因为它可以大大减少带宽,但在这一点上我并没有太过兴奋。

我的Spring返回方法如下:

  @Override 
public List< T> list(){
return service.findAll();
}

与初始化类似:

  @Override 
@Transactional
public List< Event> findAll(){
List< Event> list = eventRepository.findByArchivedFalse();
for(Event event:list){
this.initialize(event);
}
返回列表;
}
@Override
public Eventize(Event obj){
Hibernate.initialize(obj.getLocation());
Hibernate.initialize(obj.getLocation()。get ... inner data here);
return obj;
}

我想这将需要一个真正的结构审查,但是,如果我可以帮助它,我想保持结构大致相同。

解决方案

您将不得不编写自定义反序列化器,如果你不想改变JSon。然而,更改JSon正是我所推荐的。



选项1:更改JSon



我认为正确的做法是有两个单独的消息,例如:

$ p $ {
uniqueLocations:
[
{id:1,...额外位置信息},
],
locationMap:
[
{id:1, location:1},
{id:2,location:1}
... etc.
]
}

这更清晰;这将分离你的json,这样你就可以在同一个地方获得相同类型的数据。






选项2:制作Gson能够做更复杂的反序列化



然而,如果你不愿意这样做,你可以编写一个自定义的反序列化器。这是最直接的方式,扩展 TypeAdapter 仅使用特定的具体类非参数化类型。但是,如果您想使用参数化类型,则必须使用 TypeAdapterFactory



您可以阅读更多关于如何在此处执行此操作的信息:如何实现TypeAdapterFactory在Gson?


I'm currently having an issue with the deserialization of certain inner-objects, in spring, I initialize all of my objects before outputting them using @ResponseBody.

As an example, this is a response:

[{id:1, location:{id:1, ... extra location data}},
 {id:2, location:1}
]

Now, GSON throws an error as it is not able to understand that location:1 refers to the location object already deserialized in the previous object. Deserialization is done in the following method:

@Override
public void handleReader(Reader reader) {
    try {
        String json = readerToString(reader);
        T object = getGson().fromJson(json, returnType);
        handleObject(object);
    } catch (Exception e) {
        Sentry.captureException(e);
    }
}

As an example, this is called through a regular generic class, I'd use the type Event[] as the T generic in order to return an array.

How can I either fix this using Gson or make spring output the full data every time? Ideally I'd like to fix with Gson as it would allow for seriously reduced bandwidth but I'm not too fussed at this point.

My Spring returning method is as follows:

@Override
public List<T> list() {
    return service.findAll();
}

with the initialization like so:

@Override
@Transactional
public List<Event> findAll() {
    List<Event> list = eventRepository.findByArchivedFalse();
    for (Event event : list) {
        this.initialize(event);
    }
    return list;
}
@Override
public Event initialize(Event obj) {
    Hibernate.initialize(obj.getLocation());
    Hibernate.initialize(obj.getLocation().get... inner data here);
    return obj;
}

I imagine this is going to require a real structure review but, if I can help it, I'd like to keep the structure roughly the same.

解决方案

You're going to have to write a custom deserializer, if you're not willing to change the JSon. However, changing the JSon is exactly what I would recommend.

Option 1: Changing the JSon

I think the right thing to do is to have two separate messages, e.g.

{
  "uniqueLocations":
    [
      {"id":1, ... extra location details} ,
    ],
  "locationMap":
    [ 
      {"id":1,"location":1},
      {"id":2,"location":1}
      ... etc.
    ]
}

This is clearer; this separates your json so that you always have the same types of data in the same places.


Option 2: Making Gson able to do more complicated deserializations

However, if you're not willing to do that, you could write a custom deserializer. The most straightforward way to do that, extending TypeAdapter, only uses specific, concrete classes, not parameterized types. However, if you want to use a parameterized type, you must use a TypeAdapterFactory.

You can read more about how to do this here: How do I implement TypeAdapterFactory in Gson?

这篇关于Spring JSON序列化,Gson反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆