diff --git a/core-java/pom.xml b/core-java/pom.xml
index bc533607e7..bce97d1148 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -123,6 +123,12 @@
${mockito.version}
test
+
+
+ commons-codec
+ commons-codec
+ 1.10
+
diff --git a/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java
new file mode 100644
index 0000000000..83f1fb33b6
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java
@@ -0,0 +1,90 @@
+package org.baeldung.java.md5;
+
+import static org.junit.Assert.*;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class JavaMD5Test {
+
+
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+
+
+ @Test
+ public void givenPassword_whenHashing_thenVerifying() throws NoSuchAlgorithmException {
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(password.getBytes());
+ byte[] digest = md.digest();
+ String myHash = DatatypeConverter.printHexBinary(digest).toUpperCase();
+
+ assertThat(myHash.equals(hash)).isTrue();
+ }
+
+ @Test
+ public void givenFile_generatingChecksum_thenVerifying() throws NoSuchAlgorithmException, IOException {
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(Files.readAllBytes(Paths.get(filename)));
+ byte[] digest = md.digest();
+ String myChecksum = DatatypeConverter
+ .printHexBinary(digest).toUpperCase();
+
+ assertThat(myChecksum.equals(checksum)).isTrue();
+ }
+
+ @Test
+ public void givenPassword_whenHashingUsingCommons_thenVerifying() {
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+ String md5Hex = DigestUtils
+ .md5Hex(password).toUpperCase();
+
+ assertThat(md5Hex.equals(hash)).isTrue();
+ }
+
+
+ @Test
+ public void givenFile_whenChecksumUsingGuava_thenVerifying() throws IOException {
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ HashCode hash = com.google.common.io.Files
+ .hash(new File(filename), Hashing.md5());
+ String myChecksum = hash.toString()
+ .toUpperCase();
+
+ assertThat(myChecksum.equals(checksum)).isTrue();
+ }
+
+
+}
diff --git a/pom.xml b/pom.xml
index 37ed734567..7f7a145056 100644
--- a/pom.xml
+++ b/pom.xml
@@ -96,6 +96,7 @@
spring-mvc-java
spring-mvc-no-xml
spring-mvc-xml
+ spring-mvc-tiles
spring-openid
spring-protobuf
spring-quartz
diff --git a/spring-mvc-tiles/pom.xml b/spring-mvc-tiles/pom.xml
new file mode 100644
index 0000000000..1a72549e70
--- /dev/null
+++ b/spring-mvc-tiles/pom.xml
@@ -0,0 +1,85 @@
+
+ 4.0.0
+ com.baeldung
+ spring-mvc-tiles
+ 0.0.1-SNAPSHOT
+ war
+ spring-mvc-tiles
+ Integrating Spring MVC with Apache Tiles
+
+
+ 4.3.2.RELEASE
+ 3.0.5
+
+
+
+
+
+ org.springframework
+ spring-core
+ ${springframework.version}
+
+
+ org.springframework
+ spring-web
+ ${springframework.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${springframework.version}
+
+
+
+ org.apache.tiles
+ tiles-jsp
+ ${apachetiles.version}
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+
+
+ javax.servlet.jsp
+ javax.servlet.jsp-api
+ 2.3.1
+
+
+ javax.servlet
+ jstl
+ 1.2
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.2
+
+
+ 1.7
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 2.4
+
+ src/main/webapp
+ spring-mvc-tiles
+ false
+
+
+
+
+ spring-mvc-tiles
+
+
diff --git a/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationConfiguration.java b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationConfiguration.java
new file mode 100644
index 0000000000..d2e90a4f53
--- /dev/null
+++ b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationConfiguration.java
@@ -0,0 +1,47 @@
+package com.baeldung.tiles.springmvc;
+
+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.ViewResolverRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
+import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan(basePackages = "com.baeldung.tiles.springmvc")
+public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
+
+ /**
+ * Configure TilesConfigurer.
+ */
+ @Bean
+ public TilesConfigurer tilesConfigurer() {
+ TilesConfigurer tilesConfigurer = new TilesConfigurer();
+ tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/views/**/tiles.xml" });
+ tilesConfigurer.setCheckRefresh(true);
+ return tilesConfigurer;
+ }
+
+ /**
+ * Configure ViewResolvers to deliver views.
+ */
+ @Override
+ public void configureViewResolvers(ViewResolverRegistry registry) {
+ TilesViewResolver viewResolver = new TilesViewResolver();
+ registry.viewResolver(viewResolver);
+ }
+
+ /**
+ * Configure ResourceHandlers to serve static resources
+ */
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/static/**").addResourceLocations("/static/");
+ }
+
+}
diff --git a/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationController.java b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationController.java
new file mode 100644
index 0000000000..1a348d1c26
--- /dev/null
+++ b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationController.java
@@ -0,0 +1,26 @@
+package com.baeldung.tiles.springmvc;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+@RequestMapping("/")
+public class ApplicationController {
+
+ @RequestMapping(value = { "/" }, method = RequestMethod.GET)
+ public String homePage(ModelMap model) {
+ return "home";
+ }
+
+ @RequestMapping(value = { "/apachetiles" }, method = RequestMethod.GET)
+ public String productsPage(ModelMap model) {
+ return "apachetiles";
+ }
+
+ @RequestMapping(value = { "/springmvc" }, method = RequestMethod.GET)
+ public String contactUsPage(ModelMap model) {
+ return "springmvc";
+ }
+}
diff --git a/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationInitializer.java b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationInitializer.java
new file mode 100644
index 0000000000..79583dbe83
--- /dev/null
+++ b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationInitializer.java
@@ -0,0 +1,22 @@
+package com.baeldung.tiles.springmvc;
+
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return new Class[] { ApplicationConfiguration.class };
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return null;
+ }
+
+ @Override
+ protected String[] getServletMappings() {
+ return new String[] { "/" };
+ }
+
+}
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/apachetiles.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/apachetiles.jsp
new file mode 100644
index 0000000000..9936957c04
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/apachetiles.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Apache Tiles
+
+
+Tiles with Spring MVC Demo
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/home.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/home.jsp
new file mode 100644
index 0000000000..b501d4968e
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/home.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Home
+
+
+Welcome to Apache Tiles integration with Spring MVC
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/springmvc.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/springmvc.jsp
new file mode 100644
index 0000000000..209b1004de
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/springmvc.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Spring MVC
+
+
+Spring MVC configured to work with Apache Tiles
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/layouts/defaultLayout.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/layouts/defaultLayout.jsp
new file mode 100644
index 0000000000..2370ad4ab1
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/layouts/defaultLayout.jsp
@@ -0,0 +1,25 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+<%@ page isELIgnored="false"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultFooter.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultFooter.jsp
new file mode 100644
index 0000000000..3849cc5230
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultFooter.jsp
@@ -0,0 +1,2 @@
+
+
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultHeader.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultHeader.jsp
new file mode 100644
index 0000000000..8a878c857d
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultHeader.jsp
@@ -0,0 +1,3 @@
+
+ Welcome to Spring MVC integration with Apache Tiles
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultMenu.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultMenu.jsp
new file mode 100644
index 0000000000..2c91eace85
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultMenu.jsp
@@ -0,0 +1,8 @@
+
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/tiles.xml b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/tiles.xml
new file mode 100644
index 0000000000..789fbd809a
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/tiles.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/static/css/app.css b/spring-mvc-tiles/src/main/webapp/static/css/app.css
new file mode 100644
index 0000000000..9976e5406e
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/static/css/app.css
@@ -0,0 +1,36 @@
+.flex-container {
+ display: -webkit-flex;
+ display: flex;
+ -webkit-flex-flow: row wrap;
+ flex-flow: row wrap;
+ text-align: center;
+}
+
+.flex-container > * {
+ padding: 15px;
+ -webkit-flex: 1 100%;
+ flex: 1 100%;
+}
+
+.article {
+ text-align: left;
+}
+
+header {background: black;color:white;}
+footer {background: #aaa;color:white;}
+.nav {background:#eee;}
+
+.nav ul {
+ list-style-type: none;
+ padding: 0;
+}
+
+.nav ul a {
+ text-decoration: none;
+}
+
+@media all and (min-width: 768px) {
+ .nav {text-align:left;-webkit-flex: 1 auto;flex:1 auto;-webkit-order:1;order:1;}
+ .article {-webkit-flex:5 0px;flex:5 0px;-webkit-order:2;order:2;}
+ footer {-webkit-order:3;order:3;}
+}
\ No newline at end of file