使用 Gson 序列化 Objectify 键
有没有人能够使用具有 Key (对象化)字段的 gson 序列化/反序列化对象?
我正在尝试使用 gson 来执行此操作,但似乎网上有几个人在序列化 appengine 密钥时遇到了问题。有什么建议吗?
当我尝试这样做时,我在反序列化时收到以下错误:
java.lang.NullPointerException
at com.google.appengine.api.datastore.KeyTranslator.convertToPb(KeyTranslator.java:55)
at com.google.appengine.api.datastore.DataTypeTranslator$ReferenceType.setPropertyValue(DataTypeTranslator.java:680)
at com.google.appengine.api.datastore.DataTypeTranslator.createPropertyValue(DataTypeTranslator.java:207)
at com.google.appengine.api.datastore.DataTypeTranslator.createProperty(DataTypeTranslator.java:191)
at com.google.appengine.api.datastore.DataTypeTranslator.addProperty(DataTypeTranslator.java:159)
at com.google.appengine.api.datastore.DataTypeTranslator.addPropertiesToPb(DataTypeTranslator.java:142)
at com.google.appengine.api.datastore.EntityTranslator.convertToPb(EntityTranslator.java:47)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.doBatchPutBySize(AsyncDatastoreServiceImpl.java:475)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.put(AsyncDatastoreServiceImpl.java:446)
at com.googlecode.objectify.impl.AsyncObjectifyImpl.put(AsyncObjectifyImpl.java:255)
at com.googlecode.objectify.impl.AsyncObjectifyImpl.put(AsyncObjectifyImpl.java:229)
at com.googlecode.objectify.impl.ObjectifyImpl.put(ObjectifyImpl.java:126)
at com.rewardly.mailfoo.dataaccess.DAO.storeEntity(DAO.java:36)
at com.rewardly.mailfoo.ajaxcalls.UpdateEntity.doPost(UpdateEntity.java:38)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.rewardly.mailfoo.utils.UserFilter.doFilter(UserFilter.java:44)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:351)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Has anyone been able to serialize/deserialize objects using gson which have Key (the objectify ones) fields?
I'm trying to use gson to do so but it seems several people online have had issues serializing appengine keys. Any tips?
When I attempt to do so I get the following error on deserialization:
java.lang.NullPointerException
at com.google.appengine.api.datastore.KeyTranslator.convertToPb(KeyTranslator.java:55)
at com.google.appengine.api.datastore.DataTypeTranslator$ReferenceType.setPropertyValue(DataTypeTranslator.java:680)
at com.google.appengine.api.datastore.DataTypeTranslator.createPropertyValue(DataTypeTranslator.java:207)
at com.google.appengine.api.datastore.DataTypeTranslator.createProperty(DataTypeTranslator.java:191)
at com.google.appengine.api.datastore.DataTypeTranslator.addProperty(DataTypeTranslator.java:159)
at com.google.appengine.api.datastore.DataTypeTranslator.addPropertiesToPb(DataTypeTranslator.java:142)
at com.google.appengine.api.datastore.EntityTranslator.convertToPb(EntityTranslator.java:47)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.doBatchPutBySize(AsyncDatastoreServiceImpl.java:475)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.put(AsyncDatastoreServiceImpl.java:446)
at com.googlecode.objectify.impl.AsyncObjectifyImpl.put(AsyncObjectifyImpl.java:255)
at com.googlecode.objectify.impl.AsyncObjectifyImpl.put(AsyncObjectifyImpl.java:229)
at com.googlecode.objectify.impl.ObjectifyImpl.put(ObjectifyImpl.java:126)
at com.rewardly.mailfoo.dataaccess.DAO.storeEntity(DAO.java:36)
at com.rewardly.mailfoo.ajaxcalls.UpdateEntity.doPost(UpdateEntity.java:38)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.rewardly.mailfoo.utils.UserFilter.doFilter(UserFilter.java:44)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:351)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我将其作为我的一个项目中备份套件的一部分完成。现在它对我来说绝对有效。
尝试通过其构建器对 Gson(反)序列化器对象进行专门化:
代码中的最终用法:
为了完整性:
在 Key 对象中也序列化了 GAE 应用程序
标识符。但可以通过key后反射来改变
如果需要,可以在反序列化方法中检索。可能需要
将数据从第一个 GAE 应用程序移动到另一个应用程序时。为我,
键中的应用程序标识符现在为空。如果不是为了你,
联系我。我将发布适当的代码。
此代码也适用于较旧的 Gson。如果使用 2.1,则 TypeAdapter
子类化会更好&更快的方式。它非常类似于
这段代码你需要实现2个方法。但这个解决方案
也适用于旧版本。
I have it done as part of the backup suite in one my project. It definitely WORKS for me now.
Try specialization of Gson (de)serializer object by its builder:
Final usage in code:
For completeness:
In the Key object there is serialized also GAE application
identificator. But it can be changed by reflection after key
retrieval in deserialization method, if needed. It may be required
when moving the data from the 1st GAE app to another one. For me,
the app identificator in keys are null right now. If not for you,
contact me. I will publish appropriate code.
This code works for older Gson also. If using 2.1, the TypeAdapter
subclassing would be better & faster way. It is quite similar to
this code and you need to implement 2 methods. But this solution
just works with also older versions.
我只需使用 Objectify 的内置
DAOBase.fact().stringToKey()
和DAOBase.fact().keyToString()
方法就可以解决这个问题。我自己的问题是由于必须在 Java 6 下编译而产生的,因为我一直在使用< 即可解决/代码>。
Key entityKey = new DAO().fact().stringToKey(serializedKey)
,只需将类型从更改为
但是,如果您需要序列化原始低级 Key 对象,则上述答案中提到的方法现在位于 KeyFactory 中而不是 Key 上。您仍然会遇到麻烦,因为 AppIdNamespace 是暂时的、私有的,并且没有方法可以在反序列化后的键上设置这些字段。
I was able to solve this problem by simply using Objectify's built-in
DAOBase.fact().stringToKey()
andDAOBase.fact().keyToString()
methods.My own problems arose from having to compile under Java 6, because I had been using
Key<?> entityKey = new DAO().fact().stringToKey(serializedKey)
, which was solved by simply changing the type from<?>
to<Entity>
.If, however, you need to serialize the raw low-level Key objects, the methods mentioned in the above answer are now located in KeyFactory instead of on Key. You will still have trouble because AppIdNamespace is transient, private, and there are no methods to set those fields on the key post-deserialization.