我在本地计算机上运行时发现代码行为不一致。 AWS Elastic Beanstalk。该代码将接收Google Glass的通知。
代码段如下所示:
public class NotifyServlet extends HttpServlet implements WeiboConstants{
private static final Logger LOG = Logger.getLogger(NotifyServlet.class.getSimpleName());
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Respond with OK and status 200 in a timely fashion to prevent redelivery
response.setContentType("text/html");
Writer writer = response.getWriter();
writer.append("OK");
writer.close();
LOG.info("perpare reading");
BufferedReader notificationReader =
new BufferedReader(new InputStreamReader(request.getInputStream()));
String notificationString = "";
LOG.info("begin reading ");
// Count the lines as a very basic way to prevent Denial of Service attacks
int lines = 0;
while (notificationReader.ready()) {
LOG.info("reading");
notificationString += notificationReader.readLine();
lines++;
// No notification would ever be this long. Something is very wrong.
if (lines > 1000) {
throw new IOException("Attempted to parse notification payload that was unexpectedly long.");
}
}
LOG.info("got raw notification " + notificationString);
JsonFactory jsonFactory = new JacksonFactory();
Google的服务器将执行POST,这是单独注册的:
Subscription subscription = MirrorClient.insertSubscription(credential, "https://mirrornotifications.appspot.com/forward?url=http://foo.elasticbeanstalk.com/notify", userId,
"timeline");
在我的本地计算机上进行测试时,我运行 mvn jetty:运行并将上述代码中的foo
更改为my ip address:8080
。
我可以收到谷歌的通知:
{“collection”:“timeline”,“itemId”:“5cbf8f54-822d-4a8e-9a9f-508687bbb9e2”,“operation”:“INSERT”,“userToken”:“105242333117256730066”,“userActions”:[{ “type”:“LAUNCH”}]}
但是当我打包战争(mvn war:war)并部署到AWS时,我可以从日志中看到它已成功注册到Google,我从Google获得 POST 在/ notify上,但似乎正文是空的,如下面的日志所示:
Dec 06, 2013 5:01:55 AM com.google.glassware.NotifyServlet doPost
INFO: perpare reading
Dec 06, 2013 5:01:55 AM com.google.glassware.NotifyServlet doPost
INFO: begin reading
Dec 06, 2013 5:01:55 AM com.google.glassware.NotifyServlet doPost
INFO: got raw notification
Dec 06, 2013 5:01:55 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [notify] in context with path [] threw exception
java.lang.IllegalArgumentException: no JSON input found
如何进一步调试?
更新
我将相同的war文件部署到运行Jetty而不是Tomcat的服务器上,它运行正常,似乎是Tomcat特有的问题?
答案 0 :(得分:0)
要进一步调试,您可以尝试将通知直接发布到http://foo.elasticbeanstalk.com/notify
如果这导致相同的行为,我会仔细查看BufferedReader.ready()
作为循环条件。
ready()
是一种非阻塞方法。这意味着如果由于某种原因BufferedReader
的实例没有准备好立即返回数据,那么该方法将立即返回false并且将完全跳过循环。
然后调试的下一步是注释ready()
并直接阻止readLine()
以确认您的servlet收到有效负载。
<强>更新强>
看来Jetty和Tomcat确实有不同的BufferedReader.ready()实现。
以下是我在进一步研究后发现的相关Stack Overflow问题:BufferedReader ready method