We're doing a website for Cardshifter, and now I've converted the plain html files and css into a Spring MVC web application. Here is the typical configuration classes that I used in most of the project I work with.
package com.cardshifter.io.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.cardshifter.io.web" })
public class ApplicationConfig extends WebMvcConfigurerAdapter {
@Bean
ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setOrder(10);
return templateResolver;
}
@Bean
SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
@Bean
ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setOrder(1);
resolver.setTemplateEngine(templateEngine());
resolver.setViewNames(new String[] { "*" });
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/css/**","/images/**")
.addResourceLocations("/css/", "/images/");
}
}
This is the class that define the view engines and a bunch of other stuff.
package com.cardshifter.io.web.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.util.Log4jConfigListener;
import com.cardshifter.io.web.config.ApplicationConfig;
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ApplicationConfig.class);
// pour log4j
servletContext.addListener(new Log4jConfigListener());
// Register and map the dispatcher servlet
Dynamic dispatcherSpring = servletContext.addServlet("io", new DispatcherServlet(
rootContext));
dispatcherSpring.setLoadOnStartup(1);
dispatcherSpring.addMapping("/");
servletContext.addListener(new ContextLoaderListener(rootContext));
}
}
That class is the one responsible to expose the application to the servlet without a good old web.xml
.
What I'm wondering is, is there something more I would need to add in order to make the configuration easier? I always have difficulty to set the resources (css, js, etc.) in the webapp, is what I'm doing the "right" way?
1 Answer 1
You definitely want to look into Spring Boot. It can significantly reduce Spring configuration + has a lot of features that help to with deployment to production. Think about it as "convention over configuration" wrapper for Spring framework.
If you would follow Spring Boot conventions, you may need to shift some resources to different folders, but I believe you would be able to eliminate your spring configuration rapidly/completely.
If you decide not to use Spring Boot:
You may want to use AbstractAnnotationConfigDispatcherServletInitializer instead of WebApplicationInitializer, because I don't observe any unusual servet configuration. It may look like this:
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{ApplicationConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}