1

我是 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);
  }
4

0 回答 0