Jetty 12混合Handler范式与EE8 Servlet遇404问题求助
解决Jetty 12迁移中JasperReports ImageServlet 404问题及EE8源码位置说明
一、404错误的核心原因
你当前的配置错误在于将ServletContextHandler直接加入Handler.Sequence,但未正确配置上下文路径匹配:
adminContextHandler的上下文路径是/admin,而jasperServletContextHandler未设置上下文路径,导致其内部的/reports/image映射是相对于根路径(/)的,无法匹配请求/admin/reports/image。- Jetty 12中EE8的Servlet容器组件与原生Handler的上下文处理逻辑独立,直接混合会导致路径映射不生效。
二、正确的配置方案
方案1:在原生Handler序列中集成EE8 ServletHandler(推荐,共享Session)
直接使用ServletHandler替代ServletContextHandler,将其加入adminHandlers序列,这样Servlet映射会继承/admin的上下文路径:
Server httpServer = ... ContextHandler adminContextHandler = new ContextHandler("/admin"); SessionHandler sessionHandler = new SessionHandler(); adminContextHandler.setHandler(sessionHandler); Handler.Sequence adminHandlers = new Handler.Sequence(); sessionHandler.setHandler(adminHandlers); // 原生PathMappingsHandler配置 PathMappingsHandler adminHandler = new PathMappingsHandler(); adminHandlers.addHandler(adminHandler); // 替换ServletContextHandler为ServletHandler ServletHandler jasperServletHandler = new ServletHandler(); // 添加ImageServlet映射,路径相对于/admin上下文 ServletHolder imageServletHolder = jasperServletHandler.addServlet(ImageServlet.class); imageServletHolder.addMapping("/reports/image"); // 将ServletHandler加入序列 adminHandlers.addHandler(jasperServletHandler); // 上下文集合配置 ContextHandlerCollection contextCollection = new ContextHandlerCollection(adminContextHandler, ...); httpServer.setHandler(contextCollection);
方案2:独立配置ServletContextHandler(独立上下文,Session不共享)
将ServletContextHandler作为独立上下文加入ContextHandlerCollection,并设置匹配的上下文路径:
Server httpServer = ... ContextHandler adminContextHandler = new ContextHandler("/admin"); // adminContextHandler的原有配置... // 配置Jasper的ServletContextHandler ServletContextHandler jasperServletContextHandler = new ServletContextHandler(); // 设置上下文路径为/admin/reports,匹配请求前缀 jasperServletContextHandler.setContextPath("/admin/reports"); ServletHolder imageServletHolder = jasperServletContextHandler.addServlet(ImageServlet.class); // 映射路径改为/image,对应请求/admin/reports/image imageServletHolder.addMapping("/image"); // 将两个上下文都加入集合 ContextHandlerCollection contextCollection = new ContextHandlerCollection(adminContextHandler, jasperServletContextHandler, ...); httpServer.setHandler(contextCollection);
注意:方案2中两个上下文的Session是独立的,如果报表生成和图片请求需要共享Session,优先选择方案1。
三、Jetty EE8源码位置说明
Jetty 12的EE8模块源码位于Jetty项目根目录下的jetty-ee8文件夹中,包含jetty-ee8-servlet、jetty-ee8-webapp等子模块,你可以直接在Jetty的GitHub仓库中找到该目录。
内容的提问来源于stack exchange,提问作者Bruno Konik
相关产品推荐
相关产品推荐

