java 如何将特定对象的列表正确转换为 Gson?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11518091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to properly convert List of specific objects to Gson?
提问by woyaru
I am working on Spring MVC project. I am using Hibernate. I want to use AJAX with jQuery to get some JSONs from my Spring Controllers. Unfortunately when I was implementing Gson
methods in my application I have got an error:
我正在研究 Spring MVC 项目。我正在使用休眠。我想使用带有 jQuery 的 AJAX 从我的 Spring 控制器中获取一些 JSON。不幸的是,当我Gson
在应用程序中实现方法时出现错误:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class:
org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
Which adapter I have to use and in which way? The error has occurred on the last line of the method:
我必须使用哪种适配器以及以何种方式使用?错误发生在方法的最后一行:
public String messagesToJson(List<Message> messages) {
Gson gson = new Gson();
List<Message> synchronizedMessages = Collections.synchronizedList(messages);
return gson.toJson(synchronizedMessages, ArrayList.class);
}
This is my Message
class I am using in my Spring MVC project with Hibernate:
这是我Message
在带有 Hibernate 的 Spring MVC 项目中使用的类:
@Entity
@Table(name = "MESSAGES", schema = "PUBLIC", catalog = "PUBLIC")
public class Message implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int messageId;
private User users;
private String message;
private Date date;
//Constructor, getters, setters, toString
}
EDIT
编辑
I am wondering: my Message
object is proxied or the whole List<Message>
? I am getting the list of messages in this way:
我想知道:我的Message
对象是代理还是整个List<Message>
?我以这种方式获取消息列表:
public List<Message> findAllUserMessages(String username) {
Query query = entityManager.createQuery("from Message where username = :username order by date desc")
.setParameter("username", username);
@SuppressWarnings("unchecked")
List<Message> messages = query.getResultList();
return messages;
}
EDIT 2
编辑 2
No, my List<Message>
object isn't proxied.
不,我的List<Message>
对象没有被代理。
回答by woyaru
I have resolved my problem. The assumption about HibernateProxy
objects seemed to be very probable. However everything has started to work properly when I have read carefully my error. Finally I have registered type adapter in this way:
我已经解决了我的问题。关于HibernateProxy
物体的假设似乎很有可能。然而,当我仔细阅读我的错误时,一切都开始正常工作。最后我以这种方式注册了类型适配器:
public String messagesToJson(List<Message> messages) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.registerTypeAdapter(Message.class, new MessageAdapter()).create();
return gson.toJson(messages);
}
Any my MessageAdapter
class looks like:
我的任何MessageAdapter
课程看起来像:
public class MessageAdapter implements JsonSerializer<Message> {
@Override
public JsonElement serialize(Message message, Type type, JsonSerializationContext jsc) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("message_id", message.getMessageId());
jsonObject.addProperty("message", message.getMessage());
jsonObject.addProperty("user", message.getUsers().getUsername());
jsonObject.addProperty("date", message.getDate().toString());
return jsonObject;
}
}
And thats all. Now I can get JSONs in jQuery using AJAX properly.
就这样。现在我可以正确地使用 AJAX 在 jQuery 中获取 JSON。
回答by jpkrohling
As @madhead mentioned in the comments, this happens because, depending on the situation, Hibernate creates proxies around your object, which will call the actual implementation for some methods, and a "instrumented" one for others. Thus, the "actual" type of your objects are HibernateProxy. You can get access to your implementation by using a code similar to the one described here. In your case, you'd have to call the "unproxy" method for each item in your list, putting them into a new list.
正如@madhead 在评论中提到的那样,发生这种情况是因为,根据情况,Hibernate 会在您的对象周围创建代理,这些代理将调用某些方法的实际实现,并为其他方法调用“检测”方法。因此,对象的“实际”类型是 HibernateProxy。您可以使用类似于此处描述的代码来访问您的实现。在您的情况下,您必须为列表中的每个项目调用“unproxy”方法,将它们放入一个新列表中。
回答by raikumardipak
Though pretty old to answer, I guess by just creating a DTO for Message with String fields would solve the purpose.
虽然回答起来很老了,但我想只需为带有字符串字段的消息创建一个 DTO 就可以解决这个问题。