如何正确地将特定对象的列表转换为Gson?

我正在开发Spring MVC项目。 我正在使用Hibernate。 我想使用AJAX和jQuery从我的Spring Controller中获取一些JSON。 不幸的是,当我在我的应用程序中实现Gson方法时,我遇到了一个错误:

 java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter? 

我必须使用哪种适配器以及使用哪种方式? 该方法的最后一行发生了错误:

 public String messagesToJson(List messages) { Gson gson = new Gson(); List synchronizedMessages = Collections.synchronizedList(messages); return gson.toJson(synchronizedMessages, ArrayList.class); } 

这是我在使用Hibernate的Spring MVC项目中使用的Message类:

 @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 } 

编辑

我想知道:我的Message对象是代理还是整个List ? 我以这种方式获取消息列表:

 public List findAllUserMessages(String username) { Query query = entityManager.createQuery("from Message where username = :username order by date desc") .setParameter("username", username); @SuppressWarnings("unchecked") List messages = query.getResultList(); return messages; } 

编辑2

不,我的List对象未被代理。

我已经解决了我的问题。 关于HibernateProxy对象的假设似乎非常可能。 但是,当我仔细阅读错误时,一切都已开始正常工作。 最后我用这种方式注册了类型适配器:

 public String messagesToJson(List messages) { GsonBuilder gsonBuilder = new GsonBuilder(); Gson gson = gsonBuilder.registerTypeAdapter(Message.class, new MessageAdapter()).create(); return gson.toJson(messages); } 

任何我的MessageAdapter类看起来像:

 public class MessageAdapter implements JsonSerializer { @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; } } 

就这样。 现在我可以正确使用AJAX在jQuery中获取JSON。

正如@madhead在评论中提到的那样,这是因为,根据具体情况,Hibernate会在您的对象周围创建代理,这将代表某些方法的实际实现,以及其他方法的“检测”实现。 因此,对象的“实际”类型是HibernateProxy。 您可以使用类似于此处描述的代码来访问您的实现。 在您的情况下,您必须为列表中的每个项目调用“unproxy”方法,将它们放入新列表中。

虽然很难回答,但我想通过为字符串字段创建DTO来解决目的。