我想构建一个真正简单的示例,用于在嵌入式 Jetty 服务器中调用异步 servlet。当我尝试从请求的 AsyncContext 启动 Runnable 时,我收到 NullPointerException。 这是服务器代码:
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
ServletHolder holder = handler.addServletWithMapping(AsyncServlet.class, "/*");
holder.setAsyncSupported(true);
server.start();
server.join();
}
这是 servlet 代码:
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
final AsyncContext ctxt = req.startAsync();
ctxt.start(() -> {
ctxt.complete();
});
}
这是堆栈跟踪的错误:
java.lang.NullPointerException
at org.eclipse.jetty.server.AsyncContextState$2.run(AsyncContextState.java:168)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:540)
at java.lang.Thread.run(Thread.java:745)
也许服务器需要任何额外的配置。有什么建议吗?
补充:相同的 servlet 在嵌入式 tomcat 中运行,无需任何更改。
最佳答案
不要直接使用 ServletHandler
,它是 ServletContextHandler
创建/使用/管理的内部类。
这是对示例的修改,它正确设置了 servlet 上下文。
package jetty;
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class EmbeddedAsyncServer
{
public static class EmbeddedAsyncServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
final AsyncContext ctxt = req.startAsync();
ctxt.start(new Runnable()
{
@Override
public void run()
{
System.err.println("In AsyncContext / Start / Runnable / run");
ctxt.complete();
}
});
}
}
public static void main(String[] args) throws Exception
{
Server server = new Server(9090);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
ServletHolder asyncHolder = context.addServlet(EmbeddedAsyncServlet.class,"/async");
asyncHolder.setAsyncSupported(true);
server.setHandler(context);
server.start();
server.join();
}
}
访问http://localhost:9090/async
,您将看到以下输出
2014-12-29 13:18:57.075:INFO::main: Logging initialized @69ms
2014-12-29 13:18:57.131:INFO:oejs.Server:main: jetty-9.2.6.v20141205
2014-12-29 13:18:57.156:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@65123c41{/,null,AVAILABLE}
2014-12-29 13:18:57.169:INFO:oejs.ServerConnector:main: Started ServerConnector@722b302{HTTP/1.1}{0.0.0.0:9090}
2014-12-29 13:18:57.169:INFO:oejs.Server:main: Started @166ms
In AsyncContext / Start / Runnable / run
关于servlets - 带有嵌入式 Jetty 的异步 Servlet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27679901/