J'ai vu beaucoup de tutoriels Jersey qui commencent par quelque chose comme
@ApplicationPath("services")
public class JerseyApplication extends ResourceConfig {
public JerseyApplication() {
packages("com.abc.jersey.services");
}
}
sans expliquer ce qu'est exactement la classe ResourceConfig
. Alors, où puis-je trouver sa documentation, son utilisation, etc.? Googler pour "jersey resourceconfig" ne donne aucun document officiel.
Certaines de mes questions sur cette classe et son utilisation sont les suivantes:
ResourceConfig
?ResourceConfig
pour qu'elle puisse être trouvée ou est-elle automatiquement détectée par Jersey?ResourceConfig
?ResourceConfig
est-il identique à celui du fichier web.xml
? Si c'est le cas, que se passe-t-il si j'ai les deux dans mon projet? L'un d'eux a-t-il préséance sur l'autre?JAX-RS standard utilise une classe de configuration Application
. ResourceConfig
s'étend Application
.
Il existe trois manières principales (dans un conteneur de servlet) de configurer Jersey (JAX-RS):
Application/ResourceConfig
Application/ResourceConfig
annotée avec @ApplicationPath
.Il est possible de configurer l'application de manière standard JAX-RS, mais ce qui suit 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>
Étant donné que Jersey s'exécute dans un conteneur de servlet, l'application Jersey s'exécute en tant que servlet. Le servlet Jersey qui traite les demandes entrantes est le ServletContainer
. Donc, ici nous le déclarons comme le <servlet-class>
. Nous configurons également un <init-param>
indiquant à Jersey le (s) paquet (s) à analyser pour nos classes @Path
et @Provider
afin qu'il puisse les enregistrer.
Sous le capot, Jersey créera en fait une instance ResourceConfig
, car c’est ce qu’il utilise pour configurer l’application. Ensuite, il enregistrera toutes les classes qu'il découvre via l'analyse du package.
Application/ResourceConfig
Si nous voulons configurer notre application par programme avec une sous-classe Application
ou ResourceConfig
, nous pouvons le faire en modifiant le fichier Web.xml ci-dessus. Au lieu de définir un init-param pour rechercher des paquets, nous utilisons un init-param pour déclarer notre sous-classe Application/ResourceConfig
.
<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 configurons le init-param
javax.ws.rs.Application
avec le nom complet de notre sous-classe ResourceConfig
. Et au lieu d'utiliser le init-param
qui indique à Jersey le (s) paquet (s) à analyser, nous utilisons simplement la méthode pratique packages()
de ResourceConfig
.
Nous pourrions également utiliser les méthodes register()
et property()
pour enregistrer des ressources et des fournisseurs, ainsi que pour configurer les propriétés de Jersey. Avec la méthode property()
, tout ce qui peut être configuré en tant que init-param
peut également être configuré à l'aide de la méthode property()
. Par exemple, au lieu d'appeler packages()
, nous pourrions faire
public JerseyApplication() {
property("jersey.config.server.provider.packages",
"com.mypackage.to.scan");
}
Application/ResourceConfig
Sans un fichier web.xml, Jersey a besoin d’un moyen de fournir le mappage de servlets. Nous faisons cela avec l'annotation @ApplicationPath
.
// '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 le @ApplicationPath
, c'est comme si nous avions configuré le mappage de servlet dans le web.xml
<servlet-mapping>
<servlet-name>JerseyApplication</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Lorsque vous utilisez uniquement le code Java pour la configuration, il doit exister un moyen pour Jersey de découvrir notre classe de configuration. Ceci est fait avec l'utilisation de ServletContanerInitializer
. C'est quelque chose qui a été introduit dans la spécification Servlet 3.0, nous ne pouvons donc pas utiliser la configuration "Java uniquement" dans les conteneurs de servlets antérieurs.
Fondamentalement, ce qui se passe, c’est que l’implémenteur de l’initialiseur puisse dire au conteneur de servlet quelles classes rechercher, et le conteneur de servlet passera ces classes à la méthode initializer onStartup()
. Dans l'implémentation de l'initialiseur par Jersey, Jersey le configure pour rechercher les classes Application
et les classes annotées avec @ApplicationPath
. Voir cet article pour plus d'explications. Ainsi, lorsque le conteneur de servlets démarre l'application, l'initialiseur de Jersey sera transmis à notre classe Application/ResourceConfig
.
Il suffit de regarder le javadoc . C'est surtout juste l'inscription des cours. Pas grand chose à faire avec ça. Les méthodes principales que vous utiliserez sont les méthodes register()
, packages()
et property()
. La méthode register()
vous permet d’enregistrer manuellement les classes et les instances de ressources et les fournisseurs manuellement. La méthode packages()
, décrite précédemment, répertorie le (s) package (s) sur lequel Jersey doit rechercher les classes @Path
et @Provider
et les enregistrer pour vous. Et la méthode property()
vous permet de définir des propriétés configurables . 1.
ResourceConfig
est juste une classe de commodité. Rappelez-vous, il étend Application
, de sorte que nous pourrions même utiliser la classe standard Application
@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 ferions simplement
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 également quelques éléments sous le capot qui aident Jersey à configurer l'application.
Tous les exemples ci-dessus supposent que vous utilisez un environnement de serveur installé, par exemple. Matou. Mais vous pouvez également exécuter l'application dans un environnement SE, où vous exécutez un serveur intégré et démarrez l'application à partir d'une méthode main
. Vous verrez parfois ces exemples lors de la recherche d'informations, alors je veux montrer à quoi ça ressemble, afin que, lorsque vous rencontrez tous ces problèmes, vous ne soyez pas surpris et sachiez en quoi cela diffère de votre configuration.
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 se passe probablement, c’est que l’exemple utilise un serveur intégré, comme Grizzly. Le reste du code pour démarrer le serveur pourrait ê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();
}
Ainsi, dans cet exemple, un serveur autonome est en cours de démarrage et le paramètre ResourceConfig
est utilisé pour configurer Jersey. La différence ici et par rapport aux exemples précédents est que, dans cet exemple, nous n’étendons pas ResourceConfig
, mais nous ne l’instancions que. Ce ne serait pas différent si nous devions 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());
Supposons que vous suiviez un didacticiel montrant une configuration pour une application autonome, dans laquelle ils instancient ResourceConfig
, mais que vous exécutez votre application dans un conteneur de servlets et que vous utilisiez la configuration précédente pour laquelle vous étendez ResourceConfig
. Eh bien, vous savez maintenant quelle est la différence et quels changements vous devez apporter. J'ai vu des gens faire des choses vraiment bizarres parce qu'ils ne comprenaient pas cette différence. Par exemple, j'ai vu quelqu'un instancier un ResourceConfig
dans une classe de ressources. C'est pourquoi j'ai ajouté ce petit morceau supplémentaire; alors vous ne faites pas la même erreur.
1. Il existe un certain nombre de propriétés configurables différentes. Le lien vers le ServerProperties
ne sont que quelques propriétés générales. Il existe également différentes propriétés liées à des fonctionnalités spécifiques. La documentation doit mentionner ces propriétés dans la section de la documentation associée à cette fonctionnalité. Pour obtenir une liste complète de toutes les propriétés configurables , vous pouvez consulter toutes les constantes de Jersey et rechercher ceux où la valeur de chaîne commence par jersey.config
. Si vous utilisez un fichier web.xml, vous utiliseriez la valeur de chaîne sous la forme init-param
param-name
. Si vous utilisez Java config (ResourceConfig
), appelez property(ServerProperties.SOME_CONF, value)
.