diff --git a/spring-dispatcher-servlet/README.md b/spring-dispatcher-servlet/README.md
new file mode 100644
index 0000000000..56bb353487
--- /dev/null
+++ b/spring-dispatcher-servlet/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Spring DispatcherServlet](http://www.baeldung.com/spring-dispatcher-servlet)
diff --git a/spring-dispatcher-servlet/pom.xml b/spring-dispatcher-servlet/pom.xml
index b6210971ae..84a7a5b59d 100644
--- a/spring-dispatcher-servlet/pom.xml
+++ b/spring-dispatcher-servlet/pom.xml
@@ -1,96 +1,96 @@
-
-
+
+
4.0.0
-
+ com.baeldung
spring-dispatcher-servlet
war
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
- ..
-
-
+ 1.0.0
+ spring-dispatcher-servlet
+
+ 4.3.7.RELEASE
+
+
+ org.springframework
+ spring-core
+ ${springframework.version}
+
- javax.servlet
- javax.servlet-api
- ${javax.servlet.version}
- provided
+ org.springframework
+ spring-web
+ ${springframework.version}
org.springframework
spring-webmvc
- ${org.springframework.version}
-
-
- commons-logging
- commons-logging
-
-
+ ${springframework.version}
- org.thymeleaf
- thymeleaf-spring4
- ${thymeleaf.version}
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
- org.slf4j
- slf4j-api
- ${org.slf4j.version}
+ javax.servlet.jsp.jstl
+ jstl-api
+ 1.2
+
+
+ javax.servlet.jsp
+ javax.servlet.jsp-api
+ 2.3.1
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ 1.9.13
+
+
+ javax.servlet
+ jstl
+ 1.2
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.5.0
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.3
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- 1.8
- 1.8
-
-
-
- org.apache.maven.plugins
- maven-war-plugin
- ${maven-war-plugin.version}
-
- false
-
-
-
- org.eclipse.jetty
- jetty-maven-plugin
- ${jetty-maven-plugin.version}
-
-
- /
-
-
-
-
+
+
+
+ maven-compiler-plugin
+ 3.1
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.tomcat.maven
+ tomcat8-maven-plugin
+ 3.0-r1655215
+
+ /springdispatcherservlet
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.0.0
+
+ src/main/webapp
+ false
+
+
+
+
+ springdispatcherservlet
-
-
-
- 4.3.4.RELEASE
- 3.0.2.RELEASE
-
-
- 1.7.21
-
-
- 3.1.0
-
-
- 3.6.0
- 3.0.0
- 9.3.14.v20161028
-
-
+
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/DispatcherServletApplication.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/DispatcherServletApplication.java
deleted file mode 100644
index 181fb3f405..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/DispatcherServletApplication.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet;
-
-import org.springframework.web.context.ContextLoaderListener;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-import org.springframework.web.servlet.DispatcherServlet;
-
-import javax.servlet.MultipartConfigElement;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRegistration;
-
-public class DispatcherServletApplication implements org.springframework.web.WebApplicationInitializer {
- @Override
- public void onStartup(ServletContext servletContext) throws ServletException {
- AnnotationConfigWebApplicationContext rootContext =
- new AnnotationConfigWebApplicationContext();
- rootContext.register(RootConfiguration.class);
- servletContext.addListener(new ContextLoaderListener(rootContext));
- AnnotationConfigWebApplicationContext webContext =
- new AnnotationConfigWebApplicationContext();
- webContext.register(WebConfiguration.class);
- DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
- ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher",
- dispatcherServlet);
- servlet.addMapping("/*");
- MultipartConfigElement multipartConfigElement =
- new MultipartConfigElement("/tmp");
- servlet.setMultipartConfig(multipartConfigElement);
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/RootConfiguration.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/RootConfiguration.java
deleted file mode 100644
index 48281c5e5d..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/RootConfiguration.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet;
-
-import com.baeldung.spring.dispatcher.servlet.models.Task;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.*;
-
-@Configuration
-public class RootConfiguration {
- @Bean
- public Map> taskList() {
- Map> taskMap = new HashMap<>();
- List taskList = new ArrayList<>();
- taskList.add(new Task("Clean the dishes!", new Date()));
- taskMap.put("Cid", taskList);
- return taskMap;
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebConfiguration.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebConfiguration.java
deleted file mode 100644
index 419c1a2908..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/WebConfiguration.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet;
-
-import org.springframework.context.MessageSource;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.ResourceBundleMessageSource;
-import org.springframework.ui.context.support.ResourceBundleThemeSource;
-import org.springframework.web.multipart.MultipartResolver;
-import org.springframework.web.multipart.support.StandardServletMultipartResolver;
-import org.springframework.web.servlet.HandlerExceptionResolver;
-import org.springframework.web.servlet.LocaleResolver;
-import org.springframework.web.servlet.ThemeResolver;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
-import org.springframework.web.servlet.i18n.CookieLocaleResolver;
-import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
-import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
-import org.springframework.web.servlet.theme.CookieThemeResolver;
-import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
-import org.thymeleaf.spring4.SpringTemplateEngine;
-import org.thymeleaf.spring4.view.ThymeleafViewResolver;
-import org.thymeleaf.templatemode.TemplateMode;
-import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
-
-import javax.servlet.ServletContext;
-import java.util.Locale;
-
-@Configuration
-@ComponentScan("com.baeldung.spring.dispatcher.servlet.web")
-@EnableWebMvc
-public class WebConfiguration extends WebMvcConfigurerAdapter {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry
- .addResourceHandler("/public/**")
- .addResourceLocations("/public/");
- }
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(localeChangeInterceptor());
- registry.addInterceptor(themeChangeInterceptor());
- }
-
- @Bean
- public ServletContextTemplateResolver templateResolver(ServletContext servletContext) {
- ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
- templateResolver.setPrefix("/WEB-INF/views/");
- templateResolver.setSuffix(".html");
- templateResolver.setTemplateMode(TemplateMode.HTML);
- return templateResolver;
- }
-
- @Bean
- public SpringTemplateEngine templateEngine(ServletContextTemplateResolver templateResolver) {
- SpringTemplateEngine templateEngine = new SpringTemplateEngine();
- templateEngine.setTemplateResolver(templateResolver);
- return templateEngine;
- }
-
- @Bean
- public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) {
- ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
- viewResolver.setTemplateEngine(templateEngine);
- return viewResolver;
- }
-
- @Bean
- public MessageSource messageSource() {
- ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
- messageSource.setBasename("messages");
- messageSource.setFallbackToSystemLocale(false);
- return messageSource;
- }
-
- @Bean
- public LocaleResolver localeResolver() {
- CookieLocaleResolver localeResolver = new CookieLocaleResolver();
- localeResolver.setDefaultLocale(Locale.ENGLISH);
- localeResolver.setCookieName("locale");
- localeResolver.setCookieMaxAge(-1);
- return localeResolver;
- }
-
- @Bean
- public LocaleChangeInterceptor localeChangeInterceptor() {
- LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
- localeChangeInterceptor.setParamName("lang");
- localeChangeInterceptor.setIgnoreInvalidLocale(true);
- return localeChangeInterceptor;
- }
-
- @Bean
- public ResourceBundleThemeSource themeSource() {
- ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
- themeSource.setBasenamePrefix("theme-");
- themeSource.setFallbackToSystemLocale(false);
- return themeSource;
- }
-
- @Bean
- public ThemeResolver themeResolver() {
- CookieThemeResolver themeResolver = new CookieThemeResolver();
- themeResolver.setDefaultThemeName("robotask");
- themeResolver.setCookieName("theme");
- themeResolver.setCookieMaxAge(-1);
- return themeResolver;
- }
-
- @Bean
- public ThemeChangeInterceptor themeChangeInterceptor() {
- ThemeChangeInterceptor themeChangeInterceptor = new ThemeChangeInterceptor();
- themeChangeInterceptor.setParamName("theme");
- return themeChangeInterceptor;
- }
-
- @Bean
- public MultipartResolver multipartResolver() {
- return new StandardServletMultipartResolver();
- }
-
- @Bean
- public HandlerExceptionResolver handlerExceptionResolver() {
- return new ExceptionHandlerExceptionResolver();
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Attachment.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Attachment.java
deleted file mode 100644
index 1d6248650f..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Attachment.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.models;
-
-import java.util.UUID;
-
-public class Attachment {
- private String id;
-
- private String name;
-
- private String description;
-
- public Attachment() {
- this.id = UUID.randomUUID().toString();
- }
-
- public Attachment(String name, String description) {
- this();
- this.name = name;
- this.description = description;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Attachment that = (Attachment) o;
- return id.equals(that.id);
- }
-
- @Override
- public int hashCode() {
- return id.hashCode();
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Task.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Task.java
deleted file mode 100644
index 1e6a533e3a..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/models/Task.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.models;
-
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-
-public class Task {
- private String description;
-
- @DateTimeFormat(pattern = "yyyy-MM-dd'T'hh:mm")
- private Date due;
-
- private Set attachments = new HashSet<>();
-
- public Task() {
- }
-
- public Task(Date due) {
- this.due = due;
- }
-
- public Task(String description, Date due) {
- this.description = description;
- this.due = due;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public Date getDue() {
- return due;
- }
-
- public void setDue(Date due) {
- this.due = due;
- }
-
- public Set getAttachments() {
- return attachments;
- }
-
- public void setAttachments(Set attachments) {
- this.attachments = attachments;
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentController.java
deleted file mode 100644
index 2521004ff1..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentController.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-@RequestMapping("/attachments")
-public interface AttachmentController {
- @GetMapping("/{attachmentId}")
- ResponseEntity getAttachment(
- @PathVariable("attachmentId") String attachmentId,
- @RequestParam(name = "download", required = false, defaultValue = "false") boolean forcedDownload
- );
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentControllerImpl.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentControllerImpl.java
deleted file mode 100644
index 75a15cf657..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/AttachmentControllerImpl.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import com.baeldung.spring.dispatcher.servlet.models.Task;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import java.net.URLConnection;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-@Controller
-public class AttachmentControllerImpl implements AttachmentController {
- @Autowired
- private Map> taskMap;
-
- @Override
- public ResponseEntity getAttachment(
- @PathVariable("attachmentId") String attachmentId,
- @RequestParam(name = "download", required = false, defaultValue = "false") boolean forcedDownload
- ) {
- FileSystemResource resource = new FileSystemResource("/tmp/" + attachmentId);
- HttpHeaders headers = new HttpHeaders();
- taskMap.values().stream()
- .flatMap(Collection::stream)
- .flatMap(t -> t.getAttachments().stream())
- .filter(a -> a.getId().equals(attachmentId))
- .findFirst()
- .ifPresent(a -> {
- headers.add("Content-Disposition",
- "attachment; filename=" + a.getName());
- headers.add("Content-Type", forcedDownload ?
- MediaType.APPLICATION_OCTET_STREAM_VALUE :
- URLConnection.guessContentTypeFromName(a.getName()));
- });
- return new ResponseEntity<>(resource, headers, HttpStatus.OK);
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/GlobalDefaultExceptionHandler.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/GlobalDefaultExceptionHandler.java
deleted file mode 100644
index f25eb601a7..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/GlobalDefaultExceptionHandler.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.servlet.ModelAndView;
-
-import javax.servlet.http.HttpServletRequest;
-
-@ControllerAdvice
-public class GlobalDefaultExceptionHandler {
- @ExceptionHandler(Exception.class)
- public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
- ModelAndView modelAndView = new ModelAndView();
- modelAndView.addObject("exception", e);
- modelAndView.addObject("url", request.getRequestURL());
- modelAndView.setViewName("error");
- return modelAndView;
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeController.java
deleted file mode 100644
index 5ac39fadb4..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeController.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-@RequestMapping("/")
-public interface HomeController {
- @GetMapping("/*")
- String home(
- Model model
- );
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeControllerImpl.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeControllerImpl.java
deleted file mode 100644
index 66d869ca67..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/HomeControllerImpl.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import com.baeldung.spring.dispatcher.servlet.models.Task;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@Controller
-public class HomeControllerImpl implements HomeController {
- @Autowired
- private Map> taskMap;
-
- @Override
- public String home(Model model) {
- List users = taskMap.keySet().stream()
- .sorted()
- .collect(Collectors.toList());
- model.addAttribute("users", users);
- return "home";
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskController.java
deleted file mode 100644
index eff93ffb2f..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskController.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import com.baeldung.spring.dispatcher.servlet.models.Task;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-@RequestMapping("/tasks")
-public interface TaskController {
- @GetMapping("/{username}/list")
- String listTasks(
- @PathVariable("username") String username,
- Model model
- );
-
- @GetMapping("/{username}/add")
- String addTask(
- @PathVariable("username") String username,
- Model model
- );
-
- @PostMapping("/{username}/add")
- String addTask(
- @PathVariable("username") String username,
- @ModelAttribute Task task
- );
-
- @GetMapping("/{username}/get/{id}")
- String getTask(
- @PathVariable("username") String username,
- @PathVariable("id") int id,
- Model model
- );
-
- @GetMapping("/{username}/get/{id}/attach")
- String attachToTask(
- @PathVariable("username") String username,
- @PathVariable("id") int id,
- Model model
- );
-
- @PostMapping("/{username}/get/{id}/attach")
- String attachToTask(
- @PathVariable("username") String username,
- @PathVariable("id") int id,
- @RequestParam("attachment") MultipartFile attachment,
- @RequestParam("description") String description
- );
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskControllerImpl.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskControllerImpl.java
deleted file mode 100644
index 464e58aa54..0000000000
--- a/spring-dispatcher-servlet/src/main/java/com/baeldung/spring/dispatcher/servlet/web/TaskControllerImpl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.baeldung.spring.dispatcher.servlet.web;
-
-import com.baeldung.spring.dispatcher.servlet.models.Attachment;
-import com.baeldung.spring.dispatcher.servlet.models.Task;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.*;
-import java.util.stream.Collectors;
-
-@Controller
-public class TaskControllerImpl implements TaskController {
- @Autowired
- private Map> taskMap;
-
- @Override
- public String listTasks(
- @PathVariable("username") String username,
- Model model
- ) {
- List tasks = taskMap.get(username).stream()
- .sorted(Comparator.comparing(Task::getDue))
- .collect(Collectors.toList());
- model.addAttribute("username", username);
- model.addAttribute("tasks", tasks);
- return "task-list";
- }
-
- @Override
- public String addTask(
- @PathVariable("username") String username,
- Model model
- ) {
- model.addAttribute("username", username);
- model.addAttribute("task", new Task(new Date()));
- return "task-add";
- }
-
- @Override
- public String addTask(
- @PathVariable("username") String username,
- @ModelAttribute Task task
- ) {
- List taskList = taskMap.get(username);
- if (taskList == null) {
- taskList = new ArrayList<>();
- }
- taskList.add(task);
- taskMap.put(username, taskList);
- return "redirect:list";
- }
-
- @Override
- public String getTask(
- @PathVariable("username") String username,
- @PathVariable("id") int id,
- Model model
- ) {
- Task task = taskMap.get(username).get(id);
- model.addAttribute("username", username);
- model.addAttribute("id", id);
- model.addAttribute("task", task);
- return "task-get";
- }
-
- @Override
- public String attachToTask(
- @PathVariable("username") String username,
- @PathVariable("id") int id,
- Model model
- ) {
- model.addAttribute("username", username);
- model.addAttribute("id", id);
- return "task-attach";
- }
-
- @Override
- public String attachToTask(
- @PathVariable("username") String username,
- @PathVariable("id") int id,
- @RequestParam("attachment") MultipartFile multipartFile,
- @RequestParam("description") String description
- ) {
- Task task = taskMap.get(username).get(id);
- Attachment attachment = new Attachment(multipartFile.getOriginalFilename(),
- description);
- task.getAttachments().add(attachment);
- try (InputStream inputStream =
- new BufferedInputStream(multipartFile.getInputStream());
- OutputStream outputStream =
- new BufferedOutputStream(Files.newOutputStream(
- Paths.get("/tmp", attachment.getId())))) {
- byte[] buf = new byte[1024 * 16];
- int len;
- while ((len = inputStream.read(buf)) != -1) {
- outputStream.write(buf, 0, len);
- }
- } catch (IOException e) {
- throw new RuntimeException("Failed to upload file!", e);
- }
- return "redirect:./";
- }
-}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java
new file mode 100644
index 0000000000..f5ad032e84
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/AppConfig.java
@@ -0,0 +1,83 @@
+package com.baeldung.springdispatcherservlet.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.ui.context.support.ResourceBundleThemeSource;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+import org.springframework.web.servlet.config.annotation.*;
+import org.springframework.web.servlet.resource.PathResourceResolver;
+import org.springframework.web.servlet.theme.CookieThemeResolver;
+import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
+import org.springframework.web.servlet.view.JstlView;
+import org.springframework.web.servlet.view.UrlBasedViewResolver;
+
+import java.io.IOException;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan("com.baeldung.springdispatcherservlet")
+public class AppConfig extends WebMvcConfigurerAdapter {
+
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/").setViewName("index");
+ }
+
+ /** Multipart file uploading configuratioin */
+ @Bean
+ public CommonsMultipartResolver multipartResolver() throws IOException {
+ CommonsMultipartResolver resolver = new CommonsMultipartResolver();
+ resolver.setMaxUploadSize(10000000);
+ return resolver;
+ }
+
+ /** View resolver for JSP */
+ @Bean
+ public UrlBasedViewResolver viewResolver() {
+ UrlBasedViewResolver resolver = new UrlBasedViewResolver();
+ resolver.setPrefix("/WEB-INF/jsp/");
+ resolver.setSuffix(".jsp");
+ resolver.setViewClass(JstlView.class);
+ return resolver;
+ }
+
+ /** Static resource locations including themes*/
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/resources/**/*")
+ .addResourceLocations("/", "/resources/")
+ .setCachePeriod(3600)
+ .resourceChain(true)
+ .addResolver(new PathResourceResolver());
+ }
+
+ /** BEGIN theme configuration */
+ @Bean
+ public ResourceBundleThemeSource themeSource(){
+ ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
+ themeSource.setDefaultEncoding("UTF-8");
+ themeSource.setBasenamePrefix("themes.");
+ return themeSource;
+ }
+
+ @Bean
+ public CookieThemeResolver themeResolver(){
+ CookieThemeResolver resolver = new CookieThemeResolver();
+ resolver.setDefaultThemeName("default");
+ resolver.setCookieName("example-theme-cookie");
+ return resolver;
+ }
+
+ @Bean
+ public ThemeChangeInterceptor themeChangeInterceptor(){
+ ThemeChangeInterceptor interceptor = new ThemeChangeInterceptor();
+ interceptor.setParamName("theme");
+ return interceptor;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(themeChangeInterceptor());
+ }
+ /** END theme configuration */
+}
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/WebAppInitializer.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/WebAppInitializer.java
new file mode 100644
index 0000000000..0c6c7141a7
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/configuration/WebAppInitializer.java
@@ -0,0 +1,23 @@
+package com.baeldung.springdispatcherservlet.configuration;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+
+public class WebAppInitializer implements WebApplicationInitializer {
+
+ @Override
+ public void onStartup(ServletContext container) throws ServletException {
+ AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+ context.register(AppConfig.class);
+ context.setServletContext(container);
+
+ ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(context));
+ servlet.setLoadOnStartup(1);
+ servlet.addMapping("/");
+ }
+}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java
new file mode 100644
index 0000000000..1cc8261f7c
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/MultipartController.java
@@ -0,0 +1,41 @@
+package com.baeldung.springdispatcherservlet.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.ServletContext;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+@Controller
+public class MultipartController {
+
+ @Autowired
+ ServletContext context;
+
+ @RequestMapping(value = "/upload", method = RequestMethod.POST)
+ public ModelAndView FileuploadController(@RequestParam("file") MultipartFile file) {
+ ModelAndView modelAndView = new ModelAndView("index");
+ try {
+ InputStream in = file.getInputStream();
+ String path = new File(".").getAbsolutePath();
+ FileOutputStream f = new FileOutputStream(path.substring(0, path.length()-1)+ "/uploads/" + file.getOriginalFilename());
+ int ch;
+ while ((ch = in.read()) != -1) {
+ f.write(ch);
+ }
+ f.flush();
+ f.close();
+ modelAndView.getModel().put("message", "File uploaded successfully!");
+ } catch (Exception e) {
+ System.out.println("Exception uploading multipart: " + e);
+ }
+ return modelAndView;
+ }
+}
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/UserController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/UserController.java
new file mode 100644
index 0000000000..16e6f293ec
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/UserController.java
@@ -0,0 +1,30 @@
+package com.baeldung.springdispatcherservlet.controller;
+
+import com.baeldung.springdispatcherservlet.domain.User;
+import com.baeldung.springdispatcherservlet.services.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@Controller
+@RequestMapping("/user")
+public class UserController {
+
+ @Autowired
+ private UserService userService;
+
+ @RequestMapping(value = "/example", method = RequestMethod.GET)
+ @ResponseBody
+ public User fetchUserExample() {
+ return userService.exampleUser();
+ }
+
+ @RequestMapping(value = "/name", method = RequestMethod.GET)
+ @ResponseBody
+ public User fetchUserByFirstName(@RequestParam(value = "firstName") String firstName) {
+ return userService.fetchUserByFirstName(firstName);
+ }
+}
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/UserRestController.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/UserRestController.java
new file mode 100644
index 0000000000..9052662f17
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/controller/UserRestController.java
@@ -0,0 +1,27 @@
+package com.baeldung.springdispatcherservlet.controller;
+
+import com.baeldung.springdispatcherservlet.domain.User;
+import com.baeldung.springdispatcherservlet.services.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/rest/user")
+public class UserRestController {
+
+ @Autowired
+ private UserService userService;
+
+ @RequestMapping(value = "/example", method = RequestMethod.GET)
+ public User fetchUserExample() {
+ return userService.exampleUser();
+ }
+
+ @RequestMapping(value = "/name", method = RequestMethod.GET)
+ public User fetchUserByFirstName(@RequestParam(value = "firstName") String firstName) {
+ return userService.fetchUserByFirstName(firstName);
+ }
+}
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/domain/User.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/domain/User.java
new file mode 100644
index 0000000000..6e8cde50db
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/domain/User.java
@@ -0,0 +1,41 @@
+package com.baeldung.springdispatcherservlet.domain;
+
+
+public class User {
+ private long id;
+ private String firstName;
+ private String lastName;
+
+ public User(long id, String firstName, String lastName) {
+ this.id = id;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public User() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/services/UserService.java b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/services/UserService.java
new file mode 100644
index 0000000000..1b9bdd4a71
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/java/com/baeldung/springdispatcherservlet/services/UserService.java
@@ -0,0 +1,17 @@
+package com.baeldung.springdispatcherservlet.services;
+
+import org.springframework.stereotype.Service;
+
+import com.baeldung.springdispatcherservlet.domain.User;
+
+@Service
+public class UserService {
+
+ public User fetchUserByFirstName(String firstName) {
+ return new User(1, firstName, "Everyperson");
+ }
+
+ public User exampleUser() {
+ return new User(1, "Example", "Everyperson");
+ }
+}
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/resources/README.md b/spring-dispatcher-servlet/src/main/resources/README.md
deleted file mode 100644
index 7c97e75a2c..0000000000
--- a/spring-dispatcher-servlet/src/main/resources/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## Info ##
-
-- The diagram is created with [yed](http://www.yworks.com/products/yed)
diff --git a/spring-dispatcher-servlet/src/main/resources/diagram.graphml b/spring-dispatcher-servlet/src/main/resources/diagram.graphml
deleted file mode 100644
index 1806ab7719..0000000000
--- a/spring-dispatcher-servlet/src/main/resources/diagram.graphml
+++ /dev/null
@@ -1,372 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Servlet Engine (e.g. Tomcat)
-
-
-
-
-
-
-
-
-
- Folder 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Controller
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Model
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Model
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- DispatcherServlet
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- View Template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Return Control
-
-
-
-
-
-
-
-
-
-
-
- Render Response
-
-
-
-
-
-
-
-
-
-
-
- Delegate Request
-
-
-
-
-
-
-
-
-
-
-
- Delegate Rendering of Response
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Incoming Request
-
-
-
-
-
-
-
-
-
-
-
- Return Response
-
-
-
-
-
-
-
-
-
-
-
-
-
- Handle Request
-
-
-
-
-
-
-
-
-
-
-
-
-
- Create Model
-
-
-
-
-
-
-
-
- <?xml version="1.0" encoding="utf-8"?>
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve">
-<g>
-
- <radialGradient id="neck_x5F_white_1_" cx="28.0298" cy="-751.9429" r="11.4464" fx="25.7969" fy="-753.1596" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#B38E5D"/>
- <stop offset="1" style="stop-color:#805126"/>
- </radialGradient>
- <path id="neck_x5F_white_2_" fill="url(#neck_x5F_white_1_)" stroke="#5B453B" stroke-miterlimit="10" d="M19.278,37.799h18.188
- v13.23c-1.313,0.371-17.173,0.436-18.188,0.172V37.799z"/>
-
- <radialGradient id="SVGID_1_" cx="27.481" cy="-760.3003" r="31.0533" fx="21.4231" fy="-763.6011" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#B38E5D"/>
- <stop offset="1" style="stop-color:#805126"/>
- </radialGradient>
- <path fill="url(#SVGID_1_)" stroke="#5B453B" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
- V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
- c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/>
-
- <radialGradient id="face_x5F_white_1_" cx="27.7827" cy="-732.2632" r="23.424" fx="23.2131" fy="-734.753" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#B38E5D"/>
- <stop offset="1" style="stop-color:#805126"/>
- </radialGradient>
- <path id="face_x5F_white_2_" fill="url(#face_x5F_white_1_)" stroke="#5B453B" stroke-miterlimit="10" d="M43.676,23.357
- c0.086,10.199-6.738,18.52-15.246,18.586c-8.503,0.068-15.467-8.146-15.553-18.344C12.794,13.4,19.618,5.079,28.123,5.012
- C36.627,4.945,43.59,13.158,43.676,23.357z"/>
-
- <linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="2941.4297" y1="5674.7988" x2="2965.0596" y2="5768.2505" gradientTransform="matrix(0.275 0 0 0.2733 -783.3976 -1542.678)">
- <stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.42"/>
- <stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.12"/>
- </linearGradient>
- <path id="face_highlight_2_" fill="url(#face_highlight_1_)" d="M27.958,6.333c-6.035,0.047-10.747,4.493-12.787,10.386
- c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
- c2.274-0.592,3.988-2.459,4.375-4.766c0.183-1.094,0.293-2.289,0.283-3.553C42.083,13.952,36.271,6.268,27.958,6.333z"/>
- <path id="path9833_2_" fill="#4B4B4B" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
- C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
- c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
- s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.654,22.781
- c15.665-0.703,12.289-10.48,9.658-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/>
-
- <radialGradient id="collar_x5F_body_2_" cx="15.1587" cy="-763.7056" r="32.4004" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#B0E8FF"/>
- <stop offset="1" style="stop-color:#74AEEE"/>
- </radialGradient>
- <path id="collar_x5F_body_1_" fill="url(#collar_x5F_body_2_)" stroke="#5491CF" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494
- h48.51c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
- c-1.771,1.655-5.61,2.802-10.063,2.802c-4.453,0-8.292-1.146-10.063-2.802c0,0-5.755,0.586-11.189,6.021
- C1.378,56.689,0.5,62.768,0.5,62.768z"/>
-
- <radialGradient id="collar_x5F_r_2_" cx="31.5" cy="-753.832" r="9.2834" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#80CCFF"/>
- <stop offset="1" style="stop-color:#74AEEE"/>
- </radialGradient>
- <path id="collar_x5F_r_1_" fill="url(#collar_x5F_r_2_)" stroke="#5491CF" d="M38.159,41.381c0,0-0.574,2.369-3.013,4.441
- c-2.108,1.795-5.783,2.072-5.783,2.072l3.974,6.217c0,0,2.957-1.637,5.009-3.848c1.922-2.072,1.37-5.479,1.37-5.479L38.159,41.381z
- "/>
-
- <radialGradient id="collar_x5F_l_2_" cx="19.1377" cy="-753.873" r="9.2837" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#80CCFF"/>
- <stop offset="1" style="stop-color:#74AEEE"/>
- </radialGradient>
- <path id="collar_x5F_l_1_" fill="url(#collar_x5F_l_2_)" stroke="#5491CF" d="M18.63,41.422c0,0,0.576,2.369,3.012,4.441
- c2.109,1.793,5.785,2.072,5.785,2.072l-3.974,6.217c0,0-2.957-1.637-5.007-3.85c-1.922-2.072-1.37-5.48-1.37-5.48L18.63,41.422z"/>
-
- <radialGradient id="Knob2_2_" cx="27.8872" cy="9.9414" r="0.9669" gradientTransform="matrix(1 0 0 -1 0.04 66.1543)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#80CCFF"/>
- <stop offset="1" style="stop-color:#74AEEE"/>
- </radialGradient>
- <circle id="Knob2_1_" fill="url(#Knob2_2_)" stroke="#5491CF" cx="28.258" cy="56.254" r="0.584"/>
-
- <radialGradient id="Knob1_2_" cx="27.9253" cy="3.6973" r="0.9669" gradientTransform="matrix(1 0 0 -1 0.04 66.1543)" gradientUnits="userSpaceOnUse">
- <stop offset="0" style="stop-color:#80CCFF"/>
- <stop offset="1" style="stop-color:#74AEEE"/>
- </radialGradient>
- <circle id="Knob1_1_" fill="url(#Knob1_2_)" stroke="#5491CF" cx="28.296" cy="62.499" r="0.584"/>
-</g>
-</svg>
-
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/resources/diagram.png b/spring-dispatcher-servlet/src/main/resources/diagram.png
deleted file mode 100644
index c0c545d680..0000000000
Binary files a/spring-dispatcher-servlet/src/main/resources/diagram.png and /dev/null differ
diff --git a/spring-dispatcher-servlet/src/main/resources/messages.properties b/spring-dispatcher-servlet/src/main/resources/messages.properties
deleted file mode 100644
index c36eb5aa42..0000000000
--- a/spring-dispatcher-servlet/src/main/resources/messages.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-home.title=Welcome to TaskTools!
-task.add.description=description
-task.add.due=due
-task.add.header=Adding a task to {0}''s list:
-task.add.submit=Submit
-task.add.title={0}: task add
-task.attach.attachment=attached file
-task.attach.description=description
-task.attach.header=task #{0}: attach file
-task.attach.submit=Submit
-task.attach.title=#{0}: Attach file
-task.get.attach=Attach file
-task.get.attachments=attachments:
-task.get.download=Download
-task.get.header=task #{0}:
-task.get.list=Back
-task.get.title={0}: task details
-task.list.add-new=Add new
-task.list.details=Details
-task.list.header={0}''s tasks:
-task.list.home=Home
-task.list.title={0}: task list
diff --git a/spring-dispatcher-servlet/src/main/resources/messages_de.properties b/spring-dispatcher-servlet/src/main/resources/messages_de.properties
deleted file mode 100644
index 184b72101c..0000000000
--- a/spring-dispatcher-servlet/src/main/resources/messages_de.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-home.title=Willkommen bei TaskTools!
-task.add.description=Beschreibung
-task.add.due=f\u00e4llig
-task.add.header=F\u00fcge eine Aufgabe zu {0}''s Liste hinzu:
-task.add.submit=Senden
-task.add.title={0}: Task hinzuf\u00fcgen
-task.attach.attachment=Angeh\u00e4ngte Datei
-task.attach.description=Beschreibung
-task.attach.header=Task #{0}: Datei anh\u00e4ngen
-task.attach.submit=Senden
-task.attach.title=#{0}: Datei anh\u00e4ngen
-task.get.attach=Datei anh\u00e4ngen
-task.get.attachments=Anh\u00e4nge:
-task.get.download=Download
-task.get.header=Task #{0}:
-task.get.list=Zur\u00fcck
-task.get.title={0}: Task Details
-task.list.add-new=Neuer Task
-task.list.details=Details
-task.list.header={0}''s Tasks:
-task.list.home=Startseite
-task.list.title={0}: Task Liste
diff --git a/spring-dispatcher-servlet/src/main/resources/theme-post_it.properties b/spring-dispatcher-servlet/src/main/resources/theme-post_it.properties
deleted file mode 100644
index d2998e2bdf..0000000000
--- a/spring-dispatcher-servlet/src/main/resources/theme-post_it.properties
+++ /dev/null
@@ -1 +0,0 @@
-stylesheet=/public/css/themes/post_it.css
diff --git a/spring-dispatcher-servlet/src/main/resources/theme-robotask.properties b/spring-dispatcher-servlet/src/main/resources/theme-robotask.properties
deleted file mode 100644
index 68fe270b64..0000000000
--- a/spring-dispatcher-servlet/src/main/resources/theme-robotask.properties
+++ /dev/null
@@ -1 +0,0 @@
-stylesheet=/public/css/themes/robotask.css
diff --git a/spring-dispatcher-servlet/src/main/resources/themes/default.properties b/spring-dispatcher-servlet/src/main/resources/themes/default.properties
new file mode 100644
index 0000000000..a28d9bc939
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/resources/themes/default.properties
@@ -0,0 +1 @@
+styleSheet=/resources/css/default.css
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/resources/themes/example.properties b/spring-dispatcher-servlet/src/main/resources/themes/example.properties
new file mode 100644
index 0000000000..11e254eb58
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/resources/themes/example.properties
@@ -0,0 +1 @@
+styleSheet=/resources/css/example.css
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/jsp/index.jsp
new file mode 100644
index 0000000000..c482eac361
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/jsp/index.jsp
@@ -0,0 +1,30 @@
+<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
+<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>
+
+
+
+
+
+
+ Spring Dispatcher
+
+
+
+ Hello World!
+
+ Switch Theme!
+ Switch Theme!
+
+
+
+
+
+
+ ${message}
+
+
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/error.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/error.html
deleted file mode 100644
index 8f0f6afca7..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/error.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- Error
-
-
-
-
- Error:
-
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/home.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/home.html
deleted file mode 100644
index 6adec7bb12..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/home.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
- TaskTools
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-add.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-add.html
deleted file mode 100644
index 520486f52e..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-add.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-attach.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-attach.html
deleted file mode 100644
index 23246f330b..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-attach.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-get.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-get.html
deleted file mode 100644
index e7b35b6780..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-get.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 
- -
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-list.html b/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-list.html
deleted file mode 100644
index 0671f24ba3..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/WEB-INF/views/task-list.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-dispatcher-servlet/src/main/webapp/public/css/base.css b/spring-dispatcher-servlet/src/main/webapp/public/css/base.css
deleted file mode 100644
index 4d3c2597cf..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/public/css/base.css
+++ /dev/null
@@ -1,8 +0,0 @@
-a.button {
- -webkit-appearance: button;
- -moz-appearance: button;
- appearance: button;
- text-decoration: none;
- color: #2196f3;
- background-color: #e0e0e0;
-}
diff --git a/spring-dispatcher-servlet/src/main/webapp/public/css/themes/post_it.css b/spring-dispatcher-servlet/src/main/webapp/public/css/themes/post_it.css
deleted file mode 100644
index 578781ec83..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/public/css/themes/post_it.css
+++ /dev/null
@@ -1,8 +0,0 @@
-@import url('https://fonts.googleapis.com/css?family=Indie+Flower');
-
-* {
- font-family: 'Indie Flower', sans-serif;
- font-size: 18px;
- color: #ffeb3b;
- background-color: #212121;
-}
diff --git a/spring-dispatcher-servlet/src/main/webapp/public/css/themes/robotask.css b/spring-dispatcher-servlet/src/main/webapp/public/css/themes/robotask.css
deleted file mode 100644
index 8c0121b536..0000000000
--- a/spring-dispatcher-servlet/src/main/webapp/public/css/themes/robotask.css
+++ /dev/null
@@ -1,8 +0,0 @@
-@import url('https://fonts.googleapis.com/css?family=Roboto');
-
-* {
- font-family: Roboto, sans-serif;
- font-size: 1em;
- color: #212121;
- background-color: #fafafa;
-}
diff --git a/spring-dispatcher-servlet/src/main/webapp/resources/css/default.css b/spring-dispatcher-servlet/src/main/webapp/resources/css/default.css
new file mode 100644
index 0000000000..7f20f36d96
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/webapp/resources/css/default.css
@@ -0,0 +1,4 @@
+h2 {
+ color: green;
+ font-weight: 400;
+}
\ No newline at end of file
diff --git a/spring-dispatcher-servlet/src/main/webapp/resources/css/example.css b/spring-dispatcher-servlet/src/main/webapp/resources/css/example.css
new file mode 100644
index 0000000000..fe31b0396a
--- /dev/null
+++ b/spring-dispatcher-servlet/src/main/webapp/resources/css/example.css
@@ -0,0 +1,4 @@
+h2 {
+ color: red;
+ font-weight: 700;
+}
\ No newline at end of file