由于缺少实体密钥的appId,GAE端点抛出了JsonMappingException

时间:2014-04-06 09:16:18

标签: android google-app-engine google-cloud-endpoints

我正在使用GAE端点,以Android为客户端。我有一个API抛出由JsonMappingException引起的HTTP代码503(服务不可用),这显然是由于缺少子实体的appId。

@PersistenceCapable
public class AppUser implements Serializable {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;

@Persistent
private String username;

@Persistent
@Unowned
private Set<AppGroup> assignedGroups;

    // getters setters here
}

Endpoint API

public AppGroup retrieveRandomGroup(AppUser appUser) {
    Set<AppGroup> groups = appUser.getAssignedGroups();
    // choose random group assigned to this user
    Random random = new Random();
    int chosenIndex = random.nextInt(groups.size());
    AppGroup randomGroup = (AppGroup) groups.toArray()[chosenIndex];
    logger.log(Level.INFO, "Randomly choosing index: "+chosenIndex+", name:"+randomGroup.getName());
    return randomGroup;
}

当Android客户端发送请求时,它已正确处理。我知道这是因为我可以在INFO级别看到我打印的消息。但是,当引擎尝试发送响应时,发生了JsonMappingException:

java.io.IOException: com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.what2eat.bean.EatingPlace["key"]->com.google.appengine.api.datastore.Key["appId"])
at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAsString(ServletResponseResultWriter.java:187)
at com.google.api.server.spi.response.ServletResponseResultWriter.write(ServletResponseResultWriter.java:73)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:386)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:124)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:82)
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.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
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 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.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266)
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.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:188)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.NullPointerException
at com.google.appengine.api.datastore.Key.getAppId(Key.java:280)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:45)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:483)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:418)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ObjectWriter._configAndWriteValue(ObjectWriter.java:456)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ObjectWriter.writeValueAsString(ObjectWriter.java:393)
at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAsString(ServletResponseResultWriter.java:183)
at com.google.api.server.spi.response.ServletResponseResultWriter.write(ServletResponseResultWriter.java:73)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:386)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:124)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:82)
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)...(length 9875)

我检查客户端中的AppUser对象(在发送请求之前),并且密钥和密钥的appId存在。 我在接收AppUser参数时打印出一些额外的调试,以输出AppUser的密钥和密钥的appId。键有一个值,但调用key.getAppId()会抛出空指针异常。

有谁知道什么是错的? 这是密钥序列化/反序列化的问题吗?

1 个答案:

答案 0 :(得分:0)

Key类中的getAppId()方法执行以下操作:

   public String getAppId() {
    return appIdNamespace.getAppId();
  }

在您的情况下,appIdNamespace很可能为null,这会导致错误。确保已从数据存储中检索您的appUser,以便正确设置组密钥。如果在代码中生成了这些键,请使用KeyFactory.createKey方法,该方法将为您生成appIdNamespace。