Android 6中Jetty 7服务器出现System.err异常的排查咨询
我最近在Android 6系统上部署了Jetty 7服务器(版本7.6.21.v20160908),主要用来监听自定义的HTTP请求方法,功能本身能正常工作,但每次运行时ADB日志里都会出现一条奇怪的System.err异常,而且相关的报错信息特别少。下面是我的相关代码、配置和日志,想请教下这个异常到底是什么原因导致的?
Build.gradle依赖配置
dependencies { implementation 'org.eclipse.jetty:jetty-webapp:7.6.21.v20160908' // 项目其他依赖 }
自定义请求处理器核心代码
public class CustomMethodHandler extends AbstractHandler { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String method = request.getMethod(); // 处理自定义HTTP方法逻辑 if ("MY_CUSTOM_METHOD".equals(method)) { response.setStatus(HttpServletResponse.SC_OK); response.getWriter().write("Custom method handled successfully"); baseRequest.setHandled(true); } } }
完整MainActivity代码
public class MainActivity extends AppCompatActivity { private Server jettyServer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startJettyServer(); } private void startJettyServer() { jettyServer = new Server(8080); WebAppContext webAppContext = new WebAppContext(); webAppContext.setContextPath("/"); webAppContext.setResourceBase(getFilesDir().getAbsolutePath()); jettyServer.setHandler(webAppContext); // 注册自定义请求处理器 webAppContext.addHandler(new CustomMethodHandler()); try { jettyServer.start(); Log.d("JettyServer", "Server started on port 8080"); } catch (Exception e) { Log.e("JettyServer", "Failed to start Jetty server", e); } } @Override protected void onDestroy() { super.onDestroy(); if (jettyServer != null && jettyServer.isStarted()) { try { jettyServer.stop(); } catch (Exception e) { Log.e("JettyServer", "Failed to stop Jetty server", e); } } } }
ADB日志片段
W/System.err: javax.servlet.ServletException: No servlet to handle request for /
W/System.err: at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:594)
W/System.err: at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
W/System.err: at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
W/System.err: ...(剩余日志省略)
异常原因解析
其实这个异常并不是你的自定义HTTP方法处理逻辑出了问题——毕竟你说功能能正常运行。它的根源是:Jetty的ServletHandler在接收到访问根路径/的请求时,找不到对应的Servlet或Handler来处理,所以抛出了这个ServletException并打印到System.err。
出现这个情况的可能场景:
- Jetty启动后可能有内部的默认请求访问根路径做检查
- 你可能在测试时用普通GET/POST请求访问了
http://localhost:8080/,但你的自定义Handler只处理特定的自定义方法,没有覆盖根路径的普通请求
而你的自定义Handler只针对MY_CUSTOM_METHOD这个特定方法做处理,对于其他访问根路径的请求,没有对应的处理逻辑,所以Jetty就会抛出这个异常。
解决办法
你可以通过以下两种方式消除这个异常:
为根路径添加默认Handler
在现有代码中添加一个处理根路径请求的Handler,覆盖所有未匹配的请求:webAppContext.addHandler(new AbstractHandler() { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { // 处理根路径请求 if ("/".equals(target)) { response.setStatus(HttpServletResponse.SC_OK); response.getWriter().write("Jetty server is running on Android 6"); baseRequest.setHandled(true); } } });配置默认Servlet映射
直接给Jetty的WebAppContext添加一个默认Servlet,映射到根路径:ServletHolder defaultServletHolder = new ServletHolder("default", DefaultServlet.class); webAppContext.addServlet(defaultServletHolder, "/");
这两种方式都能让Jetty找到根路径请求的处理逻辑,不会再抛出这个异常,同时完全不影响你自定义HTTP方法的功能。
内容的提问来源于stack exchange,提问作者arjun

