Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无描述符的servlet容器在servlet 3.x容器中作为过滤器运行_Java_Jersey - Fatal编程技术网

Java 无描述符的servlet容器在servlet 3.x容器中作为过滤器运行

Java 无描述符的servlet容器在servlet 3.x容器中作为过滤器运行,java,jersey,Java,Jersey,有没有办法在Servlet3.x容器中以javax.servlet.Filter的形式运行Jersey servlet容器(2.x)描述符?我需要在提供服务的同时提供静态资源,因此需要使用jersey.config.servlet.filter.forwardOn404或jersey.config.servlet.filter.staticContentRegex,它们仅在根据Javadoc作为过滤器运行时才起作用 该属性仅在Jersey servlet容器配置为作为javax.servlet.

有没有办法在Servlet3.x容器中以
javax.servlet.Filter
的形式运行Jersey servlet容器(2.x)描述符?我需要在提供服务的同时提供静态资源,因此需要使用
jersey.config.servlet.filter.forwardOn404
jersey.config.servlet.filter.staticContentRegex
,它们仅在根据Javadoc作为过滤器运行时才起作用

该属性仅在Jersey servlet容器配置为作为javax.servlet.Filter运行时适用,否则将忽略该属性

我想彻底摆脱
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
            http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
    <display-name>My-Webservice</display-name>

    <filter>
        <filter-name>Jersey Filter</filter-name>
        <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.foo.webservices.MyApplication</param-value>
        </init-param>
    </filter>
</web-app>
遗憾的是,官方文档()没有说明任何有关过滤器的内容。

这是可能的,但不会像设置一些配置属性那样简单。如果你能稍微了解一下它的实际工作原理,这会有所帮助。在Servlet3.x中,引入了一个
ServletContainerInitializer
,我们可以实现它来动态加载Servlet(这将进一步讨论)。Jersey有一个它使用的实现。但它遵循JAX-RS,即应用程序应作为servlet加载。所以泽西并没有提供任何方法来解决这个问题

我们可以编写自己的
ServletContainerInitializer
,也可以直接访问Jersey的。泽西岛有一个我们可以实现的
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);
}
它应该位于类路径的根。该文件的内容应该是我们实现的完全限定名


您可以在这个

中看到一个完整的示例。非常好的答案,谢谢。我不得不在getApplicationClass方法中添加另一个检查,因为它错误地将
org.glassfish.jersey.server.ResourceConfig$RuntimeConfig
标识为应用程序类。我刚刚在
break
语句周围添加了
if(applicationCls!=null&&applicationCls.getAnnotation(ApplicationPath.class)!=null)
@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