web-dev-qa-db-fra.com

Configuration d'une application Spring-Boot à l'aide de web.xml

J'initialise une application Web Spring existante afin que le fichier war généré intègre un serveur Web Jetty. Je souhaite m'en tenir à la configuration existante autant que possible afin de limiter les régressions.

Voici l'existant web.xml:

<web-app id="fbecart-webapp" version="2.4" xmlns="http://Java.Sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://Java.Sun.com/xml/ns/j2ee http://Java.Sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.fbecart.ApplicationConfiguration</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>spring-dispatcher</servlet-name>
    <servlet-class>com.fbecart.MyDispatcherServlet</servlet-class>
    <init-param>
        <param-name>dispatchOptionsRequest</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.fbecart.SpringDispatcherServletConfiguration</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

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

<filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>org.Eclipse.jetty.servlets.GzipFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>openSessionInView</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

Voici ma classe principale JettyApplication.Java:

package com.fbecart;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({ ApplicationConfiguration.class, SpringDispatcherServletConfiguration.class,
    EmbeddedServletContainerAutoConfiguration.class })
public class JettyApplication {
  public static void main(String[] args) throws Exception {
    SpringApplication.run(JettyApplication.class, args);
  }
}

J'ai effectué quelques modifications à mes scripts de construction Gradle pour le faire fonctionner:

  • ajout des dépendances à spring-boot-starter et spring-boot-starter-jetty
  • configuration du plugin Spring-boot

L'application démarre bien, les contrôleurs sont chargés et je peux interroger le serveur. Mais aucun des filtres définis dans le web.xml n'est activé.

Maintenant, je voudrais supprimer les importations de PropertiesConfiguration.class, ApplicationConfiguration.class et SpringDispatcherServletConfiguration.class dans JettyApplication.Java, et en quelque sorte les remplacer en chargeant ou en important le contenu de web.xml dans le conteneur de servlet intégré. Mais j'ignore si c'est une bonne stratégie et si je peux y arriver. J'apprécierais grandement toute aide.

-- SOLUTION

Voici la finale JettyApplication.class basé sur la réponse de Dave:

package com.fbecart;

import org.Eclipse.jetty.servlets.GzipFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

@Configuration
@Import({ ApplicationConfiguration.class, SpringDispatcherServletConfiguration.class,
    EmbeddedServletContainerAutoConfiguration.class })
public class JettyApplication {
  public static void main(String[] args) throws Exception {
    SpringApplication.run(JettyApplication.class, args);
  }

  @Bean
  public DispatcherServlet dispatcherServlet() {
    return new MyDispatcherServlet();
  }

  @Bean
  public GzipFilter gzipFilter() {
    return new GzipFilter();
  }

  @Bean
  public CharacterEncodingFilter characterEncodingFilter() {
    final CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
    characterEncodingFilter.setEncoding("UTF-8");
    characterEncodingFilter.setForceEncoding(true);
    return characterEncodingFilter;
  }

  @Bean
  public OpenEntityManagerInViewFilter openEntityManagerInViewFilter() {
    return new OpenEntityManagerInViewFilter();
  }
}

Je remplacerai web.xml par un ServletContainerInitializer dans un avenir proche ... restez à l'écoute;)

17
Florent Bécart

Si j'étais vous, j'essaierais lentement de décoller les couches dans web.xml et de les supprimer complètement. De cette façon, vous n'aurez qu'une seule configuration pour l'ensemble de l'application, y compris tous les filtres et servlets (c'est l'idée en tout cas). Vous pouvez effectuer une exécution parallèle pendant que vous vous stabilisez là où les filtres sont dupliqués dans web.xml, puis lorsque vous avez les mêmes fonctionnalités dans une application principale, vous pouvez simplement supprimer web.xml. Pour ajouter des filtres à votre application principale, créez simplement des définitions @Bean pour les instances Filter ou FilterRegistrationBean.

Vous pouvez toujours prendre en charge un déploiement de guerre via SpringBootServletInitializer également si nécessaire.

8
Dave Syer