JAX-RS: How to extend Application class to scan pa

2019-06-16 01:32发布

问题:

Currently, I do something similar to

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);
    }
}

No if I add ten new Resources on the ApplicationPath, I need to do

    classes.add(<ClassName>.class);

ten times, it is tedious and sometimes forgetful as well.

Does JAX-RS or RESTEasy provide the way so that I can mention the package name and classes are scanned under it?

I know Jersey has something as

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

Reference

Any thoughts/ideas?

UPDATE

Seems we can do following in web.xml

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

Is there a specific Java equivalent?

回答1:

"Is there a specific Java equivalent?"

Simply leave the class empty, meaning do not override getClasses() or getSingletons(). Per the spec - 2.3.2:

[...]

In either of the latter two cases, if both Application.getClasses and Application.getSingletons return an empty list then all root resource classes and providers packaged in the web application MUST be included in the published JAX-RS application. If either getClasses or getSingletons return a non-empty list then only those classes or singletons returned MUST be included in the published JAX-RS application.

So you can simply do

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

and your classpath will get scanned for @Path and @Provider classes. Override either method (returning a non-empty set), and only those classes will be added.

It should also be noted that public Map<String, Object> getProperties() can be safely overridden. You can use this to add arbitrary properties (even to register classes/features), as seen here, or if you need to configure a provider, you can do so in a Feature or DynamicFeature as seen here



回答2:

Is a combination of all Application class, ResourceClass and @ApplicationPath

in agreement with the docs and the class ResourceConfig implements by jersey the way to do is:

@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");
    }
}

I hope this helps you



回答3:

It is very simple:

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/webapi")
public class MyApp extends Application {

}

This will scan all the classes annotated with @Provider and @Path.