我是 GCM 服务的新手。我基本上已经将示例代码复制到了我在appspot.com 上托管的服务器应用程序中。当我尝试为空参数发送消息时出现错误,但我不知道是哪一个。以下是来自appspot.com 的日志:
2012-07-20 14:57:11.042 /sendMessage 500 8ms 0kb AppEngine-Google; (+http://code.google.com/appengine)
0.1.0.2 - - [20/Jul/2012:14:57:11 -0700] "POST /sendMessage HTTP/1.1" 500 0 "http://mouseworldgcm.appspot.com/sendAll" "AppEngine-Google; (+http://code.google.com/appengine)" "mouseworldgcm.appspot.com" ms=9 cpu_ms=23 api_cpu_ms=0 cpm_usd=0.000708 queue_name=gcm task_name=3983469213642671348 instance=00c61b117c1533caf348700f9435ffa04e7119
C 2012-07-20 14:57:11.040
Uncaught exception from servlet
javax.servlet.UnavailableException: java.lang.IllegalArgumentException: argument cannot be null
at org.mortbay.jetty.servlet.ServletHolder.makeUnavailable(ServletHolder.java:415)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:458)
at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:202)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:171)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:123)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:477)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:449)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:455)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:695)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:333)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:325)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:453)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
at java.lang.Thread.run(Thread.java:679
这是 /sendAll servlet:
package com.joebutt.mouseworldgcm;
import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import java.io.IOException;
import java.util.List;
//import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet that adds a new message to all registered devices.
* <p>
* This servlet is used just by the browser (i.e., not device).
*/
@SuppressWarnings("serial")
public class SendAllMessagesServlet extends BaseServlet {
/**
* Processes the request to add a new message.
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
List<String> devices = Datastore.getDevices();
String status;
if (devices.isEmpty())
{
status = "Message ignored as there is no device registered!";
}
else
{
Queue queue = QueueFactory.getQueue("gcm");
// NOTE: check below is for demonstration purposes; a real application
// could always send a multicast, even for just one recipient
if (devices.size() == 1) {
// send a single message using plain post
String device = devices.get(0);
queue.add(withUrl("/sendMessage").param(SendMessageServlet.PARAMETER_DEVICE, device));
status = "Single message queued for registration id " + device;
} else {
// send a multicast message using JSON
String key = Datastore.createMulticast(devices);
queue.add(withUrl("/sendMessage").param(SendMessageServlet.PARAMETER_MULTICAST, key));
status = "Multicast message queued for " + devices.size() + " devices";
}
req.setAttribute(HomeServlet.ATTRIBUTE_STATUS, status.toString());
getServletContext().getRequestDispatcher("/home").forward(req, resp);
}
}
}
因此,在整个周末工作后,我确定空错误是由于发件人造成的。因此,我将其更改为其他文档中的标准类型。现在的问题是我得到一个 401 错误代码。我因此重置了我的 api 密钥并尝试了浏览器应用程序和服务器 api 密钥,两者仍然抛出 401 错误。
关于如何创建发件人的任何建议????
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
//sender = newSender(config); //this is the line I changed
sender = new Sender(ApiKeyInitializer.ATTRIBUTE_ACCESS_KEY);
}
/**
* Creates the {@link Sender} based on the servlet settings.
*/
protected Sender newSender(ServletConfig config) {
String key = (String) config.getServletContext()
.getAttribute(ApiKeyInitializer.ATTRIBUTE_ACCESS_KEY);
return new Sender(key);
}