gpt4 book ai didi

java - 无描述符 Jersey Servlet 容器在 Servlet 3.x 容器中作为过滤器运行

转载 作者:行者123 更新时间:2023-11-30 07:58:50 25 4
gpt4 key购买 nike

有没有办法在 Servlet 3.x 容器中将 Jersey Servlet 容器 (2.x) 无描述符运行为 javax.servlet.Filter ?我需要与我的服务一起提供静态资源,因此需要使用仅有效的 jersey.config.servlet.filter.forwardOn404jersey.config.servlet.filter.staticContentRegex当根据 Javadoc 作为过滤器运行时

The property is only applicable when Jersey servlet container is configured to run as a javax.servlet.Filter, otherwise this property will be ignored.

我想完全删除 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 ) 没有说明任何有关过滤器的内容。

最佳答案

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

我们可以编写自己的 ServletContainerInitializer 或者直接利用 Jersey 的。 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);
}

一旦我们实现了,我们需要创建一个文件

META-INF/services/org.glassfish.jersey.servlet.internal.spi.ServletContainerProvider

它应该位于类路径的根目录下。该文件的内容应该是我们实现的完全限定名称。

您可以在 GitHub Repo 中看到完整的示例

关于java - 无描述符 Jersey Servlet 容器在 Servlet 3.x 容器中作为过滤器运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40042871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com