webentwicklung-frage-antwort-db.com.de

Wie konfiguriert man Spring MVC mit einer reinen Java-basierten Konfiguration?

Ich habe, was ich für ein ziemlich einfaches Spring MVC-Setup halten würde. Meine applicationContext.xml lautet wie folgt:

<mvc:annotation-driven />
<mvc:resources mapping="/css/**" location="/css/" />
<context:property-placeholder location="classpath:controller-test.properties" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/views/" p:suffix=".jsp" />

Meine web.xml ist aktuell so:

  <servlet>
   <servlet-name>springDispatcherServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- Map all requests to the DispatcherServlet for handling -->
  <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

Ich versuche, dieses Setup in eine reine Java-basierte Konfiguration zu konvertieren. Ich habe im Web gesucht und bis jetzt habe ich Sachen bekommen, die erklären, wie man die Java-Konfiguration ausführt, nicht aber, wie man diese Java-Konfiguration in der Umgebung registriert, d. H. Den Web-Kontext.

Was ich bisher in Bezug auf @Configuration habe, ist folgendes:

 @Configuration
 @EnableWebMvc
 @PropertySource("classpath:controller.properties")
 @ComponentScan("com.project.web")
 public class WebSpringConfig extends WebMvcConfigurerAdapter {

 @Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/css/**").addResourceLocations("/css/");
 }

 @Bean
 public ViewResolver configureViewResolver() {
     InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();
     viewResolve.setPrefix("/WEB-INF/views/");
     viewResolve.setSuffix(".jsp");

     return viewResolve;
 }

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

Wie registriere ich das mit dem Webcontainer? Ich verwende den neuesten Frühling (4.02).

Vielen Dank!

32
user1902183

Sie müssen die folgenden Änderungen an web.xml vornehmen, um die Java-basierte Konfiguration zu unterstützen. Dadurch wird der DispatcherServlet aufgefordert, die Konfiguration mithilfe der anotationsbasierten Java-Konfiguration AnnotationConfigWebApplicationContext zu laden. Sie müssen nur den Speicherort Ihrer javaconfig-Datei an contextConfigLocation param übergeben. wie nachstehend

<servlet>
  <servlet-name>springDispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <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>/*path to your WebSpringConfig*/ </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

Update: Das Gleiche tun, ohne Änderungen an web.xml vorzunehmen

Sie können dies sogar ohne web.xml als Servlet-Spezifikation 3.0 machen, die web.xml optional macht. Sie müssen lediglich die WebApplicationInitializer-Schnittstelle implementieren/konfigurieren, um ServletContext zu konfigurieren, mit der Sie programmgesteuert DispatcherServlet erstellen, konfigurieren und registrieren können. Das Gute ist, dass WebApplicationInitializer automatisch erkannt wird.

Die Zusammenfassung ist die Notwendigkeit, WebApplicationInitializer zu implementieren, um web.xml loszuwerden.

 public class MyWebAppInitializer implements WebApplicationInitializer {

 @Override
 public void onStartup(ServletContext container) {
  // Create the 'root' Spring application context
  AnnotationConfigWebApplicationContext rootContext =
                       new AnnotationConfigWebApplicationContext();
  rootContext.register(WebSpringConfig.class);

  // Manage the lifecycle of the root application context
  container.addListener(new ContextLoaderListener(rootContext));

  // Create the dispatcher servlet's Spring application context
  AnnotationConfigWebApplicationContext dispatcherContext =
                     new AnnotationConfigWebApplicationContext();
  dispatcherContext.register(DispatcherConfig.class);

  // Register and map the dispatcher servlet
  ServletRegistration.Dynamic dispatcher =
    container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
  }
}

Update: von Kommentaren
Eine etwas kompliziertere Erklärung ist jetzt auch in der offiziellen Spring-Referenz enthalten. Spring 4 Release

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html

44
Santosh Joshi

Java-basierte Konfiguration ohne Hinzufügen von Elementen zu web.xml. WebApplicationInitializer eignet sich perfekt für die Verwendung mit Spring-Klassen mit Code @Configuration

WebApplicationInitializer " Schnittstelle, die in Servlet 3.0+ environments Implementiert werden muss, um den ServletContext programmgesteuert zu konfigurieren - im Gegensatz zu (oder möglicherweise in Verbindung mit) dem herkömmlichen web.xml-basierten Ansatz. Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container.  Verwenden der Servlet-Spezifikation 3.0 von Tomcat 7

Ab Spring 3.2 wurden einige Abstract-Klassen aufgelistet, die den WebApplicationInitializer implementiert haben, der vom SrevletContainer automatisch erkannt wird.

AbstractAnnotationConfigDispatcherServletInitializer extends
AbstractDispatcherServletInitializer extends
AbstractContextLoaderInitializer implements WebApplicationInitializer

Verwendung der Spring-Version 4.1.6.RELEASE Mit den Modulen core, web, webmvc, beans.

public class WebXML_DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { MvcServletXMLConfigurer.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}

Java-basierte Konfiguration zur Bereitstellung statischer Ressourcen mit Spring.  Spring Boot

@Configuration
@EnableWebMvc // <mvc:annotation-driven />
@ComponentScan(value = {"com.github.yash777.controllers"})
// <context:component-scan base-package="com.github.yash777" />
public class MvcServletXMLConfigurer extends WebMvcConfigurerAdapter implements WebMvcConfigurer {

    /**
     * <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
     * p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
     * 
     * @return InternalResourceViewResolver as a bean configuration.
     */
    @Bean
    public InternalResourceViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        System.out.println("WebMvcConfigurer - addResourceHandlers() function get loaded...");

        // <mvc:resources mapping="/styles/**" location="/css/" />
        registry
            .addResourceHandler("/styles/**") 
            .addResourceLocations("/css/") // webapp/css/
            .setCachePeriod(3600)
            .resourceChain(true) // Spring 4.1
            .addResolver(new GzipResourceResolver()) // Spring 4.1
            .addResolver(new PathResourceResolver()); // Spring 4.1

        // <mvc:resources mapping="/static/**" location="/static/" />
        registry.addResourceHandler("/static/**")
                .addResourceLocations("/static/", "classpath:/static/") // src/main/resources/static/
                .setCachePeriod(3600)
                .resourceChain(true)
                .addResolver(new PathResourceResolver());
    }
}

Listete einen Beispiel-Controller auf:

@Controller
@RequestMapping(value = { "/controller", "/c" })
public class Test extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @RequestMapping(value = {"/message", "/m"}, method = RequestMethod.GET )
    public void message(HttpServletRequest request, HttpServletResponse response ) throws IOException {
        System.out.println("@Controller Get method called.");
    }

    @RequestMapping(value = "/getView", method = RequestMethod.GET )
    public ModelAndView setViewName( Model model ) {
        System.out.println("GET... /getView");
        ModelAndView mav = new ModelAndView();
        mav.setViewName("test");
        return mav;
    }
}

WEB-INF/web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://Java.Sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>
1
Yash