It's possible,但不会像设置一些配置属性那么简单。如果您了解一点它的实际工作原理,将会有所帮助。在 Servlet 3.x 中,引入了ServletContainerInitializer
我们可以实现动态加载 servlet(这将进一步讨论here https://stackoverflow.com/a/29730471/2587435)。 Jersey 有一个它使用的实现。但它遵循 JAX-RS,其中规定应用程序应作为 servlet 加载。所以泽西岛没有提供任何解决这个问题的方法。
我们可以自己写ServletContainerInitializer
或者我们可以直接进入泽西岛。泽西岛有一个SerletContainerProvider
我们可以实施。我们需要自己注册 servlet 过滤器。实现看起来像这样
@Override
public void preInit(ServletContext context, Set<Class<?>> classes) throws ServletException {
final Class<? extends Application> applicationCls = getApplicationClass(classes);
if (applicationCls != null) {
final ApplicationPath appPath = applicationCls.getAnnotation(ApplicationPath.class);
if (appPath == null) {
LOGGER.warning("Application class is not annotated with ApplicationPath");
return;
}
final String mapping = createMappingPath(appPath);
addFilter(context, applicationCls, classes, mapping);
// to stop Jersey servlet initializer from trying to register another servlet
classes.remove(applicationCls);
}
}
private static void addFilter(ServletContext context, Class<? extends Application> cls,
Set<Class<?>> classes, String mapping) {
final ResourceConfig resourceConfig = ResourceConfig.forApplicationClass(cls, classes);
final ServletContainer filter = new ServletContainer(resourceConfig);
final FilterRegistration.Dynamic registration = context.addFilter(cls.getName(), filter);
registration.addMappingForUrlPatterns(null, true, mapping);
registration.setAsyncSupported(true);
}
一旦我们实现了,我们需要创建一个文件
META-INF/services/org.glassfish.jersey.servlet.internal.spi.ServletContainerProvider
它应该位于类路径的根部。该文件的内容应该是我们实现的完全限定名称。
您可以在此处查看完整的示例GitHub 存储库 https://github.com/psamsotha/jersey-web-initializer