有没有办法在Servlet 3.x容器中运行Jersey servlet容器(2.x)无描述符作为javax.servlet.Filter
?我需要在我的服务旁边提供静态资源,因此需要使用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>
并在我的自定义Application
类
@ApplicationPath(value = "/")
public class MyApplication extends ResourceConfig
{
public MyApplication()
{
packages("com.foo.webservices.services");
property(ServletProperties.FILTER_FORWARD_ON_404, true);
}
}
官方文档(https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.3)并不包含任何有关过滤器的内容。
答案 0 :(得分:2)
可能,但不会像设置一些配置属性一样简单。如果您对它的实际工作原理有所了解,将会有所帮助。使用Servlet 3.x,引入了ServletContainerInitializer
,我们可以实现动态加载servlet(这将进一步讨论here)。泽西岛有一个它使用的实现。但它遵循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 Repo
中看到完整的示例