简体   繁体   中英

Spring MVC Java config

I want to set a simple response body from a spring webapp. My problem is simple is given a web error.

My POM.xml is:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>pt.dummy</groupId>
    <artifactId>dummy</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>dummy Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring-framework.version>3.2.3.RELEASE</spring-framework.version>
        <tomcat.servlet.version>7.0.42</tomcat.servlet.version>
        <log4j.version>1.7.5</log4j.version>
        <java.version>1.7</java.version>
        <junit.version>4.11</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.servlet.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>${tomcat.servlet.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>${tomcat.servlet.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jdt.core.compiler</groupId>
                    <artifactId>ecj</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-framework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring-framework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>dummy</finalName>
        <testResources>
          <testResource>
            <!-- declared explicitly so Spring config files can be placed next to their corresponding JUnit test class 
                (see example with ValidatorTests) -->
            <directory>${project.basedir}/src/test/java</directory>
          </testResource>
          <testResource>
            <directory>${project.basedir}/src/test/resources</directory>
          </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

My web initializer is:

package dummy.web.config;

import javax.servlet.Filter;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class WebAppInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

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

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

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

      @Override
      protected Filter[] getServletFilters() {

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        return new Filter[] { characterEncodingFilter};
      }

}

Core config:

package dummy.web.config;

import org.springframework.context.annotation.Configuration;

@Configuration
public class CoreConfig {

}

Web Config:

package dummy.web.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"dummy.web.controller"})
public class WebConfig {

}

Site Controller:

package dummy.web.controller;

//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class SiteController {

//  private static final Logger LOG = LoggerFactory.getLogger(SiteController.class);

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public String getHome() {
//        LOG.debug("Home to ResponseBody");
        return "Response Body";
    }
}

Could anyone indicate the changes necessary to add to make this work?

I believe it is because of Tomcat. Most tutorials on the web put the spring mvc servlet directly in the application context. It never worked for me.

On Tomcat7 (even with XML configuration) you have to create two contexts: one for the overall app and one for spring web mvc. It has something to do with

@RequestMapping("/")

The server assigns "/" mapping to the default built-in servlet. Which is something you want him (or it or her) to do. But you also need Spring MVC to map "/".

Maybe they (the architects) thought springmvc is a specific servlet and shouldn't map the root contex. Instead, it should be under his own mapping (eg "/springmvc/"). And then it expects we have a real dispatcher which...dispatches between springmvc and whatever other servlets.

For some magical reason, in Tomcat 7.0.29 it wasn't even able to "dispatch" if you tried to hijack "/". On the recent version, mapping "/" works .But for this you need a separate web mvc context/root context.

I do not use AbstractAnnotationConfigDispatcherServletInitializer you have to translate the code below. This was adapted from this tutorial on migrating from XML to Javaconfig spring-app-migration-from-xml-to-java-based-config

public class WebInit implements WebApplicationInitializer {

    private static final String DISPATCHER_SERVLET_NAME = "spring-mvc";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";

    @Override
    public void onStartup(ServletContext servletContext)
            throws ServletException {       

        //If you want to use the XML configuration, comment the following two lines out.
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(CoreConfig.class);
        appContext.setDisplayName("removed customer name");       

        //If you want to use the XML configuration, uncomment the following lines.
        //XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
        //rootContext.setConfigLocation("classpath:mvc-servlet.xml");

        AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
        mvcContext.register(ServletConfig.class);

        ServletRegistration.Dynamic springmvc =
                servletContext.addServlet(DISPATCHER_SERVLET_NAME,
                          new DispatcherServlet(mvcContext));
        springmvc.setLoadOnStartup(1);
        springmvc.addMapping(DISPATCHER_SERVLET_MAPPING);

        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);

        FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("characterEncoding", characterEncodingFilter);
        characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

        FilterRegistration.Dynamic security = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
        security.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

        servletContext.addListener(new ContextLoaderListener(appContext));
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM