Comment enregistrer un servlet en Java

** 1. introduction

**

Cet article fournit ** une présentation de la procédure d’enregistrement d’un servlet dans Java EE et Spring Boot. annotations. Ensuite, nous enregistrerons les servlets dans Spring Boot à l’aide de la configuration XML, de la configuration Java et de propriétés configurables.

Vous pouvez trouver un excellent article d’introduction sur les servlets ici .

2. Enregistrement de servlets dans Java EE

Examinons deux manières d’enregistrer une servlet dans Java EE. Tout d’abord, nous pouvons enregistrer un servlet via web.xml . Alternativement, nous pouvons utiliser l’annotation Java EE @ WebServlet .

2.1. Via web.xml

Le moyen le plus courant d’enregistrer un servlet dans votre application Java EE consiste à l’ajouter à votre fichier web.xml :

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
    <servlet-name>Example</servlet-name>
    <servlet-class>com.baeldung.Example</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Example</servlet-name>
    <url-pattern>/Example</url-pattern>
</servlet-mapping>

Comme vous pouvez le constater, cela implique deux étapes: (1) ajouter notre servlet à la balise servlet , en veillant à spécifier également le chemin source de la classe dans laquelle le servlet réside et (2) en spécifiant le chemin de l’URL auquel le servlet sera exposé. dans la balise url-pattern .

Le fichier Java EE web.xml se trouve généralement dans WebContent/WEB-INF .

2.2. Via les annotations

Enregistrons maintenant notre servlet à l’aide de l’annotation @ WebServlet de notre classe de servlets personnalisée. Ceci élimine le besoin de mappages de servlet dans server.xml et d’enregistrement du servlet dans web.xml :

@WebServlet(
  name = "AnnotationExample",
  description = "Example Servlet Using Annotations",
  urlPatterns = {"/AnnotationExample"}
)
public class Example extends HttpServlet {

    @Override
    protected void doGet(
      HttpServletRequest request,
      HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<p>Hello World!</p>");
    }
}

Le code ci-dessus montre comment ajouter cette annotation directement à un servlet. Le servlet sera toujours disponible dans le même chemin d’URL qu’avant.

3. Enregistrement de servlets dans Spring Boot

Maintenant que nous avons montré comment enregistrer des servlets dans Java EE, examinons plusieurs manières d’enregistrer des servlets dans une application Spring Boot.

3.1. Enregistrement programmatique

Spring Boot prend en charge la configuration 100% programmatique d’une application Web.

Nous allons d’abord implémenter l’interface WebApplicationInitializer , puis l’interface WebMvcConfigurer , qui vous permet de remplacer les paramètres par défaut prédéfinis au lieu d’avoir à spécifier chaque paramètre de configuration particulier, ce qui vous fait gagner du temps et vous permet de travailler avec plusieurs paramètres éprouvés et authentiques. -la boîte.

Regardons un exemple d’implémentation WebApplicationInitializer :

public class WebAppInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext ctx
          = new AnnotationConfigWebApplicationContext();
        ctx.register(WebMvcConfigure.class);
        ctx.setServletContext(container);

        ServletRegistration.Dynamic servlet = container.addServlet(
          "dispatcherExample", new DispatcherServlet(ctx));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
     }
}

Ensuite, implémentons l’interface WebMvcConfigurer :

