diff --git a/groovy-spock/pom.xml b/groovy-spock/pom.xml
new file mode 100644
index 0000000000..be84500b0d
--- /dev/null
+++ b/groovy-spock/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+ org.spockframework
+ groovy-spock
+ 1.0-SNAPSHOT
+ jar
+ Spock Framework - Example Project
+
+
+ UTF-8
+ UTF-8
+
+
+
+
+
+ org.codehaus.gmavenplus
+ gmavenplus-plugin
+ 1.5
+
+
+
+ compile
+ testCompile
+
+
+
+
+
+
+
+
+
+ org.spockframework
+ spock-core
+ 1.0-groovy-2.4
+ test
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.7
+
+
+
\ No newline at end of file
diff --git a/groovy-spock/src/test/groovy/FirstSpecification.groovy b/groovy-spock/src/test/groovy/FirstSpecification.groovy
new file mode 100644
index 0000000000..ed228899a2
--- /dev/null
+++ b/groovy-spock/src/test/groovy/FirstSpecification.groovy
@@ -0,0 +1,89 @@
+import spock.lang.Specification
+
+class FirstSpecification extends Specification {
+
+ def "one plus one should equal two"() {
+ expect:
+ 1 + 1 == 2
+ }
+
+ def "two plus two should equal four"() {
+ given:
+ int left = 2
+ int right = 2
+
+ when:
+ int result = left + right
+
+ then:
+ result == 4
+ }
+
+ def "Should be able to remove from list"() {
+ given:
+ def list = [1, 2, 3, 4]
+
+ when:
+ list.remove(0)
+
+ then:
+ list == [2, 3, 4]
+ }
+
+ def "Should get an index out of bounds when removing a non-existent item"() {
+ given:
+ def list = [1, 2, 3, 4]
+
+ when:
+ list.remove(20)
+
+ then:
+ thrown(IndexOutOfBoundsException)
+ list.size() == 4
+ }
+
+ def "numbers to the power of two"(int a, int b, int c) {
+ expect:
+ Math.pow(a, b) == c
+
+ where:
+ a | b | c
+ 1 | 2 | 1
+ 2 | 2 | 4
+ 3 | 2 | 9
+ }
+
+ def "Should return default value for mock"() {
+ given:
+ def paymentGateway = Mock(PaymentGateway)
+
+ when:
+ def result = paymentGateway.makePayment(12.99)
+
+ then:
+ !result
+ }
+
+ def "Should return true value for mock"() {
+ given:
+ def paymentGateway = Mock(PaymentGateway)
+ paymentGateway.makePayment(20) >> true
+
+ when:
+ def result = paymentGateway.makePayment(20)
+
+ then:
+ result
+ }
+
+ def "Should verify notify was called"() {
+ given:
+ def notifier = Mock(Notifier)
+
+ when:
+ notifier.notify('foo')
+
+ then:
+ 1 * notifier.notify('foo')
+ }
+}
diff --git a/groovy-spock/src/test/groovy/Notifier.groovy b/groovy-spock/src/test/groovy/Notifier.groovy
new file mode 100644
index 0000000000..d92d0f86ef
--- /dev/null
+++ b/groovy-spock/src/test/groovy/Notifier.groovy
@@ -0,0 +1,3 @@
+interface Notifier {
+ void notify(String message)
+}
\ No newline at end of file
diff --git a/groovy-spock/src/test/groovy/PaymentGateway.groovy b/groovy-spock/src/test/groovy/PaymentGateway.groovy
new file mode 100644
index 0000000000..2a66e050f9
--- /dev/null
+++ b/groovy-spock/src/test/groovy/PaymentGateway.groovy
@@ -0,0 +1,3 @@
+interface PaymentGateway {
+ boolean makePayment(BigDecimal amount)
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 76f7247f51..c8d060ec04 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,7 @@
+ groovy-spock
gson
guava
guava18
diff --git a/spring-custom-aop/spring-custom-aop/.gitignore b/spring-custom-aop/spring-custom-aop/.gitignore
new file mode 100644
index 0000000000..60be5b80aa
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/.gitignore
@@ -0,0 +1,4 @@
+/target/
+.settings/
+.classpath
+.project
diff --git a/spring-custom-aop/spring-custom-aop/README.MD b/spring-custom-aop/spring-custom-aop/README.MD
new file mode 100644
index 0000000000..9fe18aaacc
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/README.MD
@@ -0,0 +1,13 @@
+###The Course
+The "REST With Spring" Classes: http://bit.ly/restwithspring
+
+###Relevant Articles:
+- [Quick Guide to @RestClientTest in Spring Boot](http://www.baeldung.com/restclienttest-in-spring-boot)
+- [Intro to Spring Boot Starters](http://www.baeldung.com/spring-boot-starters)
+- [A Guide to Spring in Eclipse STS](http://www.baeldung.com/eclipse-sts-spring)
+- [Introduction to WebJars](http://www.baeldung.com/maven-webjars)
+- [Create a Fat Jar App with Spring Boot](http://www.baeldung.com/deployable-fat-jar-spring-boot)
+- [The @ServletComponentScan Annotation in Spring Boot](http://www.baeldung.com/spring-servletcomponentscan)
+- [A Custom Data Binder in Spring MVC](http://www.baeldung.com/spring-mvc-custom-data-binder)
+- [Intro to Building an Application with Spring Boot](http://www.baeldung.com/intro-to-spring-boot)
+- [How to Register a Servlet in a Java Web Application](http://www.baeldung.com/register-servlet)
diff --git a/spring-custom-aop/spring-custom-aop/pom.xml b/spring-custom-aop/spring-custom-aop/pom.xml
new file mode 100644
index 0000000000..bab6f1f101
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/pom.xml
@@ -0,0 +1,224 @@
+
+ 4.0.0
+ com.baeldung
+ spring-boot
+ 0.0.1-SNAPSHOT
+ war
+ spring-boot
+ This is simple boot application for Spring boot actuator test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.2.RELEASE
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ ${tomcat.version}
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ ${tomcat.version}
+
+
+
+ io.dropwizard.metrics
+ metrics-core
+
+
+
+ com.h2database
+ h2
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ com.jayway.jsonpath
+ json-path
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.subethamail
+ subethasmtp
+ ${subethasmtp.version}
+ test
+
+
+
+ org.webjars
+ bootstrap
+ ${bootstrap.version}
+
+
+ org.webjars
+ jquery
+ ${jquery.version}
+
+
+
+ com.google.guava
+ guava
+ 18.0
+
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+ ${tomee-servlet-api.version}
+ provided
+
+
+
+
+
+ spring-boot
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+ pl.project13.maven
+ git-commit-id-plugin
+ ${git-commit-id-plugin.version}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/*IntegrationTest.java
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
+
+
+ integration
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*LiveTest.java
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+ json
+
+
+
+
+
+
+
+
+
+
+
+ org.baeldung.boot.DemoApplication
+ UTF-8
+ 1.8
+ 4.3.4.RELEASE
+ 2.2.1
+ 3.1.1
+ 3.3.7-1
+ 3.1.7
+ 8.5.11
+
+
+
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java
new file mode 100644
index 0000000000..b4d416dd96
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java
@@ -0,0 +1,25 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+
+/**
+ * using the following annotations are equivalent:
+ *
+ * @ServletComponentScan
+ *
+ * @ServletComponentScan(basePackages = "com.baeldung.annotation.servletcomponentscan.components")
+ *
+ * @ServletComponentScan(basePackageClasses = {AttrListener.class, HelloFilter.class, HelloServlet.class, EchoServlet.class})
+ *
+ */
+@SpringBootApplication
+@ServletComponentScan("com.baeldung.annotation.servletcomponentscan.components")
+public class SpringBootAnnotatedApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootAnnotatedApp.class, args);
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java
new file mode 100644
index 0000000000..8a39078aac
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java
@@ -0,0 +1,13 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "com.baeldung.annotation.servletcomponentscan.components")
+public class SpringBootPlainApp {
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java
new file mode 100644
index 0000000000..bad39c52c4
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java
@@ -0,0 +1,23 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class AttrListener implements ServletContextListener {
+
+ @Override
+ public void contextInitialized(ServletContextEvent servletContextEvent) {
+ servletContextEvent
+ .getServletContext()
+ .setAttribute("servlet-context-attr", "test");
+ System.out.println("context init");
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent servletContextEvent) {
+ System.out.println("context destroy");
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java
new file mode 100644
index 0000000000..3419cd0eaf
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java
@@ -0,0 +1,29 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+
+@WebServlet(name = "echo servlet", urlPatterns = "/echo")
+public class EchoServlet extends HttpServlet {
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response) {
+ try {
+ Path path = File
+ .createTempFile("echo", "tmp")
+ .toPath();
+ Files.copy(request.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
+ Files.copy(path, response.getOutputStream());
+ Files.delete(path);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java
new file mode 100644
index 0000000000..dc2368c5b2
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java
@@ -0,0 +1,32 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.*;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebInitParam;
+import java.io.IOException;
+
+@WebFilter(urlPatterns = "/hello", description = "a filter for hello servlet", initParams = { @WebInitParam(name = "msg", value = "filtering ") }, filterName = "hello filter", servletNames = { "echo servlet" })
+public class HelloFilter implements Filter {
+
+ private FilterConfig filterConfig;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ System.out.println("filter init");
+ this.filterConfig = filterConfig;
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ servletResponse
+ .getOutputStream()
+ .print(filterConfig.getInitParameter("msg"));
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+
+ @Override
+ public void destroy() {
+ System.out.println("filter destroy");
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java
new file mode 100644
index 0000000000..aeae7aecc9
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java
@@ -0,0 +1,32 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@WebServlet(urlPatterns = "/hello", initParams = { @WebInitParam(name = "msg", value = "hello")})
+public class HelloServlet extends HttpServlet {
+
+ private ServletConfig servletConfig;
+
+ @Override
+ public void init(ServletConfig servletConfig){
+ this.servletConfig = servletConfig;
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) {
+ try {
+ response
+ .getOutputStream()
+ .write(servletConfig.getInitParameter("msg").getBytes());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java
new file mode 100644
index 0000000000..cd696eae70
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java
@@ -0,0 +1,23 @@
+package com.baeldung.git;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+import org.springframework.core.io.ClassPathResource;
+
+@SpringBootApplication(scanBasePackages = { "com.baeldung.git" })
+public class CommitIdApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(CommitIdApplication.class, args);
+ }
+
+ @Bean
+ public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
+ PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
+ c.setLocation(new ClassPathResource("git.properties"));
+ c.setIgnoreResourceNotFound(true);
+ c.setIgnoreUnresolvablePlaceholders(true);
+ return c;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java
new file mode 100644
index 0000000000..6d44e02ec2
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java
@@ -0,0 +1,30 @@
+package com.baeldung.git;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+public class CommitInfoController {
+
+ @Value("${git.commit.message.short}")
+ private String commitMessage;
+
+ @Value("${git.branch}")
+ private String branch;
+
+ @Value("${git.commit.id}")
+ private String commitId;
+
+ @RequestMapping("/commitId")
+ public Map getCommitId() {
+ Map result = new HashMap<>();
+ result.put("Commit message", commitMessage);
+ result.put("Commit branch", branch);
+ result.put("Commit id", commitId);
+ return result;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/README.md b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/README.md
new file mode 100644
index 0000000000..7e6a597c28
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Injecting Git Information Into Spring](http://www.baeldung.com/spring-git-information)
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java
new file mode 100644
index 0000000000..c92d1c32e6
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java
@@ -0,0 +1,15 @@
+package com.baeldung.internationalization;
+
+import javax.annotation.security.RolesAllowed;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class InternationalizationApp {
+ @RolesAllowed("*")
+ public static void main(String[] args) {
+ System.setProperty("security.basic.enabled", "false");
+ SpringApplication.run(InternationalizationApp.class, args);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java
new file mode 100644
index 0000000000..59f7fd3ba5
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java
@@ -0,0 +1,38 @@
+package com.baeldung.internationalization.config;
+
+import java.util.Locale;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+import org.springframework.web.servlet.i18n.SessionLocaleResolver;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan(basePackages = "com.baeldung.internationalization.config")
+public class MvcConfig extends WebMvcConfigurerAdapter {
+
+ @Bean
+ public LocaleResolver localeResolver() {
+ SessionLocaleResolver slr = new SessionLocaleResolver();
+ slr.setDefaultLocale(Locale.US);
+ return slr;
+ }
+
+ @Bean
+ public LocaleChangeInterceptor localeChangeInterceptor() {
+ LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
+ lci.setParamName("lang");
+ return lci;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(localeChangeInterceptor());
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java
new file mode 100644
index 0000000000..96a534b853
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java
@@ -0,0 +1,14 @@
+package com.baeldung.internationalization.config;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@Controller
+public class PageController {
+
+ @GetMapping("/international")
+ public String getInternationalPage() {
+ return "international";
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java
new file mode 100644
index 0000000000..3db5d3256e
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java
@@ -0,0 +1,13 @@
+package com.baeldung.intro;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App
+{
+ public static void main( String[] args )
+ {
+ SpringApplication.run(App.class, args);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java
new file mode 100644
index 0000000000..2a7111135c
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java
@@ -0,0 +1,18 @@
+package com.baeldung.intro.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HomeController {
+
+ @RequestMapping("/")
+ public String root(){
+ return "Index Page";
+ }
+
+ @RequestMapping("/local")
+ public String local(){
+ return "/local";
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java
new file mode 100644
index 0000000000..a6ea3757fe
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java
@@ -0,0 +1,19 @@
+package com.baeldung.servlets;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class ApplicationMain extends SpringBootServletInitializer {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApplicationMain.class, args);
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(ApplicationMain.class);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java
new file mode 100644
index 0000000000..eadd40355a
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java
@@ -0,0 +1,32 @@
+package com.baeldung.servlets.configuration;
+
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+
+public class WebAppInitializer implements WebApplicationInitializer {
+
+ public void onStartup(ServletContext container) throws ServletException {
+
+ AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
+ ctx.register(WebMvcConfigure.class);
+ ctx.setServletContext(container);
+
+ ServletRegistration.Dynamic servletOne = container.addServlet("SpringProgrammaticDispatcherServlet", new DispatcherServlet(ctx));
+ servletOne.setLoadOnStartup(1);
+ servletOne.addMapping("/");
+
+ XmlWebApplicationContext xctx = new XmlWebApplicationContext();
+ xctx.setConfigLocation("/WEB-INF/context.xml");
+ xctx.setServletContext(container);
+
+ ServletRegistration.Dynamic servletTwo = container.addServlet("SpringProgrammaticXMLDispatcherServlet", new DispatcherServlet(xctx));
+ servletTwo.setLoadOnStartup(1);
+ servletTwo.addMapping("/");
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java
new file mode 100644
index 0000000000..3d6a10c2ac
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java
@@ -0,0 +1,39 @@
+package com.baeldung.servlets.configuration;
+
+import org.springframework.boot.web.support.ErrorPageFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.resource.PathResourceResolver;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+public class WebMvcConfigure extends WebMvcConfigurerAdapter {
+
+ @Bean
+ public ViewResolver getViewResolver() {
+ InternalResourceViewResolver resolver = new InternalResourceViewResolver();
+ resolver.setPrefix("/WEB-INF/");
+ resolver.setSuffix(".jsp");
+ return resolver;
+ }
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(3600).resourceChain(true).addResolver(new PathResourceResolver());
+ }
+
+ @Bean
+ public ErrorPageFilter errorPageFilter() {
+ return new ErrorPageFilter();
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java
new file mode 100644
index 0000000000..6345d1f969
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java
@@ -0,0 +1,20 @@
+package com.baeldung.servlets.props;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Properties;
+
+public final class Constants {
+
+ @Autowired
+ PropertySourcesLoader psl;
+
+ public static final String breakLine = System.getProperty("line.separator");
+ private static final PropertyLoader pl = new PropertyLoader();
+ private static final Properties mainProps = pl.getProperties("custom.properties");
+ public static final String DISPATCHER_SERVLET_NAME = mainProps.getProperty("dispatcher.servlet.name");
+ public static final String DISPATCHER_SERVLET_MAPPING = mainProps.getProperty("dispatcher.servlet.mapping");
+ private final String EXAMPLE_SERVLET_NAME = psl.getProperty("example.servlet.name");
+ private final String EXAMPLE_SERVLET_MAPPING = psl.getProperty("example.servlet.mapping");
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java
new file mode 100644
index 0000000000..c29da45929
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java
@@ -0,0 +1,27 @@
+package com.baeldung.servlets.props;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class PropertyLoader {
+ private static final Logger log = LoggerFactory.getLogger(PropertyLoader.class);
+
+ public Properties getProperties(String file) {
+ Properties prop = new Properties();
+ InputStream input = null;
+ try {
+ input = getClass().getResourceAsStream(file);
+ prop.load(input);
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ex) {
+ log.error("IOException: " + ex);
+ }
+ return prop;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java
new file mode 100644
index 0000000000..56a6751326
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java
@@ -0,0 +1,23 @@
+package com.baeldung.servlets.props;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.ConfigurableEnvironment;
+
+@Configuration
+@ComponentScan(basePackages = { "com.baeldung.*" })
+@PropertySource("classpath:custom.properties") public class PropertySourcesLoader {
+
+ private static final Logger log = LoggerFactory.getLogger(PropertySourcesLoader.class);
+
+ @Autowired
+ ConfigurableEnvironment env;
+
+ public String getProperty(String key) {
+ return env.getProperty(key);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java
new file mode 100644
index 0000000000..49dd9404b7
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java
@@ -0,0 +1,18 @@
+package com.baeldung.servlets.servlets;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class GenericCustomServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.println("Hello World
");
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java
new file mode 100644
index 0000000000..b50a7d5454
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java
@@ -0,0 +1,20 @@
+package com.baeldung.servlets.servlets.javaee;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@WebServlet(name = "AnnotationServlet",
+ description = "Example Servlet Using Annotations",
+ urlPatterns = { "/annotationservlet" })
+public class AnnotationServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ request.getRequestDispatcher("/annotationservlet.jsp").forward(request, response);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java
new file mode 100644
index 0000000000..c7b373064f
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java
@@ -0,0 +1,20 @@
+package com.baeldung.servlets.servlets.javaee;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class EEWebXmlServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.println("Hello World
");
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java
new file mode 100644
index 0000000000..e3c225d429
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java
@@ -0,0 +1,17 @@
+package com.baeldung.servlets.servlets.springboot;
+
+import com.baeldung.servlets.servlets.GenericCustomServlet;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SpringRegistrationBeanServlet {
+
+ @Bean
+ public ServletRegistrationBean genericCustomServlet() {
+ ServletRegistrationBean bean = new ServletRegistrationBean(new GenericCustomServlet(), "/springregistrationbeanservlet/*");
+ bean.setLoadOnStartup(1);
+ return bean;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java
new file mode 100644
index 0000000000..9e460d03a8
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java
@@ -0,0 +1,16 @@
+package com.baeldung.servlets.servlets.springboot.embedded;
+
+import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
+import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class EmbeddedTomcatExample {
+
+ @Bean
+ public EmbeddedServletContainerFactory servletContainer() {
+ TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
+ return tomcat;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java
new file mode 100644
index 0000000000..a3d9f9130c
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java
@@ -0,0 +1,18 @@
+package com.baeldung.utils;
+
+import javax.annotation.security.RolesAllowed;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages="com.baeldung.utils")
+public class Application {
+
+ @RolesAllowed("*")
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java
new file mode 100644
index 0000000000..7b4827cdf2
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java
@@ -0,0 +1,49 @@
+package com.baeldung.utils.controller;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.ServletRequestBindingException;
+import org.springframework.web.bind.ServletRequestUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.util.WebUtils;
+
+@Controller
+public class UtilsController {
+
+ @GetMapping("/utils")
+ public String webUtils(Model model) {
+ return "utils";
+ }
+
+ @PostMapping("/setParam")
+ public String post(HttpServletRequest request, Model model) {
+ String param = ServletRequestUtils.getStringParameter(request, "param", "DEFAULT");
+
+// Long param = ServletRequestUtils.getLongParameter(request, "param",1L);
+// boolean param = ServletRequestUtils.getBooleanParameter(request, "param", true);
+// double param = ServletRequestUtils.getDoubleParameter(request, "param", 1000);
+// float param = ServletRequestUtils.getFloatParameter(request, "param", (float) 1.00);
+// int param = ServletRequestUtils.getIntParameter(request, "param", 100);
+
+// try {
+// ServletRequestUtils.getRequiredStringParameter(request, "param");
+// } catch (ServletRequestBindingException e) {
+// e.printStackTrace();
+// }
+
+ WebUtils.setSessionAttribute(request, "parameter", param);
+ model.addAttribute("parameter", "You set: "+(String) WebUtils.getSessionAttribute(request, "parameter"));
+ return "utils";
+ }
+
+ @GetMapping("/other")
+ public String other(HttpServletRequest request, Model model) {
+ String param = (String) WebUtils.getSessionAttribute(request, "parameter");
+ model.addAttribute("parameter", param);
+ return "other";
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java
new file mode 100644
index 0000000000..e8e7fd5ce9
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java
@@ -0,0 +1,15 @@
+package com.baeldung.webjar;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class TestController {
+
+ @RequestMapping(value = "/")
+ public String welcome(Model model) {
+ return "index";
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java
new file mode 100644
index 0000000000..d2135754c9
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.webjar;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+public class WebjarsdemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(WebjarsdemoApplication.class, args);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/Application.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/Application.java
new file mode 100644
index 0000000000..aae0c427a9
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/Application.java
@@ -0,0 +1,13 @@
+package org.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.ApplicationContext;
+
+@org.springframework.boot.autoconfigure.SpringBootApplication
+public class Application {
+ private static ApplicationContext applicationContext;
+
+ public static void main(String[] args) {
+ applicationContext = SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java
new file mode 100644
index 0000000000..e61d140396
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java
@@ -0,0 +1,14 @@
+package org.baeldung.boot;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DemoApplication {
+
+ public static void main(String[] args) {
+ System.setProperty("spring.config.name", "demo");
+ SpringApplication.run(DemoApplication.class, args);
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java
new file mode 100644
index 0000000000..235fd43299
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java
@@ -0,0 +1,21 @@
+package org.baeldung.boot.components;
+
+import org.baeldung.boot.model.Foo;
+import org.baeldung.boot.repository.FooRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FooService {
+
+ @Autowired
+ private FooRepository fooRepository;
+
+ public Foo getFooWithId(Integer id) throws Exception {
+ return fooRepository.findOne(id);
+ }
+
+ public Foo getFooWithName(String name) {
+ return fooRepository.findByName(name);
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java
new file mode 100644
index 0000000000..1f008440e6
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java
@@ -0,0 +1,13 @@
+package org.baeldung.boot.exceptions;
+
+public class CommonException extends RuntimeException{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3080004140659213332L;
+
+ public CommonException(String message){
+ super(message);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java
new file mode 100644
index 0000000000..68ef3fa389
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java
@@ -0,0 +1,13 @@
+package org.baeldung.boot.exceptions;
+
+public class FooNotFoundException extends RuntimeException{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9042200028456133589L;
+
+ public FooNotFoundException(String message){
+ super(message);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java
new file mode 100644
index 0000000000..ac8a8fe429
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java
@@ -0,0 +1,46 @@
+package org.baeldung.boot.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Foo implements Serializable {
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue
+ private Integer id;
+ private String name;
+
+ public Foo() {
+ }
+
+ public Foo(String name) {
+ this.name = name;
+ }
+
+
+ public Foo(Integer id, String name) {
+ super();
+ this.id = id;
+ this.name = name;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java
new file mode 100644
index 0000000000..09d6975dba
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java
@@ -0,0 +1,8 @@
+package org.baeldung.boot.repository;
+
+import org.baeldung.boot.model.Foo;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface FooRepository extends JpaRepository {
+ public Foo findByName(String name);
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java
new file mode 100644
index 0000000000..834fa342e2
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java
@@ -0,0 +1,26 @@
+package org.baeldung.boot.service;
+
+import org.baeldung.boot.components.FooService;
+import org.baeldung.boot.model.Foo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class FooController {
+
+ @Autowired
+ private FooService fooService;
+
+ @GetMapping("/{id}")
+ public Foo getFooWithId(@PathVariable Integer id) throws Exception {
+ return fooService.getFooWithId(id);
+ }
+
+ @GetMapping("/")
+ public Foo getFooWithName(@RequestParam String name) throws Exception {
+ return fooService.getFooWithName(name);
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/Details.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/Details.java
new file mode 100644
index 0000000000..2ae3adc38f
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/Details.java
@@ -0,0 +1,32 @@
+package org.baeldung.client;
+
+public class Details {
+
+ private String name;
+
+ private String login;
+
+ public Details() {
+ }
+
+ public Details(String name, String login) {
+ this.name = name;
+ this.login = login;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLogin() {
+ return login;
+ }
+
+ public void setLogin(String login) {
+ this.login = login;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java
new file mode 100644
index 0000000000..51fa7c6181
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java
@@ -0,0 +1,20 @@
+package org.baeldung.client;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class DetailsServiceClient {
+
+ private final RestTemplate restTemplate;
+
+ public DetailsServiceClient(RestTemplateBuilder restTemplateBuilder) {
+ restTemplate = restTemplateBuilder.build();
+ }
+
+ public Details getUserDetails(String name) {
+ return restTemplate.getForObject("/{name}/details", Details.class, name);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java
new file mode 100644
index 0000000000..a50b88f94b
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java
@@ -0,0 +1,24 @@
+package org.baeldung.common.error;
+
+import org.springframework.boot.autoconfigure.web.ErrorController;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+public class MyCustomErrorController implements ErrorController {
+
+ private static final String PATH = "/error";
+
+ public MyCustomErrorController() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @RequestMapping(value = PATH)
+ public String error() {
+ return "Error heaven";
+ }
+
+ @Override
+ public String getErrorPath() {
+ return PATH;
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java
new file mode 100644
index 0000000000..774cf1b970
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java
@@ -0,0 +1,15 @@
+package org.baeldung.common.error;
+
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+
+import javax.servlet.Servlet;
+
+public class SpringHelloServletRegistrationBean extends ServletRegistrationBean {
+
+ public SpringHelloServletRegistrationBean() {
+ }
+
+ public SpringHelloServletRegistrationBean(Servlet servlet, String... urlMappings) {
+ super(servlet, urlMappings);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java
new file mode 100644
index 0000000000..9e63418a02
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java
@@ -0,0 +1,22 @@
+package org.baeldung.common.error.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class ErrorController {
+
+ public ErrorController() {
+ }
+
+ @RequestMapping("/400")
+ String error400() {
+ return "Error Code: 400 occured.";
+ }
+
+ @RequestMapping("/errorHeaven")
+ String errorHeaven() {
+ return "You have reached the heaven of errors!!!";
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java
new file mode 100644
index 0000000000..3d239f8944
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java
@@ -0,0 +1,25 @@
+package org.baeldung.common.properties;
+
+import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
+import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
+import org.springframework.boot.web.servlet.ErrorPage;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MyServletContainerCustomizationBean implements EmbeddedServletContainerCustomizer {
+
+ public MyServletContainerCustomizationBean() {
+
+ }
+
+ @Override
+ public void customize(ConfigurableEmbeddedServletContainer container) {
+ container.setPort(8084);
+ container.setContextPath("/springbootapp");
+
+ container.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
+ container.addErrorPages(new ErrorPage("/errorHeaven"));
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java
new file mode 100644
index 0000000000..07f57ec1ef
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java
@@ -0,0 +1,29 @@
+package org.baeldung.common.resources;
+
+import java.util.Objects;
+import java.util.concurrent.ExecutorService;
+
+import org.springframework.boot.ExitCodeGenerator;
+
+public class ExecutorServiceExitCodeGenerator implements ExitCodeGenerator {
+
+ private ExecutorService executorService;
+
+ public ExecutorServiceExitCodeGenerator(ExecutorService executorService) {
+ }
+
+ @Override
+ public int getExitCode() {
+ int returnCode = 0;
+ try {
+ if (!Objects.isNull(executorService)) {
+ executorService.shutdownNow();
+ returnCode = 1;
+ }
+ } catch (SecurityException ex) {
+ returnCode = 0;
+ }
+ return returnCode;
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java
new file mode 100644
index 0000000000..4ef407823e
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java
@@ -0,0 +1,17 @@
+package org.baeldung.config;
+
+import org.baeldung.web.resolver.HeaderVersionArgumentResolver;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import java.util.List;
+
+@Configuration
+public class WebConfig extends WebMvcConfigurerAdapter {
+
+ @Override
+ public void addArgumentResolvers(final List argumentResolvers) {
+ argumentResolvers.add(new HeaderVersionArgumentResolver());
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java
new file mode 100644
index 0000000000..7d1ad7d899
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java
@@ -0,0 +1,59 @@
+package org.baeldung.controller;
+
+import org.baeldung.domain.GenericEntity;
+import org.baeldung.domain.Modes;
+import org.baeldung.web.resolver.Version;
+import org.springframework.http.HttpStatus;
+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.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+public class GenericEntityController {
+ private List entityList = new ArrayList<>();
+
+ {
+ entityList.add(new GenericEntity(1l, "entity_1"));
+ entityList.add(new GenericEntity(2l, "entity_2"));
+ entityList.add(new GenericEntity(3l, "entity_3"));
+ entityList.add(new GenericEntity(4l, "entity_4"));
+ }
+
+ @RequestMapping("/entity/all")
+ public List findAll() {
+ return entityList;
+ }
+
+ @RequestMapping(value = "/entity", method = RequestMethod.POST)
+ public GenericEntity addEntity(GenericEntity entity) {
+ entityList.add(entity);
+ return entity;
+ }
+
+ @RequestMapping("/entity/findby/{id}")
+ public GenericEntity findById(@PathVariable Long id) {
+ return entityList.stream().filter(entity -> entity.getId().equals(id)).findFirst().get();
+ }
+
+ @GetMapping("/entity/findbydate/{date}")
+ public GenericEntity findByDate(@PathVariable("date") LocalDateTime date) {
+ return entityList.stream().findFirst().get();
+ }
+
+ @GetMapping("/entity/findbymode/{mode}")
+ public GenericEntity findByEnum(@PathVariable("mode") Modes mode) {
+ return entityList.stream().findFirst().get();
+ }
+
+ @GetMapping("/entity/findbyversion")
+ public ResponseEntity findByVersion(@Version String version) {
+ return version != null ? new ResponseEntity(entityList.stream().findFirst().get(), HttpStatus.OK) : new ResponseEntity(HttpStatus.NOT_FOUND);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java
new file mode 100644
index 0000000000..fc8fefd77e
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java
@@ -0,0 +1,43 @@
+package org.baeldung.controller.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class HelloWorldServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ public HelloWorldServlet() {
+ super();
+ }
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("HelloWorldServlet: GET METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("HelloWorldServlet: POST METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java
new file mode 100644
index 0000000000..16cff5b1fa
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java
@@ -0,0 +1,43 @@
+package org.baeldung.controller.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Objects;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class SpringHelloWorldServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ public SpringHelloWorldServlet() {
+ super();
+ }
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("SpringHelloWorldServlet: GET METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ out.println("SpringHelloWorldServlet: POST METHOD");
+ out.flush();
+ } finally {
+ if (!Objects.isNull(out))
+ out.close();
+ }
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java
new file mode 100644
index 0000000000..17c6fd06de
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java
@@ -0,0 +1,27 @@
+package org.baeldung.converter;
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.ConverterFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StringToEnumConverterFactory implements ConverterFactory {
+
+ private static class StringToEnumConverter implements Converter {
+
+ private Class enumType;
+
+ public StringToEnumConverter(Class enumType) {
+ this.enumType = enumType;
+ }
+
+ public T convert(String source) {
+ return (T) Enum.valueOf(this.enumType, source.trim());
+ }
+ }
+
+ @Override
+ public Converter getConverter(final Class targetType) {
+ return new StringToEnumConverter(targetType);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java
new file mode 100644
index 0000000000..cbb9e6ddb4
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java
@@ -0,0 +1,16 @@
+package org.baeldung.converter;
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Component
+public class StringToLocalDateTimeConverter implements Converter {
+
+ @Override
+ public LocalDateTime convert(final String source) {
+ return LocalDateTime.parse(source, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java
new file mode 100644
index 0000000000..7b1d27cb66
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java
@@ -0,0 +1,42 @@
+package org.baeldung.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class GenericEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+ private String value;
+
+ public GenericEntity() {
+ }
+
+ public GenericEntity(String value) {
+ this.value = value;
+ }
+
+ public GenericEntity(Long id, String value) {
+ this.id = id;
+ this.value = value;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java
new file mode 100644
index 0000000000..473406ef26
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java
@@ -0,0 +1,6 @@
+package org.baeldung.domain;
+
+public enum Modes {
+
+ ALPHA, BETA;
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java
new file mode 100644
index 0000000000..222a54c6ef
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java
@@ -0,0 +1,35 @@
+package org.baeldung.endpoints;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.boot.actuate.endpoint.Endpoint;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CustomEndpoint implements Endpoint> {
+
+ public CustomEndpoint() {
+
+ }
+
+ public String getId() {
+ return "customEndpoint";
+ }
+
+ public boolean isEnabled() {
+ return true;
+ }
+
+ public boolean isSensitive() {
+ return true;
+ }
+
+ public List invoke() {
+ // Your logic to display the output
+ List messages = new ArrayList();
+ messages.add("This is message 1");
+ messages.add("This is message 2");
+ return messages;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java
new file mode 100644
index 0000000000..0add741a1f
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java
@@ -0,0 +1,23 @@
+package org.baeldung.endpoints;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
+import org.springframework.boot.actuate.endpoint.Endpoint;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ListEndpoints extends AbstractEndpoint> {
+ private List endpoints;
+
+ @Autowired
+ public ListEndpoints(List endpoints) {
+ super("listEndpoints");
+ this.endpoints = endpoints;
+ }
+
+ public List invoke() {
+ return this.endpoints;
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java
new file mode 100644
index 0000000000..4410a02d47
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java
@@ -0,0 +1,22 @@
+package org.baeldung.endpoints;
+
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MyHealthCheck implements HealthIndicator {
+
+ public Health health() {
+ int errorCode = check(); // perform some specific health check
+ if (errorCode != 0) {
+ return Health.down().withDetail("Error Code", errorCode).withDetail("Description", "You custom MyHealthCheck endpoint is down").build();
+ }
+ return Health.up().build();
+ }
+
+ public int check() {
+ // Your logic to check health
+ return 1;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java
new file mode 100644
index 0000000000..b828a5b841
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java
@@ -0,0 +1,68 @@
+package org.baeldung.main;
+
+import org.baeldung.common.error.SpringHelloServletRegistrationBean;
+import org.baeldung.common.resources.ExecutorServiceExitCodeGenerator;
+import org.baeldung.controller.servlet.HelloWorldServlet;
+import org.baeldung.controller.servlet.SpringHelloWorldServlet;
+import org.baeldung.service.LoginService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@RestController
+@EnableAutoConfiguration
+@ComponentScan({ "org.baeldung.common.error", "org.baeldung.common.error.controller", "org.baeldung.common.properties", "org.baeldung.common.resources", "org.baeldung.endpoints", "org.baeldung.service", "org.baeldung.monitor.jmx", "org.baeldung.service" })
+public class SpringBootApplication {
+
+ private static ApplicationContext applicationContext;
+
+ @Autowired
+ private LoginService service;
+
+ @RequestMapping("/")
+ String home() {
+ service.login("admin", "admin".toCharArray());
+ return "TADA!!! You are in Spring Boot Actuator test application.";
+ }
+
+ public static void main(String[] args) {
+ applicationContext = SpringApplication.run(SpringBootApplication.class, args);
+ }
+
+ @Bean
+ public ExecutorService executorService() {
+ return Executors.newFixedThreadPool(10);
+ }
+
+ @Bean
+ public HelloWorldServlet helloWorldServlet() {
+ return new HelloWorldServlet();
+ }
+
+ @Bean
+ public SpringHelloServletRegistrationBean servletRegistrationBean() {
+ SpringHelloServletRegistrationBean bean = new SpringHelloServletRegistrationBean(new SpringHelloWorldServlet(), "/springHelloWorld/*");
+ bean.setLoadOnStartup(1);
+ bean.addInitParameter("message", "SpringHelloWorldServlet special message");
+ return bean;
+ }
+
+ @Bean
+ @Autowired
+ public ExecutorServiceExitCodeGenerator executorServiceExitCodeGenerator(ExecutorService executorService) {
+ return new ExecutorServiceExitCodeGenerator(executorService);
+ }
+
+ public void shutDown(ExecutorServiceExitCodeGenerator executorServiceExitCodeGenerator) {
+ SpringApplication.exit(applicationContext, executorServiceExitCodeGenerator);
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java
new file mode 100644
index 0000000000..febe3336eb
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java
@@ -0,0 +1,21 @@
+package org.baeldung.monitor.jmx;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.MetricRegistry;
+
+@Configuration
+public class MonitoringConfig {
+ @Autowired
+ private MetricRegistry registry;
+
+ @Bean
+ public JmxReporter jmxReporter() {
+ JmxReporter reporter = JmxReporter.forRegistry(registry).build();
+ reporter.start();
+ return reporter;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java
new file mode 100644
index 0000000000..7bb1e6dcdc
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java
@@ -0,0 +1,7 @@
+package org.baeldung.repository;
+
+import org.baeldung.domain.GenericEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface GenericEntityRepository extends JpaRepository {
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java
new file mode 100644
index 0000000000..34840fad67
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java
@@ -0,0 +1,5 @@
+package org.baeldung.service;
+
+public interface LoginService {
+ public boolean login(String userName, char[] password);
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java
new file mode 100644
index 0000000000..2e5ef89c48
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java
@@ -0,0 +1,29 @@
+package org.baeldung.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.metrics.CounterService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class LoginServiceImpl implements LoginService {
+
+ private CounterService counterService;
+
+ @Autowired
+ public LoginServiceImpl(CounterService counterService) {
+ this.counterService = counterService;
+ }
+
+ public boolean login(String userName, char[] password) {
+ boolean success;
+ if (userName.equals("admin") && "secret".toCharArray().equals(password)) {
+ counterService.increment("counter.login.success");
+ success = true;
+ } else {
+ counterService.increment("counter.login.failure");
+ success = false;
+ }
+ return success;
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java
new file mode 100644
index 0000000000..23d741b98c
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java
@@ -0,0 +1,23 @@
+package org.baeldung.session.exception;
+
+import org.baeldung.boot.model.Foo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;
+
+@EntityScan(basePackageClasses = Foo.class)
+@SpringBootApplication
+public class Application {
+ public static void main(String[] args) {
+ System.setProperty("spring.config.name", "exception");
+ System.setProperty("spring.profiles.active", "exception");
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public HibernateJpaSessionFactoryBean sessionFactory() {
+ return new HibernateJpaSessionFactoryBean();
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java
new file mode 100644
index 0000000000..679d691b26
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java
@@ -0,0 +1,10 @@
+package org.baeldung.session.exception.repository;
+
+import org.baeldung.boot.model.Foo;
+
+public interface FooRepository {
+
+ void save(Foo foo);
+
+ Foo get(Integer id);
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java
new file mode 100644
index 0000000000..83de888e5e
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java
@@ -0,0 +1,25 @@
+package org.baeldung.session.exception.repository;
+
+import org.baeldung.boot.model.Foo;
+import org.hibernate.SessionFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Repository;
+
+@Profile("exception")
+@Repository
+public class FooRepositoryImpl implements FooRepository {
+ @Autowired
+ private SessionFactory sessionFactory;
+
+ @Override
+ public void save(Foo foo) {
+ sessionFactory.getCurrentSession().saveOrUpdate(foo);
+ }
+
+ @Override
+ public Foo get(Integer id) {
+ return sessionFactory.getCurrentSession().get(Foo.class, id);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java
new file mode 100644
index 0000000000..89a77f38d1
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java
@@ -0,0 +1,26 @@
+package org.baeldung.web.resolver;
+
+import org.springframework.core.MethodParameter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Component
+public class HeaderVersionArgumentResolver implements HandlerMethodArgumentResolver {
+
+ @Override
+ public boolean supportsParameter(final MethodParameter methodParameter) {
+ return methodParameter.getParameterAnnotation(Version.class) != null;
+ }
+
+ @Override
+ public Object resolveArgument(final MethodParameter methodParameter, final ModelAndViewContainer modelAndViewContainer, final NativeWebRequest nativeWebRequest, final WebDataBinderFactory webDataBinderFactory) throws Exception {
+ HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
+
+ return request.getHeader("Version");
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java
new file mode 100644
index 0000000000..2a9e6e60b3
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java
@@ -0,0 +1,11 @@
+package org.baeldung.web.resolver;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface Version {
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/application.properties b/spring-custom-aop/spring-custom-aop/src/main/resources/application.properties
new file mode 100644
index 0000000000..72ed8795c9
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/application.properties
@@ -0,0 +1,43 @@
+server.port=8080
+server.contextPath=/springbootapp
+management.port=8081
+management.address=127.0.0.1
+
+endpoints.shutdown.enabled=true
+
+endpoints.jmx.domain=Spring Sample Application
+endpoints.jmx.uniqueNames=true
+
+##jolokia.config.debug=true
+##endpoints.jolokia.enabled=true
+##endpoints.jolokia.path=jolokia
+
+spring.jmx.enabled=true
+endpoints.jmx.enabled=true
+
+## for pretty printing of json when endpoints accessed over HTTP
+http.mappers.jsonPrettyPrint=true
+
+## Configuring info endpoint
+info.app.name=Spring Sample Application
+info.app.description=This is my first spring boot application G1
+info.app.version=1.0.0
+
+## Spring Security Configurations
+security.user.name=admin1
+security.user.password=secret1
+management.security.role=SUPERUSER
+
+logging.level.org.springframework=INFO
+
+#Servlet Configuration
+servlet.name=dispatcherExample
+servlet.mapping=/dispatcherExampleURL
+
+#banner.charset=UTF-8
+#banner.location=classpath:banner.txt
+#banner.image.location=classpath:banner.gif
+#banner.image.width= //TODO
+#banner.image.height= //TODO
+#banner.image.margin= //TODO
+#banner.image.invert= //TODO
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/banner.txt b/spring-custom-aop/spring-custom-aop/src/main/resources/banner.txt
new file mode 100644
index 0000000000..abfa666eb6
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/banner.txt
@@ -0,0 +1,14 @@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@########@@@@@@@@@@@@@@@@@@@@@@@@...@@@@@@@@@:..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@#. @@@@@* *@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@#o @@@@@* @@@@@* @@@:*.*@@@@@@@: *8@@@ @@@@&:.#@. @o**@@@@**:@o*o@@:.:@@@@@:.o#@&*:@@@@
+@@@@@@@@@@@@* @@@@@* 8888 8@ @@@8 #@o 8@# .@ @@* :. @* @@@@ @. : &@ ** .@@@@
+@@@@@@@@@@. @ o@@@@@* *@@@o::& .* 8@@@@. @@ 8@@@@. @* @@@@ @. @@@& * @@@@# .@@@@
+@@@@@@@@@& @ @@@@@@* @@@@@@ 8 @@@@ .. o&&&&&&& @@ #@@@@. @* @@@@ @. @@@# * @@@@@ .@@@@
+@@@@@@@@@ @@o @@@@@@@* oooo* 8 @@@& @* @@@ # 88. 88. *& o#: @. @@@# *@ & .@@@@
+@@@@@@@@# @@@8 @@@@@@@* .*@@@#. *@@ @@@& :#@@@o .@@: *&@8 @o o@@: @. @@@# *@@#. :8# .@@@@
+@@@@@@@@@ @@@@ &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# o@@@@ @@@@@
+@@@@@& &@@@@ 8@@@@@@@@@8&8@@@@@#8#@@@o8@#&@@o&@@@&@@8@@&@@@@88@@8#@8&@@##@@@@@@#8@@#8@@88@@@@@ *@@@@@@@
+@@@# #@@@@#. @@@@@@@@@@@@@8@@8#o@@@@@o.@o*@@*.@@@.@&:8o8*@@@8&@@#@@@8@@@@8@#@@@8&@@@@@@#@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/custom.properties b/spring-custom-aop/spring-custom-aop/src/main/resources/custom.properties
new file mode 100644
index 0000000000..34f31bcd50
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/custom.properties
@@ -0,0 +1,4 @@
+dispatcher.servlet.name=dispatcherExample
+dispatcher.servlet.mapping=/dispatcherExampleURL
+example.servlet.name=dispatcherExample
+example.servlet.mapping=/dispatcherExampleURL
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/demo.properties b/spring-custom-aop/spring-custom-aop/src/main/resources/demo.properties
new file mode 100644
index 0000000000..649b64f59b
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/demo.properties
@@ -0,0 +1,6 @@
+spring.output.ansi.enabled=never
+server.port=7070
+
+# Security
+security.user.name=admin
+security.user.password=password
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/logback.xml b/spring-custom-aop/spring-custom-aop/src/main/resources/logback.xml
new file mode 100644
index 0000000000..78913ee76f
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/logback.xml
@@ -0,0 +1,14 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/messages.properties b/spring-custom-aop/spring-custom-aop/src/main/resources/messages.properties
new file mode 100644
index 0000000000..e4dbc44c3f
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/messages.properties
@@ -0,0 +1,4 @@
+greeting=Hello! Welcome to our website!
+lang.change=Change the language
+lang.eng=English
+lang.fr=French
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/messages_fr.properties b/spring-custom-aop/spring-custom-aop/src/main/resources/messages_fr.properties
new file mode 100644
index 0000000000..ac5853717d
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/messages_fr.properties
@@ -0,0 +1,4 @@
+greeting=Bonjour! Bienvenue sur notre site!
+lang.change=Changez la langue
+lang.eng=Anglais
+lang.fr=Francais
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/public/error/404.html b/spring-custom-aop/spring-custom-aop/src/main/resources/public/error/404.html
new file mode 100644
index 0000000000..df83ce219b
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/public/error/404.html
@@ -0,0 +1,8 @@
+
+
+ RESOURCE NOT FOUND
+
+
+ 404 RESOURCE NOT FOUND
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/index.html b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/index.html
new file mode 100644
index 0000000000..2c4387ed10
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/index.html
@@ -0,0 +1,19 @@
+
+
+ WebJars Demo
+
+
+
+
+
+
+
×
+
Success! It is working as we expected.
+
+
+
+
+
+
+
+
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/international.html b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/international.html
new file mode 100644
index 0000000000..a2a5fbb591
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/international.html
@@ -0,0 +1,29 @@
+
+
+
+
+Home
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/other.html b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/other.html
new file mode 100644
index 0000000000..d13373f9fe
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/other.html
@@ -0,0 +1,16 @@
+
+
+
+
+Spring Utils Demo
+
+
+
+ Parameter set by you:
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/utils.html b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/utils.html
new file mode 100644
index 0000000000..93030f424f
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/resources/templates/utils.html
@@ -0,0 +1,23 @@
+
+
+
+
+Spring Utils Demo
+
+
+
+
+
+Another Page
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/context.xml b/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/context.xml
new file mode 100644
index 0000000000..263bed4430
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/context.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml b/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml
new file mode 100644
index 0000000000..ade8e66777
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/web.xml b/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..60a4b079de
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+
+
+ JSP
+
+ index.html
+ index.htm
+ index.jsp
+
+
+
+
+ EEWebXmlServlet
+ com.baeldung.servlets.javaee.EEWebXmlServlet
+
+
+
+ EEWebXmlServlet
+ /eewebxmlservlet
+
+
+
+
+ SpringBootWebXmlServlet
+ org.springframework.web.servlet.DispatcherServlet
+
+ contextConfigLocation
+ /WEB-INF/dispatcher.xml
+
+ 1
+
+
+
+ SpringBootWebXmlServlet
+ /
+
+
+
+
diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/annotationservlet.jsp b/spring-custom-aop/spring-custom-aop/src/main/webapp/annotationservlet.jsp
new file mode 100644
index 0000000000..f21748df50
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/webapp/annotationservlet.jsp
@@ -0,0 +1 @@
+Annotation Servlet!
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/index.jsp b/spring-custom-aop/spring-custom-aop/src/main/webapp/index.jsp
new file mode 100644
index 0000000000..e534282777
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/webapp/index.jsp
@@ -0,0 +1 @@
+Hello!
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java
new file mode 100644
index 0000000000..8d5eb56bf4
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java
@@ -0,0 +1,65 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+
+import static org.junit.Assert.*;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootAnnotatedApp.class)
+@AutoConfigureMockMvc
+@TestPropertySource(properties = { "security.basic.enabled=false" })
+public class SpringBootWithServletComponentIntegrationTest {
+
+ @Autowired private ServletContext servletContext;
+
+ @Test
+ public void givenServletContext_whenAccessAttrs_thenFoundAttrsPutInServletListner() {
+ assertNotNull(servletContext);
+ assertNotNull(servletContext.getAttribute("servlet-context-attr"));
+ assertEquals("test", servletContext.getAttribute("servlet-context-attr"));
+ }
+
+ @Test
+ public void givenServletContext_whenCheckHelloFilterMappings_thenCorrect() {
+ assertNotNull(servletContext);
+ FilterRegistration filterRegistration = servletContext.getFilterRegistration("hello filter");
+
+ assertNotNull(filterRegistration);
+ assertTrue(filterRegistration
+ .getServletNameMappings()
+ .contains("echo servlet"));
+ }
+
+ @Autowired private TestRestTemplate restTemplate;
+
+ @Test
+ public void givenServletFilter_whenGetHello_thenRequestFiltered() {
+ ResponseEntity responseEntity = this.restTemplate.getForEntity("/hello", String.class);
+ assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
+ assertEquals("filtering hello", responseEntity.getBody());
+ }
+
+ @Test
+ public void givenFilterAndServlet_whenPostEcho_thenEchoFiltered() {
+ ResponseEntity responseEntity = this.restTemplate.postForEntity("/echo", "echo", String.class);
+ assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
+ assertEquals("filtering echo", responseEntity.getBody());
+ }
+
+
+
+}
+
+
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java
new file mode 100644
index 0000000000..64507ad02c
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+
+import static org.junit.Assert.*;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootPlainApp.class)
+@AutoConfigureMockMvc
+@TestPropertySource(properties = { "security.basic.enabled=false" })
+public class SpringBootWithoutServletComponentIntegrationTest {
+
+ @Autowired private ServletContext servletContext;
+
+ @Autowired private TestRestTemplate restTemplate;
+
+ @Test
+ public void givenServletContext_whenAccessAttrs_thenNotFound() {
+ assertNull(servletContext.getAttribute("servlet-context-attr"));
+ }
+
+ @Test
+ public void givenServletFilter_whenGetHello_thenEndpointNotFound() {
+ ResponseEntity responseEntity = this.restTemplate.getForEntity("/hello", String.class);
+ assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode());
+ }
+
+ @Test
+ public void givenServletContext_whenCheckFilterMappings_thenEmpty() {
+ assertNotNull(servletContext);
+ FilterRegistration filterRegistration = servletContext.getFilterRegistration("hello filter");
+
+ assertNull(filterRegistration);
+ }
+
+}
+
+
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java
new file mode 100644
index 0000000000..348d594c05
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.git;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = CommitIdApplication.class)
+public class CommitIdIntegrationTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CommitIdIntegrationTest.class);
+
+ @Value("${git.commit.message.short:UNKNOWN}")
+ private String commitMessage;
+
+ @Value("${git.branch:UNKNOWN}")
+ private String branch;
+
+ @Value("${git.commit.id:UNKNOWN}")
+ private String commitId;
+
+ @Test
+ public void whenInjecting_shouldDisplay() throws Exception {
+
+ LOG.info(commitId);
+ LOG.info(commitMessage);
+ LOG.info(branch);
+
+ assertThat(commitMessage).isNotEqualTo("UNKNOWN");
+
+ assertThat(branch).isNotEqualTo("UNKNOWN");
+
+ assertThat(commitId).isNotEqualTo("UNKNOWN");
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java
new file mode 100644
index 0000000000..af46fe0423
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.intro;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+@TestPropertySource(properties = { "security.basic.enabled=false" })
+public class AppLiveTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void getIndex() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Index Page")));
+ }
+
+ @Test
+ public void getLocal() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("/local")));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerTest.java
new file mode 100644
index 0000000000..7aed45dbb0
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.utils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+
+import com.baeldung.utils.controller.UtilsController;
+
+public class UtilsControllerTest {
+
+ @InjectMocks
+ private UtilsController utilsController;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ this.mockMvc = MockMvcBuilders.standaloneSetup(utilsController)
+ .build();
+
+ }
+
+ @Test
+ public void givenParameter_setRequestParam_andSetSessionAttribute() throws Exception {
+ String param = "testparam";
+ this.mockMvc.perform(
+ post("/setParam")
+ .param("param", param)
+ .sessionAttr("parameter", param))
+ .andExpect(status().isOk());
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java
new file mode 100644
index 0000000000..d6e71dcf6b
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java
@@ -0,0 +1,18 @@
+package com.baeldung.webjar;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = WebjarsdemoApplication.class)
+@WebAppConfiguration
+public class WebjarsdemoApplicationIntegrationTest {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java
new file mode 100644
index 0000000000..87c59a4662
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java
@@ -0,0 +1,66 @@
+package org.baeldung;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+
+import org.baeldung.domain.Modes;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.nio.charset.Charset;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = Application.class)
+@WebAppConfiguration
+public class SpringBootApplicationIntegrationTest {
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+ private MockMvc mockMvc;
+
+ @Before
+ public void setupMockMvc() {
+ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
+ }
+
+ @Test
+ public void givenRequestHasBeenMade_whenMeetsAllOfGivenConditions_thenCorrect() throws Exception {
+ MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType)).andExpect(jsonPath("$", hasSize(4)));
+ }
+
+ @Test
+ public void givenRequestHasBeenMade_whenMeetsFindByDateOfGivenConditions_thenCorrect() throws Exception {
+ MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbydate/{date}", "2011-12-03T10:15:30")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType))
+ .andExpect(jsonPath("$.id", equalTo(1)));
+ }
+
+ @Test
+ public void givenRequestHasBeenMade_whenMeetsFindByModeOfGivenConditions_thenCorrect() throws Exception {
+ MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbymode/{mode}", Modes.ALPHA.name())).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType)).andExpect(jsonPath("$.id", equalTo(1)));
+ }
+
+ @Test
+ public void givenRequestHasBeenMade_whenMeetsFindByVersionOfGivenConditions_thenCorrect() throws Exception {
+ MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbyversion").header("Version", "1.0.0")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType))
+ .andExpect(jsonPath("$.id", equalTo(1)));
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java
new file mode 100644
index 0000000000..d4b19e6a1d
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java
@@ -0,0 +1,27 @@
+package org.baeldung;
+
+import org.baeldung.domain.GenericEntity;
+import org.baeldung.repository.GenericEntityRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = Application.class)
+public class SpringBootJPAIntegrationTest {
+ @Autowired
+ private GenericEntityRepository genericEntityRepository;
+
+ @Test
+ public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
+ GenericEntity genericEntity = genericEntityRepository.save(new GenericEntity("test"));
+ GenericEntity foundedEntity = genericEntityRepository.findOne(genericEntity.getId());
+ assertNotNull(foundedEntity);
+ assertEquals(genericEntity.getValue(), foundedEntity.getValue());
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java
new file mode 100644
index 0000000000..10e3d6d60b
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java
@@ -0,0 +1,81 @@
+package org.baeldung;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.context.WebApplicationContext;
+import org.subethamail.wiser.Wiser;
+import org.subethamail.wiser.WiserMessage;
+
+import javax.mail.MessagingException;
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = Application.class)
+public class SpringBootMailIntegrationTest {
+ @Autowired
+ private JavaMailSender javaMailSender;
+
+ private Wiser wiser;
+
+ private String userTo = "user2@localhost";
+ private String userFrom = "user1@localhost";
+ private String subject = "Test subject";
+ private String textMail = "Text subject mail";
+
+ @Before
+ public void setUp() throws Exception {
+ final int TEST_PORT = 8025;
+ wiser = new Wiser(TEST_PORT);
+ wiser.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ wiser.stop();
+ }
+
+ @Test
+ public void givenMail_whenSendAndReceived_thenCorrect() throws Exception {
+ SimpleMailMessage message = composeEmailMessage();
+ javaMailSender.send(message);
+ List messages = wiser.getMessages();
+
+ assertThat(messages, hasSize(1));
+ WiserMessage wiserMessage = messages.get(0);
+ assertEquals(userFrom, wiserMessage.getEnvelopeSender());
+ assertEquals(userTo, wiserMessage.getEnvelopeReceiver());
+ assertEquals(subject, getSubject(wiserMessage));
+ assertEquals(textMail, getMessage(wiserMessage));
+ }
+
+ private String getMessage(WiserMessage wiserMessage) throws MessagingException, IOException {
+ return wiserMessage.getMimeMessage().getContent().toString().trim();
+ }
+
+ private String getSubject(WiserMessage wiserMessage) throws MessagingException {
+ return wiserMessage.getMimeMessage().getSubject();
+ }
+
+ private SimpleMailMessage composeEmailMessage() {
+ SimpleMailMessage mailMessage = new SimpleMailMessage();
+ mailMessage.setTo(userTo);
+ mailMessage.setReplyTo(userFrom);
+ mailMessage.setFrom(userFrom);
+ mailMessage.setSubject(subject);
+ mailMessage.setText(textMail);
+ return mailMessage;
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java
new file mode 100644
index 0000000000..57a8abc1ee
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java
@@ -0,0 +1,17 @@
+package org.baeldung.boot;
+
+import org.baeldung.session.exception.Application;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = Application.class)
+@TestPropertySource("classpath:exception.properties")
+public class ApplicationIntegrationTest {
+ @Test
+ public void contextLoads() {
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java
new file mode 100644
index 0000000000..4fcea35b4a
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java
@@ -0,0 +1,17 @@
+package org.baeldung.boot;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = DemoApplication.class)
+@WebAppConfiguration
+public class DemoApplicationIntegrationTest {
+
+ @Test
+ public void contextLoads() {
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentTests.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentTests.java
new file mode 100644
index 0000000000..72ccc0bfb8
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentTests.java
@@ -0,0 +1,70 @@
+package org.baeldung.boot;
+
+import org.baeldung.boot.components.FooService;
+import org.baeldung.boot.model.Foo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(
+ classes = DemoApplication.class,
+ webEnvironment = WebEnvironment.RANDOM_PORT)
+public class FooComponentTests {
+
+ @Autowired
+ private TestRestTemplate testRestTemplate;
+
+ @SpyBean
+ private FooService fooService;
+
+ @Before
+ public void init() throws Exception {
+ Foo foo = new Foo();
+ foo.setId(5);
+ foo.setName("MOCKED_FOO");
+
+ doReturn(foo).when(fooService).getFooWithId(anyInt());
+
+ // doCallRealMethod().when(fooComponent).getFooWithName(anyString());
+ }
+
+ @Test
+ public void givenInquiryingFooWithId_whenFooComponentIsMocked_thenAssertMockedResult() {
+ Map pathVariables = new HashMap<>();
+ pathVariables.put("id", "1");
+ ResponseEntity fooResponse = testRestTemplate.getForEntity("/{id}", Foo.class, pathVariables);
+
+ assertNotNull(fooResponse);
+ assertEquals(HttpStatus.OK, fooResponse.getStatusCode());
+ assertEquals(5, fooResponse.getBody().getId().longValue());
+ assertEquals("MOCKED_FOO", fooResponse.getBody().getName());
+ }
+
+ @Test
+ public void givenInquiryingFooWithName_whenFooComponentIsMocked_thenAssertMockedResult() {
+ Map pathVariables = new HashMap<>();
+ pathVariables.put("name", "Foo_Name");
+ ResponseEntity fooResponse = testRestTemplate.getForEntity("/?name={name}", Foo.class, pathVariables);
+
+ assertNotNull(fooResponse);
+ assertEquals(HttpStatus.OK, fooResponse.getStatusCode());
+ assertEquals(1, fooResponse.getBody().getId().longValue());
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java
new file mode 100644
index 0000000000..932cce26d5
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java
@@ -0,0 +1,43 @@
+package org.baeldung.boot;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.baeldung.boot.DemoApplication;
+import org.baeldung.boot.model.Foo;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes=DemoApplication.class,webEnvironment = WebEnvironment.RANDOM_PORT)
+public class FooIntegrationTest {
+
+ @Autowired
+ private TestRestTemplate testRestTemplate;
+
+
+ @Test
+ public void givenInquiryingFooWithId_whenIdIsValid_thenHttpStatusOK(){
+ Map pathVariables = new HashMap();
+ pathVariables.put("id", "1");
+ ResponseEntity fooResponse = testRestTemplate.getForEntity("/{id}", Foo.class, pathVariables);
+ Assert.assertNotNull(fooResponse);
+ Assert.assertEquals(HttpStatus.OK,fooResponse.getStatusCode());
+ }
+
+ @Test
+ public void givenInquiryingFooWithName_whenNameIsValid_thenHttpStatusOK(){
+ Map pathVariables = new HashMap();
+ pathVariables.put("name", "Foo_Name");
+ ResponseEntity fooResponse = testRestTemplate.getForEntity("/?name={name}", Foo.class, pathVariables);
+ Assert.assertNotNull(fooResponse);
+ Assert.assertEquals(HttpStatus.OK,fooResponse.getStatusCode());
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPATest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPATest.java
new file mode 100644
index 0000000000..c29aa64e6c
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPATest.java
@@ -0,0 +1,34 @@
+package org.baeldung.boot;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.baeldung.boot.model.Foo;
+import org.baeldung.boot.repository.FooRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class FooJPATest {
+
+ @Autowired
+ private TestEntityManager entityManager;
+
+ @Autowired
+ private FooRepository repository;
+
+ @Test
+ public void findFooByName() {
+ this.entityManager.persist(new Foo("Foo_Name_2"));
+ Foo foo = this.repository.findByName("Foo_Name_2");
+ assertNotNull(foo);
+ assertEquals("Foo_Name_2",foo.getName());
+ // Due to having Insert query for Foo with Id 1, so TestEntityManager generates new Id of 2
+ assertEquals(2l,foo.getId().longValue());
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonTest.java
new file mode 100644
index 0000000000..2789ed0a8c
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonTest.java
@@ -0,0 +1,35 @@
+package org.baeldung.boot;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.baeldung.boot.model.Foo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.json.JsonTest;
+import org.springframework.boot.test.json.JacksonTester;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@JsonTest
+public class FooJsonTest {
+
+ @Autowired
+ private JacksonTester json;
+
+
+ @Test
+ public void testSerialize() throws Exception {
+ Foo foo = new Foo(3, "Foo_Name_3");
+ assertThat(this.json.write(foo)).isEqualToJson("expected.json");
+ assertThat(this.json.write(foo)).hasJsonPathStringValue("@.name");
+ assertThat(this.json.write(foo)).extractingJsonPathStringValue("@.name").isEqualTo("Foo_Name_3");
+ }
+
+ @Test
+ public void testDeserialize() throws Exception {
+ String content = "{\"id\":4,\"name\":\"Foo_Name_4\"}";
+ assertThat(this.json.parseObject(content).getName()).isEqualTo("Foo_Name_4");
+ assertThat(this.json.parseObject(content).getId()==4);
+ }
+}
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..a844b26b2d
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java
@@ -0,0 +1,34 @@
+package org.baeldung.boot.repository;
+
+import static org.junit.Assert.assertThat;
+
+import org.baeldung.boot.DemoApplicationIntegrationTest;
+import org.baeldung.boot.model.Foo;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.is;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class FooRepositoryIntegrationTest extends DemoApplicationIntegrationTest {
+ @Autowired
+ private FooRepository fooRepository;
+
+ @Before
+ public void setUp() {
+ fooRepository.save(new Foo("Foo"));
+ fooRepository.save(new Foo("Bar"));
+ }
+
+ @Test
+ public void testFindByName() {
+ Foo foo = fooRepository.findByName("Bar");
+ assertThat(foo, notNullValue());
+ assertThat(foo.getId(), is(2));
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java
new file mode 100644
index 0000000000..be992bcc36
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java
@@ -0,0 +1,32 @@
+package org.baeldung.boot.repository;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import org.baeldung.boot.ApplicationIntegrationTest;
+import org.baeldung.boot.model.Foo;
+import org.baeldung.session.exception.repository.FooRepository;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+@TestPropertySource("classpath:exception-hibernate.properties")
+public class HibernateSessionIntegrationTest extends ApplicationIntegrationTest {
+ @Autowired
+ private FooRepository fooRepository;
+
+ @Test
+ public void whenSavingWithCurrentSession_thenThrowNoException() {
+ Foo foo = new Foo("Exception Solved");
+ fooRepository.save(foo);
+ foo = null;
+ foo = fooRepository.get(1);
+
+ assertThat(foo, notNullValue());
+ assertThat(foo.getId(), is(1));
+ assertThat(foo.getName(), is("Exception Solved"));
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java
new file mode 100644
index 0000000000..55b7fa7216
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.boot.repository;
+
+import org.baeldung.boot.ApplicationIntegrationTest;
+import org.baeldung.boot.model.Foo;
+import org.baeldung.session.exception.repository.FooRepository;
+import org.hibernate.HibernateException;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class NoHibernateSessionIntegrationTest extends ApplicationIntegrationTest {
+ @Autowired
+ private FooRepository fooRepository;
+
+ @Test(expected = HibernateException.class)
+ public void whenSavingWithoutCurrentSession_thenThrowException() {
+ Foo foo = new Foo("Exception Thrown");
+ fooRepository.save(foo);
+ }
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java
new file mode 100644
index 0000000000..5627855aa3
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java
@@ -0,0 +1,46 @@
+package org.baeldung.client;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.client.MockRestServiceServer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
+
+@RunWith(SpringRunner.class)
+@RestClientTest(DetailsServiceClient.class)
+public class DetailsServiceClientIntegrationTest {
+
+ @Autowired
+ private DetailsServiceClient client;
+
+ @Autowired
+ private MockRestServiceServer server;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Before
+ public void setUp() throws Exception {
+ String detailsString = objectMapper.writeValueAsString(new Details("John Smith", "john"));
+ this.server.expect(requestTo("/john/details")).andRespond(withSuccess(detailsString, MediaType.APPLICATION_JSON));
+ }
+
+ @Test
+ public void whenCallingGetUserDetails_thenClientExecutesCorrectCall() throws Exception {
+
+ Details details = this.client.getUserDetails("john");
+
+ assertThat(details.getLogin()).isEqualTo("john");
+ assertThat(details.getName()).isEqualTo("John Smith");
+
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/application.properties b/spring-custom-aop/spring-custom-aop/src/test/resources/application.properties
new file mode 100644
index 0000000000..0e6cb86bc5
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/resources/application.properties
@@ -0,0 +1,5 @@
+spring.mail.host=localhost
+spring.mail.port=8025
+spring.mail.properties.mail.smtp.auth=false
+
+security.basic.enabled=false
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/exception-hibernate.properties b/spring-custom-aop/spring-custom-aop/src/test/resources/exception-hibernate.properties
new file mode 100644
index 0000000000..cde746acb9
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/resources/exception-hibernate.properties
@@ -0,0 +1,2 @@
+spring.profiles.active=exception
+spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/exception.properties b/spring-custom-aop/spring-custom-aop/src/test/resources/exception.properties
new file mode 100644
index 0000000000..c55e415a3a
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/resources/exception.properties
@@ -0,0 +1,6 @@
+# Security
+security.user.name=admin
+security.user.password=password
+
+spring.dao.exceptiontranslation.enabled=false
+spring.profiles.active=exception
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/import.sql b/spring-custom-aop/spring-custom-aop/src/test/resources/import.sql
new file mode 100644
index 0000000000..a382410271
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/resources/import.sql
@@ -0,0 +1 @@
+Insert into Foo values(1,'Foo_Name');
\ No newline at end of file
diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json b/spring-custom-aop/spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json
new file mode 100644
index 0000000000..f5409421a6
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json
@@ -0,0 +1,4 @@
+{
+ "id":3,
+ "name":"Foo_Name_3"
+}
\ No newline at end of file