Spring Web Application Example With: Maven, Spring Core, Spring MVC, UTF-8 support.

Also some post-redirect-get in action!

This is my directory layout:

Start with pom.xml:
<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>biz.tugay</groupId>
    <artifactId>2016-01-11</artifactId>
    <packaging>war</packaging>
 
    <version>1.0-SNAPSHOT</version>
 
    <name>2016-01-11 Application</name>
    <url>http://www.tugay.biz</url>
 
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>2.2.1</version>
        </dependency>
 
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.zeroturnaround</groupId>
                <artifactId>jrebel-maven-plugin</artifactId>
                <version>1.1.5</version>
                <executions>
                    <execution>
                        <id>generate-rebel-xml</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>2016-01-11</finalName>
    </build>
 
</project>

And web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
 
    <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>
 
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <page-encoding>UTF-8</page-encoding>
            <scripting-invalid>true</scripting-invalid>
            <trim-directive-whitespaces>true</trim-directive-whitespaces>
            <default-content-type>text/html</default-content-type>
        </jsp-property-group>
    </jsp-config>
 
    <session-config>
        <session-timeout>30</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>
 
</web-app>

AppUserDB:
package biz.tugay.janeleven.root.db;
 
import biz.tugay.janeleven.root.model.AppUser;
 
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
 
public class AppUserDB {
 
    private static final Map<Long, AppUser> USER_MAP = new HashMap<Long, AppUser>();
 
    private static Long idCounter = 0L;
 
    public static void addUser(AppUser appUser) {
        idCounter++;
        USER_MAP.put(idCounter, appUser);
    }
 
    public static Collection<AppUser> getAll() {
        return USER_MAP.values();
    }
}

AppUser:
package biz.tugay.janeleven.root.model;
 
public class AppUser {
 
    private String username;
 
    public AppUser(String username) {
        this.username = username;
    }
 
    public String getUsername() {
        return username;
    }
 
}

AppUserService:
package biz.tugay.janeleven.root.service;
 
import biz.tugay.janeleven.root.db.AppUserDB;
import biz.tugay.janeleven.root.model.AppUser;
import org.springframework.stereotype.Service;
 
import java.util.Collection;
 
@Service
public class AppUserService {
 
    public AppUser addAppUser(String name) {
        final AppUser appUser = new AppUser(name);
        AppUserDB.addUser(appUser);
        return appUser;
    }
 
    public Collection<AppUser> getAllAppUsers() {
        return AppUserDB.getAll();
    }
}

HelloWorldServlet:
package biz.tugay.janeleven.web;
/* AppUser: koray@tugay.biz Date: 11/01/16 Time: 21:21 */
 
import biz.tugay.janeleven.root.model.AppUser;
import biz.tugay.janeleven.root.service.AppUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
 
import java.util.Collection;
 
@Controller
@RequestMapping(value = "/")
public class HelloWorldServlet {
 
    @Autowired
    private AppUserService appUserService;
 
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String helloWorld(Model model) {
        final Collection<AppUser> appUserList = appUserService.getAllAppUsers();
        model.addAttribute("appUserList", appUserList);
        return "hello.jsp";
    }
 
    @RequestMapping(value = "", method = RequestMethod.POST)
    public String addApplicationUser(@RequestParam("username") String username) {
        appUserService.addAppUser(username);
        return "redirect:/";
    }
 
}

hello.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
 
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
 
<body>
<form action="<c:url value="/"/>" method="POST">
    <label for="username">User Name:
        <input type="text" name="username" id="username">
    </label>
    <br/>
    <br/>
    <input type="submit" value="Add Application User"/>
</form>
<br/>
<br/>
<div>
    <%--@elvariable id="appUserList" type="java.util.Collection<biz.tugay.janeleven.root.model.AppUser>"--%>
    <c:forEach items="${appUserList}" var="appUser">
        <c:out value="${appUser.username}"/>
        <br/>
    </c:forEach>
 
</div>
</body>
</html>

And finally classes required for Spring Configuration and Bootstrap:
package biz.tugay.janeleven.root.config;
 
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
 
@Configuration
@ComponentScan(basePackages = "biz.tugay.janeleven.root.*")
public class RootContextConfiguration {
}
 
package biz.tugay.janeleven.root.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "biz.tugay.janeleven.web")
public class WebContextConfiguration {
 
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        return resolver;
    }
 
}
 
package biz.tugay.janeleven.root.config;
/* AppUser: koray@tugay.biz Date: 11/01/16 Time: 20:50 */
 
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 javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
 
public class SpringBootstrap implements WebApplicationInitializer {
 
    public void onStartup(ServletContext servletContext) throws ServletException {
        final AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootContextConfiguration.class);
        final ContextLoaderListener contextLoadListener = new ContextLoaderListener(rootContext);
        servletContext.addListener(contextLoadListener);
 
        final AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
        webContext.register(WebContextConfiguration.class);
 
        final DispatcherServlet servlet = new DispatcherServlet(webContext);
        final ServletRegistration.Dynamic dispatcher = servletContext.addServlet("springDispatcher", servlet);
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

And screenshots from the application: