92 votes

En quoi consiste exactement la classe ResourceConfig dans Jersey 2?

J'ai vu beaucoup de Maillot de tutoriels qui commence avec quelque chose comme

@ApplicationPath("services")
public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        packages("com.abc.jersey.services");
    }
}

sans expliquer ce qu'est exactement l' ResourceConfig classe. Alors, où puis-je trouver de la documentation, de l'utilisation, etc.? Googler "jersey resourceconfig" ne donne aucun officiel doc.

Certaines de mes questions sur cette classe et son utilisation sont:

  • Quelles sont les choses que je peux faire à l'intérieur de la sous-classe d' ResourceConfig?
  • Dois-je m'inscrire à la sous-classe d' ResourceConfig quelque part afin qu'il puisse être trouvé ou il est automatiquement détecté par Jersey?
  • Si la sous-classe est automatiquement détecté ce qui se passe si j'ai plusieurs sous-classes de ResourceConfig?
  • Est le but de l' ResourceConfig le même que l' web.xml le fichier? Si donc ce qui arrive si j'ai les deux dans mon projet? Ne l'un d'eux l'emporte sur l'autre?

227voto

peeskillet Points 32287

Standard de JAX-RS utilise un Application de configuration de la classe. ResourceConfig s'étend Application.

Il existe trois principales façons différentes (dans un conteneur de servlet) pour configurer Jersey (JAX-RS):

  1. Avec seulement web.xml
  2. Avec les deux web.xml et un Application/ResourceConfig classe
  3. Avec seulement un Application/ResourceConfig classe annotée avec l' @ApplicationPath.

Avec seulement web.xml

Il est possible de configurer l'application d'une norme de JAX-RS, mais la suivante est spécifique à Jersey

<web-app>
    <servlet>
        <servlet-name>jersey-servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.mypackage.to.scan</param-value>
        </init-param>
    </servlet>
    ...
    <servlet-mapping>
        <servlet-name>jersey-servlet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
    ...
</web-app>

Depuis Jersey s'exécute dans un conteneur de servlet, il est juste que le Maillot de l'application s'exécute en tant que servlet. Le Maillot de Servlet qui gère les demandes entrantes est l' ServletContainer. Donc, ici, nous le déclarons que l' <servlet-class>. Nous avons également configurer un <init-param> dire d'un Maillot de paquet(s) à analyser pour notre @Path et @Provider classes, donc il peut les enregistrer.

Sous le capot, Jersey va réellement créer un ResourceConfig instance, que c'est ce qu'il utilise pour configurer l'application. Ensuite, il va enregistrer toutes les classes que l'on découvre à travers le package d'analyse.

Avec les deux web.xml et Application/ResourceConfig

Si nous voulons de programmation pour configurer notre application avec un Application ou ResourceConfig sous-classe, on peut le faire avec un seul changement à la ci-dessus web.xml. Au lieu de définir une init-param pour scanner les colis, nous utilisons un init-param pour déclarer notre Application/ResourceConfig sous-classe.

<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.example.JerseyApplication</param-value>
    </init-param>
    <servlet-mapping>
        <servlet-name>jersey-servlet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
</servlet>
package com.example;

public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        packages("com.abc.jersey.services");
    }
}

Ici, nous allons configurer le init-param javax.ws.rs.Application avec le nom pleinement qualifié de notre - ResourceConfig sous-classe. Et au lieu d'utiliser l' init-param qui dit Maillot de paquet(s) à analyser, nous utiliserons la méthode de convenance packages() de la ResourceConfig.

Nous pourrions également utiliser les méthodes register() et property() d'inscrire les ressources et les fournisseurs, et de configurer Jersey propriétés. Avec l' property() méthode, tout ce qui peut être configuré comme un init-param, peut également être configuré à l'aide de l' property() méthode. Par exemple, au lieu d'appeler packages(), nous pourrions le faire

public JerseyApplication() {
    property("jersey.config.server.provider.packages",
             "com.mypackage.to.scan");
}

Avec seulement Application/ResourceConfig

Sans web.xml Jersey besoin d'un moyen pour nous de fournir le servlet-mapping. Nous le faisons avec l' @ApplicationPath d'annotation.

// 'services', '/services', or '/services/*'
// is all the same. Jersey will change it to be '/services/*'
@ApplicationPath("services")
public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        packages("com.abc.jersey.services");
    }
}

Ici avec l' @ApplicationPath, c'est comme si nous avons configuré le servlet de la cartographie dans les web.xml

<servlet-mapping>
    <servlet-name>JerseyApplication</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>

En utilisant uniquement du code Java pour la configuration, il doit y avoir un moyen pour le Jersey à découvrir notre classe de configuration. Cela se fait avec l'utilisation d'un ServletContanerInitializer. C'est quelque chose qui a été introduit dans la Servlet 3.0 Spécification, de sorte que nous ne pouvons pas utiliser Java "seulement" dans la configuration antérieure des conteneurs de servlet.

Essentiellement ce qui se passe est que le réalisateur de l'initialiseur peut dire le conteneur de servlet quelles classes de chercher, et le conteneur de servlet va passer ces classes à l'initialiseur onStartup() méthode. En Jersey de mise en œuvre de l'initialiseur, Maillot configure à la recherche de Application classes et les classes annotées avec @ApplicationPath. Voir ce post pour plus d'explications. Ainsi, lorsque le conteneur de servlet démarre l'application, de Jersey, de l'initialiseur sera adopté notre Application/ResourceConfig classe.

