【问题标题】:JAX-RS: How to extend Application class to scan packages?JAX-RS:如何扩展应用程序类来扫描包?
【发布时间】:2014-12-29 19:36:17
【问题描述】:

目前,我正在做类似的事情

import javax.annotation.Nonnull;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@ApplicationPath("oauth")
public class OAuthApplication extends Application {
    final Set<Class<?>> classes = new HashSet<>();

    @Nonnull
    @Override
    public Set<Class<?>> getClasses() {
        classes.add(RegisterResource.class);
        return Collections.unmodifiableSet(classes);
    }
}

不,如果我在ApplicationPath 上添加十个新的Resources,我需要这样做

    classes.add(<ClassName>.class);

十次,这很乏味,有时也很健忘。

JAX-RSRESTEasy 是否提供了让我可以提及包名和在其下扫描类的方式?

我知道Jersey 有点像

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        packages("org.foo.rest;org.bar.rest");
    }
}

Reference

有什么想法/想法吗?

更新

看来我们可以关注web.xml

   <context-param>
      <param-name>resteasy.scan</param-name>
      <param-value>true</param-value>
   </context-param>

是否有特定的 Java 等效项?

【问题讨论】:

    标签: java rest jersey jax-rs resteasy


    【解决方案1】:

    “是否有特定的 Java 等价物?”

    只需将类留空,这意味着不要覆盖 getClasses()getSingletons()Per the spec - 2.3.2:

    [...]

    在后两种情况下,如果Application.getClassesApplication.getSingletons 都返回一个空列表,那么打包在Web 应用程序中的所有根资源类和提供程序必须包含在已发布的JAX-RS 应用程序中。如果 getClassesgetSingletons 返回非空列表,则只有返回的那些类或单例必须包含在已发布的 JAX-RS 应用程序中。

    所以你可以简单地做

    @ApplicationPath("oauth")
    public class OAuthApplication extends Application {}
    

    您的类路径将被扫描@Path@Provider 类。覆盖任一方法(返回非空集),只会添加那些类。

    还应注意public Map&lt;String, Object&gt; getProperties() 可以安全地被覆盖。您可以使用它添加任意属性(甚至注册类/功能),如seen here,或者如果您需要配置提供程序,您可以在FeatureDynamicFeature 中这样做seen here

    【讨论】:

    • 也许这应该是一个单独的问题,但我发现,使用此处建议的解决方案,我的 JAX-RS 应用程序不会自动获取一些位于单独 EJB 中的已注册 ExceptionMapper 提供程序EAR 中的包,其中还包含 WAR。我宁愿不必像 OP 所指示的那样显式添加每个类,但确实需要 Jersey 提供的那种“添加包”快捷方式,但仍然找不到使用 RESTEasy 的方法。有什么想法吗?
    • 似乎我需要一个不同的问题,因为在重写的 getClasses() 方法中显式添加所有类实际上也不起作用。也不会将它们注册为功能。这些 ExceptionMapper 提供程序一定有什么特别之处。嗯……
    • 取得了一点进展...... Wildfly 日志表明似乎没有正确处理的异常之一是 EJBException: ERROR [io.undertow.request] (default task-121) UT005023 :对/rest/authenticate的异常处理请求:org.jboss.resteasy.spi.UnhandledException:javax.ejb.EJBException:io.jsonwebtoken.ExpiredJwtException。为 EJBException 添加 ExceptionMapper 确实允许我处理此异常,但我不完全理解为什么会发生这种情况,因为我的 EJB 包(而不是 WAR)中抛出的 ExpiredJwtException 没有出现此问题。
    • 最后,我的问题是由于容器如何将未检查的(系统)异常包装在 EJBException 中(请参阅stackoverflow.com/a/19563956/304620)。就我而言,解决方案是在 ejb-jar.xml 中表示 io.jsonwebtoken.ExpiredJwtException 以使其成为应用程序(已检查)异常。
    【解决方案2】:

    是所有Application类、ResourceClass和@ApplicationPath的组合

    按照docsResourceConfig的类实现的方式是:

    @ApplicationPath(value = "/resource")
    public class ApplicationREST extends ResourceConfig {
    
        public ApplicationREST() {
            //add single resources
            register(SimpleResource1.class);
            register(SimpleResource2.class);
            ...
    
            //enable multipar feature
            register(MultiPartFeature.class);
            ...            
    
            //enable scan package and recursive
            packages(true, "com.example.rest");
        }
    }
    

    希望对你有帮助

    【讨论】:

    • 我使用了它,但起初它给了我 500 的未注册 MultiPartFeature,注册后它给了我所有 API 的 404。有什么想法吗?
    【解决方案3】:

    很简单:

    import javax.ws.rs.ApplicationPath;
    import javax.ws.rs.core.Application;
    
    @ApplicationPath("/webapi")
    public class MyApp extends Application {
    
    }
    

    这将扫描所有使用@Provider 和@Path 注释的类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多