spring - 如何仅使用注释使用 Spring 配置 Jersey

标签 spring jersey

我有一个同时使用 Spring 和 Jersey 的 Servlet 3.0 Web 应用程序。我目前使用在 web.xml 中配置为过滤器的 SpringServlet 来设置它,并且资源类用 @Path 注释。和 @Component .这是 web.xml 片段:

<filter>
    <filter-name>jersey-serlvet</filter-name>
    <filter-class>
        com.sun.jersey.spi.spring.container.servlet.SpringServlet
    </filter-class>
    <init-param>
        <param-name>
            com.sun.jersey.config.property.packages
        </param-name>
        <param-value>com.foo;com.bar</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.config.feature.FilterForwardOn404</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>jersey-serlvet</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这个设置有效,但我真的想只用注释来设置这个 - 没有 web.xml 配置。我的第一次尝试是删除上面的 SpringServlet 配置并创建一个扩展 Application 的类。 .这是其中的一个片段:
@ApplicationPath("/*")
public class MyApplication extends PackagesResourceConfig {

    public MyApplication() {
        super("com.foo;com.bar");

        HashMap<String, Object> settings = new HashMap<String, Object>(1);
        settings.put(ServletContainer.FEATURE_FILTER_FORWARD_ON_404, true);
        this.setPropertiesAndFeatures(settings);
    }
}

这是因为 JAX-RS 资源已注册,我可以在它们的 URL 上点击它们,但是当它们尝试使用它们的 Autowiring 属性时,它们会抛出 NullPointerExceptions ......这是有道理的,因为我猜测资源现在正在被加载Jersey 并且不是 Spring 管理的 bean,因此没有 Autowiring 。

尽管进行了相当多的搜索,但我找不到任何将 Jersey 资源加载为仅带有注释的 Spring bean 的方法。有这样的方法吗?如果可以的话,我真的不想为资源编写一堆代码来手动获取 Spring 上下文并调用 DI。

如果仅注释不起作用,那么我可以使用 web.xml 中的过滤器配置,如果我可以指定 Application要加载的类而不是要扫描的包列表。如果我可以去掉里面的包列表,只指定一个 Application类实例然后我会满足。

显然,如果有人为我提供明确的答案会很棒,但我也很感激任何关于我可以查看或尝试的其他地方的指示或提示。

谢谢,
马特

最佳答案

下面是我的应用程序的一部分,它使用 Servlet 3.0、Spring、Jersey 1.8 并且没有 web.xml:

public class WebAppInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    context.setConfigLocation("com.myapp.config");

    final FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("characterEncodingFilter", new CharacterEncodingFilter());
    characterEncodingFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
    characterEncodingFilter.setInitParameter("encoding", "UTF-8");
    characterEncodingFilter.setInitParameter("forceEncoding", "true");

    final FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
    springSecurityFilterChain.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");

    servletContext.addListener(new ContextLoaderListener(context));
    servletContext.setInitParameter("spring.profiles.default", "production");

    final SpringServlet servlet = new SpringServlet();

    final ServletRegistration.Dynamic appServlet = servletContext.addServlet("appServlet", servlet);
    appServlet.setInitParameter("com.sun.jersey.config.property.packages", "com.myapp.api");
    appServlet.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", "com.myapp.api.SizeLimitFilter");
    appServlet.setLoadOnStartup(1);

    final Set<String> mappingConflicts = appServlet.addMapping("/api/*");

    if (!mappingConflicts.isEmpty()) {
        throw new IllegalStateException("'appServlet' cannot be mapped to '/' under Tomcat versions <= 7.0.14");
    }
}

}

关于spring - 如何仅使用注释使用 Spring 配置 Jersey,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14722029/

相关文章:

java - 解析媒体类型时出错 'application/json;encoding=utf8, charset=utf-8'

spring - 单例 vs 原型(prototype) JdbcTemplate

java - Java Firebase 管理与 Jersey 兼容吗?

java - Jersey JSON 支持不起作用

javascript - Access-Control-Allow-Origin 在 AngularJS 应用程序中不起作用

http - EntityTag - 值(value),缓存,比较 - 如何在 Jersey

java - 指定用户过滤器时出现 NoClassDefFoundError

java - Freemarker 日期分配看似有效日期失败

java - 为什么@transactional注解不建议与select操作一起使用

java - 在Testcontainers中使用自定义DB docker-image