Quelles sont les choses que je peux faire à l'intérieur de la sous-classe de ResourceConfig

Il suffit de regarder la javadoc. Surtout juste l'enregistrement de classes. Pas grand chose d'autre que vous devez faire avec elle. Les principales méthodes que vous allez utiliser sont l' register(), packages(), et property() méthodes. L' register() méthode vous permet d'enregistrer manuellement les classes et les instances de ressources et les fournisseurs manuellement. L' packages() méthode, décrite précédemment, les listes le paquet(s) que vous souhaitez Jersey pour le balayage @Path et @Provider de classes et de les enregistrer pour vous. Et l' property() méthode permet de définir certaines propriétés configurables 1.

L' ResourceConfig est juste une commodité de classe. Rappelez-vous, il s'étend Application, de sorte que nous pouvions utiliser la norme Application classe

@ApplicationPath("/services")
public class JerseyApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<>();
        classes.add(MyResource.class);
        return classes;
    }
    @Override
    public Set<Object> getSingletons() {
        final Set<Object> singletons = new HashSet<>();
        singletons.add(new MyProvider());
        return singletons;
    }

    @Override
    public Map<String, Object> getProperties() {
        final Map<String, Object> properties = new HashMap<>();
        properties.put("jersey.config.server.provider.packages",
                       "com.mypackage.to.scan");
        return properties;
    }
}

Avec un ResourceConfig, nous nous contenterons de faire

public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        register(MyResource.class);
        register(new MyProvider());
        packages("com.mypackages.to.scan");
    }
}

En plus d'être plus pratique, il y a aussi quelques chose sous le capot que l'aide Maillot de configuration de l'application.

Une SE de l'Environnement

Tous les exemples ci-dessus, supposons que vous êtes en cours d'exécution dans un environnement de serveur, par exemple Tomcat. Mais vous pouvez également exécuter l'application dans une SE de l'environnement, de l'endroit où vous exécutez un serveur incorporé et démarrer l'application à partir d'un main méthode. Vous verrez souvent ces exemples lors de la recherche autour pour info, donc je veux montrer à quoi ça ressemble, de sorte que lorsque vous tous les rencontrez, vous n'êtes pas surpris de voir et de savoir comment il diffère de votre installation.

Alors, parfois, vous verrez un exemple comme

ResourceConfig config = new ResourceConfig();
config.packages("com.my.package");
config.register(SomeFeature.class);
config.property(SOME_PROP, someValue);

Ce qui est plus probable qui se passe ici est que l'exemple est à l'aide d'un serveur embarqué, comme le Grizzly. Le reste du code pour démarrer le serveur est peut-être quelque chose comme

public static void main(String[] args) {
    ResourceConfig config = new ResourceConfig();
    config.packages("com.my.package");
    config.register(SomeFeature.class);
    config.property(SOME_PROP, someValue);

    String baseUri = "http://localhost:8080/api/";
    HttpServer server = GrizzlyHttpServerFactory
            .createHttpServer(URI.create(baseUri), config);
    server.start();
}

Donc, dans cet exemple, il y a un serveur autonome en cours de démarrage et l' ResourceConfig est utilisé pour configurer Jersey. Les différentes ici et à partir de l'exemple précédent est que, dans cet exemple, nous ne sommes pas à l'extension de l' ResourceConfig, mais à la place de son instanciation. Ce ne serait pas différente si nous avions à faire

public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        packages("com.my.package");
        register(SomeFeature.class);
        property(SOME_PROP, someValue);
    }
}

HttpServer server = GrizzlyHttpServerFactory
            .createHttpServer(URI.create(baseUri), new JerseyConfig());

Dire que vous avez été en passant par certaines tutoriel, et il a montré une configuration pour une application autonome, où ils instancier l' ResourceConfig, mais vous sont en cours d'exécution de votre application dans un conteneur de servlet et ont été à l'aide de la configuration antérieure où vous êtes l'extension de l' ResourceConfig. Eh bien maintenant, vous savez quelle est la différence et quels sont les changements que vous devez faire. J'ai vu des gens faire vraiment des trucs bizarres, parce qu'ils ne comprennent pas cette différence. Par exemple, j'ai vu quelqu'un de l'instanciation d'un ResourceConfig à l'intérieur d'une classe de ressource. C'est pourquoi j'ai ajouté ce petit morceau; ainsi vous ne faites pas la même erreur.


Notes de bas de page

1. Il y a un certain nombre de différentes propriétés configurables. Le lien vers l' ServerProperties sont à seulement quelques propriétés générales. Il y a également des propriétés différentes liées à des fonctions spécifiques. Le document doit mentionner ces propriétés dans la section de la documentation liée à cette fonction. Pour une liste complète de toutes les propriétés configurables, vous pouvez regarder tous les Maillot de constantes et de regarder pour ceux où la chaîne de valeur commence avec jersey.config. Si vous utilisez un web.xml, alors vous devez utiliser la chaîne de valeur comme l' init-param param-name. Si vous utilisez Java config (ResourceConfig), alors que vous appelez property(ServerProperties.SOME_CONF, value)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X