@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver
          = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/** ** ")
          .addResourceLocations("/resources/").setCachePeriod(3600)
          .resourceChain(true).addResolver(new PathResourceResolver());
    }
}

Ci-dessus, nous spécifions explicitement certains paramètres par défaut pour les servlets JSP afin de prendre en charge les vues .jsp et le service des ressources statiques.

3.2. Configuration XML

Un autre moyen de configurer et d’enregistrer les servlets dans Spring Boot consiste à utiliser web.xml :

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/dispatcher.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Le fichier web.xml utilisé pour spécifier la configuration dans Spring est similaire à celui trouvé dans Java EE. Ci-dessus, vous pouvez voir comment nous spécifions quelques paramètres supplémentaires via des attributs sous la balise servlet .

Ici, nous utilisons un autre XML pour compléter la configuration:

<beans ...>

    <context:component-scan base-package="com.baeldung"/>

    <bean
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

N’oubliez pas que votre Spring web.xml réside généralement dans src/main/webapp/WEB-INF .

3.3. Combinaison d’inscription XML et programmatique

Mixons une approche de configuration XML avec une configuration programmatique de Spring:

public void onStartup(ServletContext container) throws ServletException {
   XmlWebApplicationContext xctx = new XmlWebApplicationContext();
   xctx.setConfigLocation('classpath:/context.xml');
   xctx.setServletContext(container);

   ServletRegistration.Dynamic servlet = container.addServlet(
     "dispatcher", new DispatcherServlet(ctx));
   servlet.setLoadOnStartup(1);
   servlet.addMapping("/");
}

Configurons également le servlet de répartiteur:

<beans ...>

    <context:component-scan base-package="com.baeldung"/>
    <bean class="com.baeldung.configuration.WebAppInitializer"/>
</beans>

3.4. Inscription par Bean

Nous pouvons également configurer et enregistrer nos servlets par programme à l’aide de ServletRegistrationBean . Nous allons le faire ci-dessous pour enregistrer un HttpServlet (qui implémente l’interface javax.servlet.Servlet ):

@Bean
public ServletRegistrationBean exampleServletBean() {
    ServletRegistrationBean bean = new ServletRegistrationBean(
      new CustomServlet(), "/exampleServlet/** ");
    bean.setLoadOnStartup(1);
    return bean;
}

Le principal avantage de cette approche est qu’elle vous permet d’ajouter deux servlets ainsi que différents types de servlets à votre application Spring.

Au lieu d’utiliser simplement un DispatcherServlet, qui est un type plus spécifique de HttpServlet et le type le plus courant utilisé dans l’approche de programmation par WebApplicationInitializer que nous avons expliquée à la section 3.1, nous allons utiliser un exemple plus simple de sous-classe WebApplicationInitializer qui expose les quatre bases HttpRequest opérations via quatre fonctions: doGet () , doPost () , doPut () et doDelete () exactement comme dans Java EE.

N’oubliez pas que HttpServlet est une classe abstraite (elle ne peut donc pas être instanciée). Nous pouvons facilement créer une extension personnalisée:

public class CustomServlet extends HttpServlet{
    ...
}

** 4. Enregistrement de servlets avec des propriétés

**

Une autre façon, bien que peu commune, de configurer et d’enregistrer vos servlets consiste à utiliser un fichier de propriétés personnalisé chargé dans l’application via un objet instance PropertyLoader, PropertySource, ou PropertySources _. _

Cela fournit un type de configuration intermédiaire et la possibilité de personnaliser autrement application.properties , qui fournit peu de configuration directe pour les servlets non intégrés.

4.1. Approche des propriétés du système

Nous pouvons ajouter des paramètres personnalisés à notre fichier application.properties ou à un autre fichier de propriétés. Ajoutons quelques paramètres pour configurer notre DispatcherServlet :

servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL

Chargerons nos propriétés personnalisées dans notre application:

System.setProperty("custom.config.location", "classpath:custom.properties");

Et maintenant, nous pouvons accéder à ces propriétés via:

System.getProperty("custom.config.location");

4.2. Approche des propriétés personnalisées

Commençons par un fichier custom.properties :

servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL

Nous pouvons ensuite utiliser un chargeur de propriétés courant:

public Properties getProperties(String file) throws IOException {
  Properties prop = new Properties();
  InputStream input = null;
  input = getClass().getResourceAsStream(file);
  prop.load(input);
  if (input != null) {
      input.close();
  }
  return prop;
}

Et maintenant, nous pouvons ajouter ces propriétés personnalisées en tant que constantes à notre implémentation WebApplicationInitializer :

private static final PropertyLoader pl = new PropertyLoader();
private static final Properties springProps
  = pl.getProperties("custom__spring.properties");

public static final String SERVLET__NAME
  = springProps.getProperty("servlet.name");
public static final String SERVLET__MAPPING
  = springProps.getProperty("servlet.mapping");

Nous pouvons ensuite les utiliser pour, par exemple, configurer notre servlet de répartiteur:

ServletRegistration.Dynamic servlet = container.addServlet(
  SERVLET__NAME, new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping(SERVLET__MAPPING);

L’avantage de cette approche réside dans l’absence de maintenance .xml , mais avec des paramètres de configuration faciles à modifier qui ne nécessitent pas de redéploiement de la base de code.

4.3. L’approche PropertySource

Un moyen plus rapide d’accomplir ce qui précède consiste à utiliser la propriété PropertySource de Spring qui permet d’accéder à un fichier de configuration et de le charger.

PropertyResolver est une interface implémentée par ConfigurableEnvironment, qui rend les propriétés d’application disponibles au démarrage et à l’initialisation du servlet:

@Configuration
@PropertySource("classpath:/com/yourapp/custom.properties")
public class ExampleCustomConfig {
    @Autowired
    ConfigurableEnvironment env;

    public String getProperty(String key) {
        return env.getProperty(key);
    }
}

Ci-dessus, nous transférons automatiquement une dépendance dans la classe et spécifions l’emplacement de notre fichier de propriétés personnalisé. Nous pouvons ensuite récupérer notre propriété saillante en appelant la fonction getProperty () en transmettant la valeur String.

4.4. L’approche programmatique de PropertySource

Nous pouvons combiner l’approche ci-dessus (qui consiste à récupérer des valeurs de propriété) avec l’approche ci-dessous (qui nous permet de spécifier ces valeurs par programme):

ConfigurableEnvironment env = new StandardEnvironment();
MutablePropertySources props = env.getPropertySources();
Map map = new HashMap(); map.put("key", "value");
props.addFirst(new MapPropertySource("Map", map));

Nous avons créé une carte reliant une clé à une valeur, puis nous l’ajoutons à PropertySources pour permettre l’appel au besoin.

5. Enregistrement de servlets incorporés

Enfin, nous examinerons également la configuration de base et l’enregistrement des servlets intégrées dans Spring Boot.

  • Un servlet intégré fournit une fonctionnalité de conteneur Web complet (Tomcat, Jetty, etc.) sans avoir à installer ou à entretenir le conteneur Web séparément ** .

Vous pouvez ajouter les dépendances et la configuration requises pour un déploiement simple de serveur en direct, chaque fois qu’une telle fonctionnalité est prise en charge sans douleur, de manière compacte et rapide.

Nous verrons seulement comment faire cela, mais la même approche peut être adoptée pour Jetty et ses alternatives.

Spécifions la dépendance d’un conteneur Web Tomcat 8 intégré dans pom.xml :

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
     <artifactId>tomcat-embed-core</artifactId>
     <version>8.5.11</version>
</dependency>

Ajoutons maintenant les balises nécessaires pour ajouter Tomcat au fichier .war produit par Maven lors de la construction:

<build>
    <finalName>embeddedTomcatExample</finalName>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>2.0.0</version>
            <configuration>
                <assembleDirectory>target</assembleDirectory>
                <programs>
                    <program>
                        <mainClass>launch.Main</mainClass>
                        <name>webapp</name>
                    </program>
            </programs>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Si vous utilisez Spring Boot, vous pouvez plutôt ajouter la dépendance spring-boot-starter-tomcat de Spring à votre pom.xml :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

5.1. Inscription par l’intermédiaire de propriétés

Spring Boot prend en charge la configuration de la plupart des paramètres Spring possibles via application.properties . Après avoir ajouté les dépendances de servlet intégrées nécessaires à votre pom.xml , vous pouvez personnaliser et configurer votre servlet intégré à l’aide de plusieurs de ces options de configuration:

server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet
server.jsp-servlet.registered=true
server.port=8080
server.servlet-path=/----

Vous trouverez ci-dessus certains paramètres d'application pouvant être utilisés pour configurer le partage de ressources __DispatcherServlet__ et statique. Les paramètres pour les servlets intégrées, la prise en charge de SSL et les sessions sont également disponibles.

Il y a vraiment trop de paramètres de configuration pour être listés ici, mais vous pouvez voir la liste complète dans https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html[Spring Documentation de démarrage].

====  **  5.2. Configuration via YAML **

De même, nous pouvons configurer notre conteneur de servlets intégré à l'aide de YAML.

Cela nécessite l'utilisation d'un chargeur de propriétés YAML spécialisé - le __YamlPropertySourceLoader__ - qui expose notre YAML et permet aux clés et aux valeurs qu'il contient d'être utilisées dans notre application.

[source,java,gutter:,true]

YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader(); PropertySource<?> yamlProps = sourceLoader.load("yamlProps", resource, null);

====  **  5.3. Configuration par programme via TomcatEmbeddedServletContainerFactory **

La configuration par programme d'un conteneur de servlets intégré est possible via une instance sous-classée de __EmbeddedServletContainerFactory__. Par exemple, vous pouvez utiliser __TomcatEmbeddedServletContainerFactory__ pour configurer votre servlet Tomcat intégré.

__TomcatEmbeddedServletContainerFactory__ encapsule l'objet __org.apache.catalina.startup.Tomcat__ en fournissant des options de configuration supplémentaires:

[source,java,gutter:,true]

@Bean public ConfigurableServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcatContainerFactory = new TomcatServletWebServerFactory(); return tomcatContainerFactory; }

Ensuite, nous pouvons configurer l'instance renvoyée:

[source,java,gutter:,true]

tomcatContainerFactory.setPort(9000); tomcatContainerFactory.setContextPath("/springboottomcatexample");

Chacun de ces paramètres peut être configuré à l'aide de l'une des méthodes décrites précédemment.

Nous pouvons également accéder et manipuler directement l'objet __org.apache.catalina.startup.Tomcat__:

[source,java,gutter:,true]

Tomcat tomcat = new Tomcat(); tomcat.setPort(port); tomcat.setContextPath("/springboottomcatexample"); tomcat.start();

===  **  6. Conclusion**

Dans cet article, nous avons passé en revue plusieurs méthodes pour **  enregistrer un servlet dans une application Java EE et Spring Boot. **

Le code source utilisé dans ce didacticiel est disponible dans le projet https://github.com/eugenp/tutorials/tree/master/spring-boot[Github].