gson.toJson()在Servlet中抛出StackOverflowError [英] gson.toJson() throws StackOverflowError in Servlet

查看:184
本文介绍了gson.toJson()在Servlet中抛出StackOverflowError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有客户对象列表

List<Client> clientsList=new ArrayList<Client>();
clientsList=clientDao.GetAllClients();

实体客户有其他列表作为属性:

Entity Client has others list as attributes:

@ManyToOne(optional=false)
private User createdBy;


@ManyToMany(mappedBy = "Clients")
private Set<ClientType> Types=new HashSet();


@ManyToOne(optional=false)
private LeadSource id_LeadSource;
@ManyToOne(optional=false)
private Agencie id_Agencie;

@OneToMany(cascade=CascadeType.ALL,mappedBy="Owner")
private Set<Propertie> properties=new HashSet();

@OneToMany(cascade=CascadeType.ALL,mappedBy="buyer")
private Set<Sale> sales=new HashSet();

@OneToMany(cascade=CascadeType.ALL,mappedBy = "client")
private Set<Rent> Rents=new HashSet();

@OneToMany(cascade=CascadeType.ALL,mappedBy = "clientDoc")
private Set<Document> Docuements=new HashSet();

当我尝试将客户列表转换为json格式时

and when i try to convert list of clients to json format

out.write(new Gson().toJson(clientsList));

我收到此错误:

java.lang.StackOverflowError
at com.google.gson.stream.JsonWriter.beforeName(JsonWriter.java:603)
at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401)
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:512)
at com.google.gson.internal.bind.TypeAdapters$8.write(TypeAdapters.java:270)
at com.google.gson.internal.bind.TypeAdapters$8.write(TypeAdapters.java:255)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:113)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:240)


推荐答案

那是因为您的实体具有双向连接。因此,例如客户有一组 s,每个租金都有对客户的引用。当您尝试序列化客户端时,您序列化其租金然后您必须序列化每个客户端 in Rent 等等。这就是导致 StackOverflowError 的原因。

That is because your entities have bidirectional connections. So for example Client has a set of Rents and each rent has a reference to Client. When you try serializing a Client you serialize its Rents and then you have to serialize each Client in Rent and so on. This is what causes the StackOverflowError.

要解决此问题,您必须将某些属性标记为 transient (或使用一些类似的anotation),例如在 Rent transient Client c>然后任何编组的lib都会忽略这个属性。

To solve this problem you will have to mark some properties as transient (or use some similar anotation), for example use transient Client in Rent Then any marshalling lib will just ignore this property.

如果是Gson,你可以用另一种方式来标记那些的字段希望通过 @Expose 包含在json中并使用以下命令创建gson对象:

In case of Gson you can do the other way around marking those field you do want to be included in json with @Expose and creating the gson object with:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

P.S。另外,我想提一下将JPA实体转换为json并将其发送到某个地方通常不是一个好主意。我建议创建一个DTO(数据传输对象)类,其中只包含您需要的信息,理想情况下只使用简单类型,如 int 日期 String 等等。如果您对此方法有疑问,可以谷歌 DTO 数据传输对象或点击此链接: https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm

P.S. Also, I would like to mention that converting your JPA entity to json and sending it somewhere is generally not a very good idea. I'd recommend creating a DTO(Data Transfer Object) class where you include only the info you need and ideally using only simple types like int, Date, String and so on. If you have questions about this approach you can google for DTO, Data Transfer Object or follow this link: https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm

这篇关于gson.toJson()在Servlet中抛出StackOverflowError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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