From cd89253474a9ab6ba174c5b79ee9d8aeffe107f1 Mon Sep 17 00:00:00 2001 From: Cavero Barca Date: Mon, 14 Sep 2020 23:58:12 +0200 Subject: [PATCH 01/24] Create the layers configuration, modify the pom and Dockerfile --- docker/docker-spring-boot/pom.xml | 1 + docker/docker-spring-boot/src/layers.xml | 27 +++++++++++++++++++ .../src/main/docker/Dockerfile | 1 + 3 files changed, 29 insertions(+) create mode 100644 docker/docker-spring-boot/src/layers.xml diff --git a/docker/docker-spring-boot/pom.xml b/docker/docker-spring-boot/pom.xml index b9c80bc43a..e8f6c134b1 100644 --- a/docker/docker-spring-boot/pom.xml +++ b/docker/docker-spring-boot/pom.xml @@ -45,6 +45,7 @@ true + ${project.basedir}/src/layers.xml diff --git a/docker/docker-spring-boot/src/layers.xml b/docker/docker-spring-boot/src/layers.xml new file mode 100644 index 0000000000..61c9bd9c39 --- /dev/null +++ b/docker/docker-spring-boot/src/layers.xml @@ -0,0 +1,27 @@ + + + + org/springframework/boot/loader/** + + + + + + *:*:*SNAPSHOT + + + com.baeldung.docker:*:* + + + + + dependencies + spring-boot-loader + internal-dependencies + snapshot-dependencies + application + + \ No newline at end of file diff --git a/docker/docker-spring-boot/src/main/docker/Dockerfile b/docker/docker-spring-boot/src/main/docker/Dockerfile index fa147dd69b..663cc94490 100644 --- a/docker/docker-spring-boot/src/main/docker/Dockerfile +++ b/docker/docker-spring-boot/src/main/docker/Dockerfile @@ -10,6 +10,7 @@ RUN java -Djarmode=layertools -jar application.jar extract FROM adoptopenjdk:11-jre-hotspot COPY --from=builder dependencies/ ./ COPY --from=builder snapshot-dependencies/ ./ +COPY --from=builder internal-dependencies/ ./ COPY --from=builder spring-boot-loader/ ./ COPY --from=builder application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file From f84e6099381ef89d4c2276a5fe878e939be04ece Mon Sep 17 00:00:00 2001 From: Cavero Barca Date: Tue, 22 Sep 2020 01:08:21 +0200 Subject: [PATCH 02/24] Add a new project with dependencies to separate the layers --- docker/docker-internal-dto/pom.xml | 14 +++++++++ .../java/com/baeldung/docker/VariableDto.java | 14 +++++++++ docker/docker-spring-boot/pom.xml | 28 ++++++++++------- .../src/main/docker/Dockerfile | 4 +-- docker/pom.xml | 30 +++++++++++++++++++ 5 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 docker/docker-internal-dto/pom.xml create mode 100644 docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java create mode 100644 docker/pom.xml diff --git a/docker/docker-internal-dto/pom.xml b/docker/docker-internal-dto/pom.xml new file mode 100644 index 0000000000..d7ba6d7373 --- /dev/null +++ b/docker/docker-internal-dto/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + com.baeldung.docker + docker-spring-boot-parent + 0.0.1 + + + docker-internal-dto + + \ No newline at end of file diff --git a/docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java b/docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java new file mode 100644 index 0000000000..86e173e351 --- /dev/null +++ b/docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java @@ -0,0 +1,14 @@ +package com.baeldung.docker; + +public class VariableDto { + + private final String value; + + public VariableDto(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/docker/docker-spring-boot/pom.xml b/docker/docker-spring-boot/pom.xml index e8f6c134b1..9524f68a5a 100644 --- a/docker/docker-spring-boot/pom.xml +++ b/docker/docker-spring-boot/pom.xml @@ -1,21 +1,21 @@ - + 4.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.3.1.RELEASE - + com.baeldung.docker + docker-spring-boot-parent + 0.0.1 - com.baeldung.docker - spring-boot-docker - 0.0.1-SNAPSHOT - spring-boot-docker + + docker-spring-boot + + docker-spring-boot Demo project showing Spring Boot and Docker - 8 + 11 @@ -24,6 +24,12 @@ spring-boot-starter-web + + com.baeldung.docker + docker-internal-dto + 0.0.1 + + org.springframework.boot spring-boot-starter-test diff --git a/docker/docker-spring-boot/src/main/docker/Dockerfile b/docker/docker-spring-boot/src/main/docker/Dockerfile index 663cc94490..c0fd9c9cdb 100644 --- a/docker/docker-spring-boot/src/main/docker/Dockerfile +++ b/docker/docker-spring-boot/src/main/docker/Dockerfile @@ -9,8 +9,8 @@ RUN java -Djarmode=layertools -jar application.jar extract FROM adoptopenjdk:11-jre-hotspot COPY --from=builder dependencies/ ./ -COPY --from=builder snapshot-dependencies/ ./ -COPY --from=builder internal-dependencies/ ./ COPY --from=builder spring-boot-loader/ ./ +COPY --from=builder internal-dependencies/ ./ +COPY --from=builder snapshot-dependencies/ ./ COPY --from=builder application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] \ No newline at end of file diff --git a/docker/pom.xml b/docker/pom.xml new file mode 100644 index 0000000000..3668ceb0fc --- /dev/null +++ b/docker/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.3.1.RELEASE + + + + com.baeldung.docker + docker-spring-boot-parent + 0.0.1 + docker-spring-boot-parent + Demo project showing Spring Boot and Docker + pom + + + 11 + + + + docker-internal-dto + docker-spring-boot + + + From b5e0e559e370178199efda67e5509d60bdecac64 Mon Sep 17 00:00:00 2001 From: sharifi Date: Sat, 3 Oct 2020 11:32:38 +0330 Subject: [PATCH 03/24] add new module to parent pom --- spring-boot-modules/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index fa70a9f058..19dfcbb962 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -26,6 +26,7 @@ spring-boot-artifacts spring-boot-autoconfiguration spring-boot-basic-customization + spring-boot-basic-customization-2 spring-boot-bootstrap spring-boot-client spring-boot-config-jpa-error From 7e56ea33036c8748faa9748244cc7a01ba7c9e24 Mon Sep 17 00:00:00 2001 From: sharifi Date: Sat, 3 Oct 2020 11:33:33 +0330 Subject: [PATCH 04/24] add README file --- .../spring-boot-basic-customization-2/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/README.md diff --git a/spring-boot-modules/spring-boot-basic-customization-2/README.md b/spring-boot-modules/spring-boot-basic-customization-2/README.md new file mode 100644 index 0000000000..faaee0962e --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/README.md @@ -0,0 +1,7 @@ +## Spring Boot Basic Customization 2 + +This module contains articles about Spring Boot customization 2 + +### Relevant Articles: + + - [DispatcherServlet and web.xml in Spring Boot](https://www.baeldung.com/) From 7ffa8ce6a521c5570b305469f8fd7220f1f3e089 Mon Sep 17 00:00:00 2001 From: sharifi Date: Sat, 3 Oct 2020 11:33:57 +0330 Subject: [PATCH 05/24] add gitignore file --- .../.gitignore | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/.gitignore diff --git a/spring-boot-modules/spring-boot-basic-customization-2/.gitignore b/spring-boot-modules/spring-boot-basic-customization-2/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file From 17d3411f7c61ef40446e397b55a6f2cd4ed9dc55 Mon Sep 17 00:00:00 2001 From: sharifi Date: Sat, 3 Oct 2020 11:35:16 +0330 Subject: [PATCH 06/24] add main source --- .../spring-boot-basic-customization-2/pom.xml | 33 +++++++++++++++++++ .../com.baeldung.demo/DemoApplication.java | 15 +++++++++ .../java/com.baeldung.demo/conf/WebConf.java | 29 ++++++++++++++++ .../controller/Controller.java | 15 +++++++++ .../filter/CustomFilter.java | 30 +++++++++++++++++ .../listener/CustomListener.java | 22 +++++++++++++ .../servlet/CustomServlet.java | 29 ++++++++++++++++ .../src/main/resources/application.properties | 2 ++ 8 files changed, 175 insertions(+) create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/pom.xml create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties diff --git a/spring-boot-modules/spring-boot-basic-customization-2/pom.xml b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml new file mode 100644 index 0000000000..3ce9266ebe --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + ../ + + + spring-boot-basic-customization-2 + jar + + spring-boot-basic-customization-2 + Module For Spring Boot Basic Customization 2 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java new file mode 100644 index 0000000000..9e8148f043 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.context.annotation.Configuration; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java new file mode 100644 index 0000000000..02fcf152f1 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java @@ -0,0 +1,29 @@ +package com.baeldung.demo.conf; + +import com.baeldung.demo.listener.CustomListener; +import com.baeldung.demo.servlet.CustomServlet; +import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.ServletContextListener; + +@Configuration +public class WebConf { + + @Bean + public ServletRegistrationBean customServletBean() { + ServletRegistrationBean bean = + new ServletRegistrationBean(new CustomServlet(), "/servlet"); + return bean; + } + + @Bean + public ServletListenerRegistrationBean customListenerBean() { + ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(); + bean.setListener(new CustomListener()); + return bean; + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java new file mode 100644 index 0000000000..a6d1812511 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java @@ -0,0 +1,15 @@ +package com.baeldung.demo.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/") +public class Controller { + + @GetMapping + public String getRequest(){ + return "Baeldung DispatcherServlet"; + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java new file mode 100644 index 0000000000..c661aecf6d --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java @@ -0,0 +1,30 @@ +package com.baeldung.demo.filter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import java.io.IOException; + +@Component +public class CustomFilter implements Filter { + + Logger logger = LoggerFactory.getLogger(CustomFilter.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + logger.info("CustomFilter is invoked"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java new file mode 100644 index 0000000000..a9e3ad680f --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java @@ -0,0 +1,22 @@ +package com.baeldung.demo.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +public class CustomListener implements ServletContextListener { + + Logger logger = LoggerFactory.getLogger(CustomListener.class); + + @Override + public void contextInitialized(ServletContextEvent sce) { + logger.info("CustomListener is initialized"); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + logger.info("CustomListener is destroyed"); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java new file mode 100644 index 0000000000..fd3e92bedc --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java @@ -0,0 +1,29 @@ +package com.baeldung.demo.servlet; + +import com.baeldung.demo.filter.CustomFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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; + +public class CustomServlet extends HttpServlet { + + Logger logger = LoggerFactory.getLogger(CustomServlet.class); + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + logger.info("CustomServlet doGet() method is invoked"); + super.doGet(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + logger.info("CustomServlet doPost() method is invoked"); + super.doPost(req, resp); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties new file mode 100644 index 0000000000..8c4690dedc --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties @@ -0,0 +1,2 @@ +server.servlet.context-path=/demo +spring.mvc.servlet.path=/baeldung \ No newline at end of file From da6fb652fbf0c732dd7a0a4d34736a15d06aa343 Mon Sep 17 00:00:00 2001 From: sharifi Date: Fri, 9 Oct 2020 11:36:07 +0330 Subject: [PATCH 07/24] remove gitignore file --- .../.gitignore | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/.gitignore diff --git a/spring-boot-modules/spring-boot-basic-customization-2/.gitignore b/spring-boot-modules/spring-boot-basic-customization-2/.gitignore deleted file mode 100644 index 2af7cefb0a..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -nbproject/private/ -build/ -nbbuild/ -dist/ -nbdist/ -.nb-gradle/ \ No newline at end of file From 5cb3bc85bea94ab6414df0e218ec0c7898f27d55 Mon Sep 17 00:00:00 2001 From: sharifi Date: Fri, 9 Oct 2020 11:48:10 +0330 Subject: [PATCH 08/24] change package name and main class's name --- .../DispatchServletApplication.java} | 6 +++--- .../conf/WebConf.java | 6 +++--- .../controller/Controller.java | 2 +- .../filter/CustomFilter.java | 2 +- .../listener/CustomListener.java | 2 +- .../servlet/CustomServlet.java | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) rename spring-boot-modules/spring-boot-basic-customization-2/src/main/java/{com.baeldung.demo/DemoApplication.java => com.baeldung.dispatchservlet/DispatchServletApplication.java} (68%) rename spring-boot-modules/spring-boot-basic-customization-2/src/main/java/{com.baeldung.demo => com.baeldung.dispatchservlet}/conf/WebConf.java (83%) rename spring-boot-modules/spring-boot-basic-customization-2/src/main/java/{com.baeldung.demo => com.baeldung.dispatchservlet}/controller/Controller.java (88%) rename spring-boot-modules/spring-boot-basic-customization-2/src/main/java/{com.baeldung.demo => com.baeldung.dispatchservlet}/filter/CustomFilter.java (93%) rename spring-boot-modules/spring-boot-basic-customization-2/src/main/java/{com.baeldung.demo => com.baeldung.dispatchservlet}/listener/CustomListener.java (92%) rename spring-boot-modules/spring-boot-basic-customization-2/src/main/java/{com.baeldung.demo => com.baeldung.dispatchservlet}/servlet/CustomServlet.java (89%) diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java similarity index 68% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java index 9e8148f043..4d58715d88 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/DemoApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java @@ -1,4 +1,4 @@ -package com.baeldung.demo; +package com.baeldung.dispatchservlet; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -6,10 +6,10 @@ import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.Configuration; @SpringBootApplication -public class DemoApplication { +public class DispatchServletApplication { public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); + SpringApplication.run(DispatchServletApplication.class, args); } } diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java similarity index 83% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java index 02fcf152f1..9a1170ca34 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/conf/WebConf.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java @@ -1,7 +1,7 @@ -package com.baeldung.demo.conf; +package com.baeldung.dispatchservlet.conf; -import com.baeldung.demo.listener.CustomListener; -import com.baeldung.demo.servlet.CustomServlet; +import com.baeldung.dispatchservlet.listener.CustomListener; +import com.baeldung.dispatchservlet.servlet.CustomServlet; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java similarity index 88% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java index a6d1812511..14d71c60fb 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/controller/Controller.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java @@ -1,4 +1,4 @@ -package com.baeldung.demo.controller; +package com.baeldung.dispatchservlet.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java similarity index 93% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java index c661aecf6d..8429fc855f 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/filter/CustomFilter.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java @@ -1,4 +1,4 @@ -package com.baeldung.demo.filter; +package com.baeldung.dispatchservlet.filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java similarity index 92% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java index a9e3ad680f..62b316c012 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/listener/CustomListener.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java @@ -1,4 +1,4 @@ -package com.baeldung.demo.listener; +package com.baeldung.dispatchservlet.listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java similarity index 89% rename from spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java index fd3e92bedc..2a99e797ce 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.demo/servlet/CustomServlet.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java @@ -1,6 +1,6 @@ -package com.baeldung.demo.servlet; +package com.baeldung.dispatchservlet.servlet; -import com.baeldung.demo.filter.CustomFilter; +import com.baeldung.dispatchservlet.filter.CustomFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; From 271ad4e3c7224b1ea65fe66146767622598832fe Mon Sep 17 00:00:00 2001 From: sharifi Date: Fri, 9 Oct 2020 11:48:57 +0330 Subject: [PATCH 09/24] remove context-path and path --- .../src/main/resources/application.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties index 8c4690dedc..e69de29bb2 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties @@ -1,2 +0,0 @@ -server.servlet.context-path=/demo -spring.mvc.servlet.path=/baeldung \ No newline at end of file From b447b94b5037f2c9078d2104d4b92e7759eefbfc Mon Sep 17 00:00:00 2001 From: "amit.pandey" Date: Sun, 11 Oct 2020 16:26:31 +0530 Subject: [PATCH 10/24] moved spring-rest-compress module to spring-resttemplate-2 module --- spring-resttemplate-2/README.md | 1 + spring-resttemplate-2/pom.xml | 23 ++++++++ ...mpressingClientHttpRequestInterceptor.java | 38 +++++++++++++ .../java/com/baeldung/compress/GzipUtils.java | 52 +++++++++++++++++ .../compress/JettyWebServerConfiguration.java | 38 +++++++++++++ .../java/com/baeldung/compress/Message.java | 29 ++++++++++ .../baeldung/compress/MessageController.java | 38 +++++++++++++ .../compress/RestTemplateConfiguration.java | 21 +++++++ .../SpringCompressRequestApplication.java | 15 +++++ .../baeldung/compress/GzipUtilsUnitTest.java | 19 +++++++ .../compress/MessageControllerUnitTest.java | 56 +++++++++++++++++++ 11 files changed, 330 insertions(+) create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/CompressingClientHttpRequestInterceptor.java create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/GzipUtils.java create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/JettyWebServerConfiguration.java create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/Message.java create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/MessageController.java create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/RestTemplateConfiguration.java create mode 100644 spring-resttemplate-2/src/main/java/com/baeldung/compress/SpringCompressRequestApplication.java create mode 100644 spring-resttemplate-2/src/test/java/com/baeldung/compress/GzipUtilsUnitTest.java create mode 100644 spring-resttemplate-2/src/test/java/com/baeldung/compress/MessageControllerUnitTest.java diff --git a/spring-resttemplate-2/README.md b/spring-resttemplate-2/README.md index e1e0ba40b0..37d8ac9740 100644 --- a/spring-resttemplate-2/README.md +++ b/spring-resttemplate-2/README.md @@ -8,3 +8,4 @@ This module contains articles about Spring RestTemplate - [Proxies With RestTemplate](https://www.baeldung.com/java-resttemplate-proxy) - [A Custom Media Type for a Spring REST API](https://www.baeldung.com/spring-rest-custom-media-type) - [RestTemplate Post Request with JSON](https://www.baeldung.com/spring-resttemplate-post-json) +- [How to compress requests using the Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-compressing-requests) diff --git a/spring-resttemplate-2/pom.xml b/spring-resttemplate-2/pom.xml index b1d6f60c53..2aed154be6 100644 --- a/spring-resttemplate-2/pom.xml +++ b/spring-resttemplate-2/pom.xml @@ -20,7 +20,30 @@ org.springframework.boot spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + org.apache.httpcomponents + httpclient + + + + commons-io + commons-io + ${commons-io.version} + + org.springframework.boot spring-boot-starter-test diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/CompressingClientHttpRequestInterceptor.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/CompressingClientHttpRequestInterceptor.java new file mode 100644 index 0000000000..e880e8f915 --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/CompressingClientHttpRequestInterceptor.java @@ -0,0 +1,38 @@ +package com.baeldung.compress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; + +import java.io.IOException; + +public class CompressingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + + private static final Logger LOG = LoggerFactory.getLogger(CompressingClientHttpRequestInterceptor.class); + + private static final String GZIP_ENCODING = "gzip"; + + /** + * Compress a request body using Gzip and add Http headers. + * + * @param req + * @param body + * @param exec + * @return + * @throws IOException + */ + @Override + public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec) + throws IOException { + LOG.info("Compressing request..."); + HttpHeaders httpHeaders = req.getHeaders(); + httpHeaders.add(HttpHeaders.CONTENT_ENCODING, GZIP_ENCODING); + httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING); + return exec.execute(req, GzipUtils.compress(body)); + } + +} diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/GzipUtils.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/GzipUtils.java new file mode 100644 index 0000000000..50c565d92c --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/GzipUtils.java @@ -0,0 +1,52 @@ +package com.baeldung.compress; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.apache.commons.io.IOUtils; + +public class GzipUtils { + + /** + * Gzip a string. + * + * @param text + * @return + * @throws Exception + */ + public static byte[] compress(String text) throws Exception { + return GzipUtils.compress(text.getBytes(StandardCharsets.UTF_8)); + } + + /** + * Gzip a byte array. + * + * @param body + * @return + * @throws IOException + */ + public static byte[] compress(byte[] body) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) { + gzipOutputStream.write(body); + } + return baos.toByteArray(); + } + + /** + * Decompress a Gzipped byte array to a String. + * + * @param body + * @return + * @throws IOException + */ + public static String decompress(byte[] body) throws IOException { + try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(body))) { + return IOUtils.toString(gzipInputStream, StandardCharsets.UTF_8); + } + } +} diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/JettyWebServerConfiguration.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/JettyWebServerConfiguration.java new file mode 100644 index 0000000000..3ac8c31ab3 --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/JettyWebServerConfiguration.java @@ -0,0 +1,38 @@ +package com.baeldung.compress; + +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.server.handler.gzip.GzipHandler; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configure Jetty web server so it handles compressed requests. + */ +@Configuration +public class JettyWebServerConfiguration { + + private static final int MIN_BYTES = 1; + + /** + * Customise the Jetty web server to automatically decompress requests. + */ + @Bean + public JettyServletWebServerFactory jettyServletWebServerFactory() { + + JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); + factory.addServerCustomizers(server -> { + + GzipHandler gzipHandler = new GzipHandler(); + // Enable request decompression + gzipHandler.setInflateBufferSize(MIN_BYTES); + gzipHandler.setHandler(server.getHandler()); + + HandlerCollection handlerCollection = new HandlerCollection(gzipHandler); + server.setHandler(handlerCollection); + }); + + return factory; + } + +} diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/Message.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/Message.java new file mode 100644 index 0000000000..f43d06c2fc --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/Message.java @@ -0,0 +1,29 @@ +package com.baeldung.compress; + +public class Message { + + private String text; + + public Message() { + } + + public Message(String text) { + this.text = text; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Message {"); + sb.append("text='").append(text).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/MessageController.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/MessageController.java new file mode 100644 index 0000000000..ec574d9dec --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/MessageController.java @@ -0,0 +1,38 @@ +package com.baeldung.compress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +public class MessageController { + + protected static final String PROCESSED = "Processed "; + + protected static final String REQUEST_MAPPING = "process"; + + private static final Logger LOG = LoggerFactory.getLogger(MessageController.class); + + /** + * A simple endpoint that responds with "Processed " + supplied Message content. + * + * @param headers + * @param message + * @return + */ + @PostMapping(value = REQUEST_MAPPING) + public ResponseEntity processMessage(@RequestHeader Map headers, + @RequestBody Message message) { + + // Print headers + headers.forEach((k, v) -> LOG.info(k + "=" + v)); + + return ResponseEntity.ok(PROCESSED + message.getText()); + } +} diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/RestTemplateConfiguration.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/RestTemplateConfiguration.java new file mode 100644 index 0000000000..12b1e4249e --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/RestTemplateConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.compress; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfiguration { + + /** + * A RestTemplate that compresses requests. + * + * @return RestTemplate + */ + @Bean + public RestTemplate getRestTemplate() { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor()); + return restTemplate; + } +} diff --git a/spring-resttemplate-2/src/main/java/com/baeldung/compress/SpringCompressRequestApplication.java b/spring-resttemplate-2/src/main/java/com/baeldung/compress/SpringCompressRequestApplication.java new file mode 100644 index 0000000000..9ff88ab257 --- /dev/null +++ b/spring-resttemplate-2/src/main/java/com/baeldung/compress/SpringCompressRequestApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.compress; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAutoConfiguration +public class SpringCompressRequestApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringCompressRequestApplication.class, args); + } + +} diff --git a/spring-resttemplate-2/src/test/java/com/baeldung/compress/GzipUtilsUnitTest.java b/spring-resttemplate-2/src/test/java/com/baeldung/compress/GzipUtilsUnitTest.java new file mode 100644 index 0000000000..10c2eeb748 --- /dev/null +++ b/spring-resttemplate-2/src/test/java/com/baeldung/compress/GzipUtilsUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.compress; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class GzipUtilsUnitTest { + + @Test + public void givenCompressedText_whenDecompressed_thenSuccessful() throws Exception { + final String expectedText = "Hello Baeldung!"; + byte[] compressedText = GzipUtils.compress(expectedText); + String decompressedText = GzipUtils.decompress(compressedText); + assertNotNull(compressedText); + assertEquals(expectedText, decompressedText); + } + +} \ No newline at end of file diff --git a/spring-resttemplate-2/src/test/java/com/baeldung/compress/MessageControllerUnitTest.java b/spring-resttemplate-2/src/test/java/com/baeldung/compress/MessageControllerUnitTest.java new file mode 100644 index 0000000000..643e3f6881 --- /dev/null +++ b/spring-resttemplate-2/src/test/java/com/baeldung/compress/MessageControllerUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.compress; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class MessageControllerUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(MessageControllerUnitTest.class); + + @Autowired + private RestTemplate restTemplate; + + @LocalServerPort + private int randomServerPort; + + /** + * As a further test you can intercept the request body, using a tool like + * Wireshark, to see the request body is actually gzipped. + * + * @throws Exception + */ + @Test + public void givenRestTemplate_whenPostCompressedRequest_thenRespondsSuccessfully() throws Exception { + + final String text = "Hello Baeldung!"; + Message message = new Message(text); + + HttpEntity request = new HttpEntity<>(message); + String uri = String.format("http://localhost:%s/%s", randomServerPort, MessageController.REQUEST_MAPPING); + + ResponseEntity responseEntity = restTemplate.postForEntity(uri, request, String.class); + + String response = responseEntity.getBody(); + LOG.info("Got response [{}]", response); + + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertNotNull(response); + assertEquals(MessageController.PROCESSED + text, response); + } + +} From f0b9b3db29ccb0b59b7cbefb219c0584a06278bd Mon Sep 17 00:00:00 2001 From: sharifi Date: Mon, 12 Oct 2020 23:07:48 +0330 Subject: [PATCH 11/24] separate directories --- .../DispatchServletApplication.java | 15 ++++++++++ .../dispatchservlet/conf/WebConf.java | 29 ++++++++++++++++++ .../controller/Controller.java | 15 ++++++++++ .../dispatchservlet/filter/CustomFilter.java | 30 +++++++++++++++++++ .../listener/CustomListener.java | 22 ++++++++++++++ .../servlet/CustomServlet.java | 29 ++++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/DispatchServletApplication.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/controller/Controller.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/DispatchServletApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/DispatchServletApplication.java new file mode 100644 index 0000000000..4d58715d88 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/DispatchServletApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.dispatchservlet; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.context.annotation.Configuration; + +@SpringBootApplication +public class DispatchServletApplication { + + public static void main(String[] args) { + SpringApplication.run(DispatchServletApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java new file mode 100644 index 0000000000..9a1170ca34 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java @@ -0,0 +1,29 @@ +package com.baeldung.dispatchservlet.conf; + +import com.baeldung.dispatchservlet.listener.CustomListener; +import com.baeldung.dispatchservlet.servlet.CustomServlet; +import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.ServletContextListener; + +@Configuration +public class WebConf { + + @Bean + public ServletRegistrationBean customServletBean() { + ServletRegistrationBean bean = + new ServletRegistrationBean(new CustomServlet(), "/servlet"); + return bean; + } + + @Bean + public ServletListenerRegistrationBean customListenerBean() { + ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(); + bean.setListener(new CustomListener()); + return bean; + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/controller/Controller.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/controller/Controller.java new file mode 100644 index 0000000000..14d71c60fb --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/controller/Controller.java @@ -0,0 +1,15 @@ +package com.baeldung.dispatchservlet.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/") +public class Controller { + + @GetMapping + public String getRequest(){ + return "Baeldung DispatcherServlet"; + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java new file mode 100644 index 0000000000..8429fc855f --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java @@ -0,0 +1,30 @@ +package com.baeldung.dispatchservlet.filter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import java.io.IOException; + +@Component +public class CustomFilter implements Filter { + + Logger logger = LoggerFactory.getLogger(CustomFilter.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + logger.info("CustomFilter is invoked"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java new file mode 100644 index 0000000000..62b316c012 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java @@ -0,0 +1,22 @@ +package com.baeldung.dispatchservlet.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +public class CustomListener implements ServletContextListener { + + Logger logger = LoggerFactory.getLogger(CustomListener.class); + + @Override + public void contextInitialized(ServletContextEvent sce) { + logger.info("CustomListener is initialized"); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + logger.info("CustomListener is destroyed"); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java new file mode 100644 index 0000000000..2a99e797ce --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java @@ -0,0 +1,29 @@ +package com.baeldung.dispatchservlet.servlet; + +import com.baeldung.dispatchservlet.filter.CustomFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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; + +public class CustomServlet extends HttpServlet { + + Logger logger = LoggerFactory.getLogger(CustomServlet.class); + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + logger.info("CustomServlet doGet() method is invoked"); + super.doGet(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + logger.info("CustomServlet doPost() method is invoked"); + super.doPost(req, resp); + } +} From eeadbb04f0521eb0db15f908be861320a04ad8f7 Mon Sep 17 00:00:00 2001 From: sharifi Date: Wed, 14 Oct 2020 15:32:29 +0330 Subject: [PATCH 12/24] delete the original classes related to separate the directories --- .../DispatchServletApplication.java | 15 ---------- .../conf/WebConf.java | 29 ------------------ .../controller/Controller.java | 15 ---------- .../filter/CustomFilter.java | 30 ------------------- .../listener/CustomListener.java | 22 -------------- .../servlet/CustomServlet.java | 29 ------------------ 6 files changed, 140 deletions(-) delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java delete mode 100644 spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java deleted file mode 100644 index 4d58715d88..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/DispatchServletApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.dispatchservlet; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.servlet.ServletComponentScan; -import org.springframework.context.annotation.Configuration; - -@SpringBootApplication -public class DispatchServletApplication { - - public static void main(String[] args) { - SpringApplication.run(DispatchServletApplication.class, args); - } - -} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java deleted file mode 100644 index 9a1170ca34..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/conf/WebConf.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.dispatchservlet.conf; - -import com.baeldung.dispatchservlet.listener.CustomListener; -import com.baeldung.dispatchservlet.servlet.CustomServlet; -import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.servlet.ServletContextListener; - -@Configuration -public class WebConf { - - @Bean - public ServletRegistrationBean customServletBean() { - ServletRegistrationBean bean = - new ServletRegistrationBean(new CustomServlet(), "/servlet"); - return bean; - } - - @Bean - public ServletListenerRegistrationBean customListenerBean() { - ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(); - bean.setListener(new CustomListener()); - return bean; - } - -} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java deleted file mode 100644 index 14d71c60fb..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/controller/Controller.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.dispatchservlet.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping(value = "/") -public class Controller { - - @GetMapping - public String getRequest(){ - return "Baeldung DispatcherServlet"; - } -} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java deleted file mode 100644 index 8429fc855f..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/filter/CustomFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.baeldung.dispatchservlet.filter; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.servlet.*; -import java.io.IOException; - -@Component -public class CustomFilter implements Filter { - - Logger logger = LoggerFactory.getLogger(CustomFilter.class); - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - logger.info("CustomFilter is invoked"); - chain.doFilter(request, response); - } - - @Override - public void destroy() { - - } -} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java deleted file mode 100644 index 62b316c012..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/listener/CustomListener.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.baeldung.dispatchservlet.listener; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -public class CustomListener implements ServletContextListener { - - Logger logger = LoggerFactory.getLogger(CustomListener.class); - - @Override - public void contextInitialized(ServletContextEvent sce) { - logger.info("CustomListener is initialized"); - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - logger.info("CustomListener is destroyed"); - } -} diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java deleted file mode 100644 index 2a99e797ce..0000000000 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com.baeldung.dispatchservlet/servlet/CustomServlet.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.dispatchservlet.servlet; - -import com.baeldung.dispatchservlet.filter.CustomFilter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -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; - -public class CustomServlet extends HttpServlet { - - Logger logger = LoggerFactory.getLogger(CustomServlet.class); - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - logger.info("CustomServlet doGet() method is invoked"); - super.doGet(req, resp); - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - logger.info("CustomServlet doPost() method is invoked"); - super.doPost(req, resp); - } -} From d790913cbd2d9355e77583dbe379bb1bcb69af9f Mon Sep 17 00:00:00 2001 From: sharifi Date: Sat, 24 Oct 2020 17:51:06 +0330 Subject: [PATCH 13/24] improve code quality --- .../main/java/com/baeldung/dispatchservlet/conf/WebConf.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java index 9a1170ca34..7c52b117fd 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java @@ -14,8 +14,8 @@ public class WebConf { @Bean public ServletRegistrationBean customServletBean() { - ServletRegistrationBean bean = - new ServletRegistrationBean(new CustomServlet(), "/servlet"); + ServletRegistrationBean bean + = new ServletRegistrationBean(new CustomServlet(), "/servlet"); return bean; } From 16b38741becfb811357ef92ea353728c0e16b0e1 Mon Sep 17 00:00:00 2001 From: Cavero Barca Date: Fri, 30 Oct 2020 17:44:33 +0100 Subject: [PATCH 14/24] Correct the artifactid and names to match with the folder following the guidelines --- docker/docker-internal-dto/pom.xml | 3 ++- .../main/java/com/baeldung/docker/{ => dto}/VariableDto.java | 2 +- docker/docker-spring-boot/pom.xml | 2 +- .../com/baeldung/docker/{ => spring}/DemoApplication.java | 2 +- .../com/baeldung/docker/{ => spring}/HelloController.java | 2 +- docker/pom.xml | 4 ++-- 6 files changed, 8 insertions(+), 7 deletions(-) rename docker/docker-internal-dto/src/main/java/com/baeldung/docker/{ => dto}/VariableDto.java (85%) rename docker/docker-spring-boot/src/main/java/com/baeldung/docker/{ => spring}/DemoApplication.java (88%) rename docker/docker-spring-boot/src/main/java/com/baeldung/docker/{ => spring}/HelloController.java (90%) diff --git a/docker/docker-internal-dto/pom.xml b/docker/docker-internal-dto/pom.xml index d7ba6d7373..01b92f81dc 100644 --- a/docker/docker-internal-dto/pom.xml +++ b/docker/docker-internal-dto/pom.xml @@ -5,10 +5,11 @@ 4.0.0 com.baeldung.docker - docker-spring-boot-parent + docker 0.0.1 docker-internal-dto + docker-internal-dto \ No newline at end of file diff --git a/docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java b/docker/docker-internal-dto/src/main/java/com/baeldung/docker/dto/VariableDto.java similarity index 85% rename from docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java rename to docker/docker-internal-dto/src/main/java/com/baeldung/docker/dto/VariableDto.java index 86e173e351..2de3b734ea 100644 --- a/docker/docker-internal-dto/src/main/java/com/baeldung/docker/VariableDto.java +++ b/docker/docker-internal-dto/src/main/java/com/baeldung/docker/dto/VariableDto.java @@ -1,4 +1,4 @@ -package com.baeldung.docker; +package com.baeldung.docker.dto; public class VariableDto { diff --git a/docker/docker-spring-boot/pom.xml b/docker/docker-spring-boot/pom.xml index 9524f68a5a..74bd1561cf 100644 --- a/docker/docker-spring-boot/pom.xml +++ b/docker/docker-spring-boot/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.baeldung.docker - docker-spring-boot-parent + docker 0.0.1 diff --git a/docker/docker-spring-boot/src/main/java/com/baeldung/docker/DemoApplication.java b/docker/docker-spring-boot/src/main/java/com/baeldung/docker/spring/DemoApplication.java similarity index 88% rename from docker/docker-spring-boot/src/main/java/com/baeldung/docker/DemoApplication.java rename to docker/docker-spring-boot/src/main/java/com/baeldung/docker/spring/DemoApplication.java index e0c1d57e89..9210cabbb3 100644 --- a/docker/docker-spring-boot/src/main/java/com/baeldung/docker/DemoApplication.java +++ b/docker/docker-spring-boot/src/main/java/com/baeldung/docker/spring/DemoApplication.java @@ -1,4 +1,4 @@ -package com.baeldung.docker; +package com.baeldung.docker.spring; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/docker/docker-spring-boot/src/main/java/com/baeldung/docker/HelloController.java b/docker/docker-spring-boot/src/main/java/com/baeldung/docker/spring/HelloController.java similarity index 90% rename from docker/docker-spring-boot/src/main/java/com/baeldung/docker/HelloController.java rename to docker/docker-spring-boot/src/main/java/com/baeldung/docker/spring/HelloController.java index b463bb557f..430a158011 100644 --- a/docker/docker-spring-boot/src/main/java/com/baeldung/docker/HelloController.java +++ b/docker/docker-spring-boot/src/main/java/com/baeldung/docker/spring/HelloController.java @@ -1,4 +1,4 @@ -package com.baeldung.docker; +package com.baeldung.docker.spring; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; diff --git a/docker/pom.xml b/docker/pom.xml index 3668ceb0fc..f05c303938 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -12,9 +12,9 @@ com.baeldung.docker - docker-spring-boot-parent + docker 0.0.1 - docker-spring-boot-parent + docker Demo project showing Spring Boot and Docker pom From 9bce552d6d369ab24a3acaf72889fd78f3d9b53a Mon Sep 17 00:00:00 2001 From: Mateusz Szablak Date: Fri, 13 Nov 2020 19:25:15 +0100 Subject: [PATCH 15/24] BAEL-4723 Defining Indexes in JPA (#10247) * BAEL-4723 Defining Indexes in JPA * unit -> integration test Co-authored-by: mateusz.szablak --- .../java/com/baeldung/jpa/index/Student.java | 70 +++++++++++++++++++ .../main/resources/META-INF/persistence.xml | 15 ++++ .../java-jpa-3/src/main/resources/logback.xml | 2 +- .../jpa/index/IndexIntegrationTest.java | 50 +++++++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java create mode 100644 persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/index/IndexIntegrationTest.java diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java new file mode 100644 index 0000000000..0a77cfbc9e --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java @@ -0,0 +1,70 @@ +package com.baeldung.jpa.index; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.Table; +import java.io.Serializable; +import java.util.Objects; + +@Entity +@Table(indexes = { + @Index(columnList = "firstName"), + @Index(name = "fn_index", columnList = "id"), + @Index(name = "multiIndex1", columnList = "firstName, lastName"), + @Index(name = "multiIndex2", columnList = "lastName, firstName"), + @Index(name = "multiSortIndex", columnList = "firstName, lastName DESC"), + @Index(name = "uniqueIndex", columnList = "firstName", unique = true), + @Index(name = "uniqueMultiIndex", columnList = "firstName, lastName", unique = true) +}) +public class Student implements Serializable { + @Id + @GeneratedValue + private Long id; + private String firstName; + private String lastName; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Student student = (Student) o; + return Objects.equals(id, student.id) && + Objects.equals(firstName, student.firstName) && + Objects.equals(lastName, student.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(id, firstName, lastName); + } +} diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml index 88378bd8db..8fe3a8bbf1 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml @@ -40,4 +40,19 @@ + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.index.Student + true + + + + + + + + + + + diff --git a/persistence-modules/java-jpa-3/src/main/resources/logback.xml b/persistence-modules/java-jpa-3/src/main/resources/logback.xml index 2527fea245..8000740dd1 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/logback.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/logback.xml @@ -8,7 +8,7 @@ - + diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/index/IndexIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/index/IndexIntegrationTest.java new file mode 100644 index 0000000000..f59450567b --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/index/IndexIntegrationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.jpa.index; + +import org.hibernate.exception.ConstraintViolationException; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.util.Optional; + +public class IndexIntegrationTest { + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @BeforeClass + public static void setup() { + factory = Persistence.createEntityManagerFactory("jpa-index"); + entityManager = factory.createEntityManager(); + } + + @Test + public void givenStudent_whenPersistStudentWithSameFirstName_thenConstraintViolationException() { + Student student = new Student(); + student.setFirstName("FirstName"); + student.setLastName("LastName"); + + Student student2 = new Student(); + student2.setFirstName("FirstName"); + student2.setLastName("LastName2"); + + entityManager.getTransaction().begin(); + entityManager.persist(student); + entityManager.getTransaction().commit(); + + Assert.assertEquals(1L, (long) student.getId()); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(student2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex).map(Throwable::getCause).map(Throwable::getCause).filter(x -> x instanceof ConstraintViolationException).isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } +} From cfb424f9d10b550856e1588def0d0e2c4af1b2d3 Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Fri, 13 Nov 2020 19:31:59 +0100 Subject: [PATCH 16/24] BAEL-4609 - Testing Kafka and Spring Boot (#10249) * BAEL-4437 - System Rules * BAEL-4687 Testing Kafka and Spring Boot * BAEL-4609 - Testing Kafka and Spring Boot Co-authored-by: Jonathan Cook --- spring-kafka/pom.xml | 25 +++- .../kafka/embedded/KafkaConsumer.java | 39 ++++++ .../kafka/embedded/KafkaProducer.java | 22 ++++ .../KafkaProducerConsumerApplication.java | 15 +++ .../com/baeldung/SpringContextLiveTest.java | 17 --- .../com/baeldung/SpringContextManualTest.java | 17 --- .../EmbeddedKafkaIntegrationTest.java | 52 ++++++++ .../KafkaTestContainersIntegrationTest.java | 120 ++++++++++++++++++ .../src/test/resources/application.yml | 7 + spring-kafka/src/test/resources/logback.xml | 13 ++ 10 files changed, 286 insertions(+), 41 deletions(-) create mode 100644 spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java create mode 100644 spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java create mode 100644 spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java delete mode 100644 spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java delete mode 100644 spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java create mode 100644 spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java create mode 100644 spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java create mode 100644 spring-kafka/src/test/resources/application.yml create mode 100644 spring-kafka/src/test/resources/logback.xml diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index 2b4a0914e6..235dd75966 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 spring-kafka - 0.0.1-SNAPSHOT spring-kafka Intro to Kafka with Spring @@ -15,25 +15,36 @@ - org.springframework.boot spring-boot-starter - org.springframework.kafka spring-kafka + ${spring-kafka.version} - com.fasterxml.jackson.core jackson-databind + + org.springframework.kafka + spring-kafka-test + ${spring-kafka.version} + test + + + org.testcontainers + kafka + ${testcontainers-kafka.version} + test + - 2.3.7.RELEASE + 2.5.8.RELEASE + 1.15.0 \ No newline at end of file diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java new file mode 100644 index 0000000000..48a194b4e3 --- /dev/null +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java @@ -0,0 +1,39 @@ +package com.baeldung.kafka.embedded; + +import java.util.concurrent.CountDownLatch; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class KafkaConsumer { + + private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumer.class); + + private CountDownLatch latch = new CountDownLatch(1); + private String payload = null; + + @KafkaListener(topics = "${test.topic}") + public void receive(ConsumerRecord consumerRecord) { + LOGGER.info("received payload='{}'", consumerRecord.toString()); + setPayload(consumerRecord.toString()); + latch.countDown(); + } + + public CountDownLatch getLatch() { + return latch; + } + + public String getPayload() { + return payload; + } + + private void setPayload(String payload) { + this.payload = payload; + } + +} diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java new file mode 100644 index 0000000000..d7cbd35011 --- /dev/null +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java @@ -0,0 +1,22 @@ +package com.baeldung.kafka.embedded; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +@Component +public class KafkaProducer { + + private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducer.class); + + @Autowired + private KafkaTemplate kafkaTemplate; + + public void send(String topic, String payload) { + LOGGER.info("sending payload='{}' to topic='{}'", payload, topic); + kafkaTemplate.send(topic, payload); + } + +} diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java new file mode 100644 index 0000000000..bf14251d75 --- /dev/null +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.kafka.embedded; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAutoConfiguration +public class KafkaProducerConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(KafkaProducerConsumerApplication.class, args); + } + +} diff --git a/spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java b/spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java deleted file mode 100644 index 60262df9d4..0000000000 --- a/spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import com.baeldung.spring.kafka.KafkaApplication; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = KafkaApplication.class) -public class SpringContextLiveTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java b/spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java deleted file mode 100644 index 0d2c19136f..0000000000 --- a/spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import com.baeldung.spring.kafka.KafkaApplication; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = KafkaApplication.class) -public class SpringContextManualTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java new file mode 100644 index 0000000000..4c727795c4 --- /dev/null +++ b/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.kafka.embedded; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; + +@SpringBootTest +@DirtiesContext +@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) +class EmbeddedKafkaIntegrationTest { + + @Autowired + public KafkaTemplate template; + + @Autowired + private KafkaConsumer consumer; + + @Autowired + private KafkaProducer producer; + + @Value("${test.topic}") + private String topic; + + @Test + public void givenEmbeddedKafkaBroker_whenSendingtoDefaultTemplate_thenMessageReceived() throws Exception { + template.send(topic, "Sending with default template"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + + @Test + public void givenEmbeddedKafkaBroker_whenSendingtoSimpleProducer_thenMessageReceived() throws Exception { + producer.send(topic, "Sending with our own simple KafkaProducer"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + +} diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java new file mode 100644 index 0000000000..972b6cce4d --- /dev/null +++ b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java @@ -0,0 +1,120 @@ +package com.baeldung.kafka.testcontainers; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.kafka.embedded.KafkaConsumer; +import com.baeldung.kafka.embedded.KafkaProducer; +import com.baeldung.kafka.embedded.KafkaProducerConsumerApplication; + +@RunWith(SpringRunner.class) +@Import(com.baeldung.kafka.testcontainers.KafkaTestContainersIntegrationTest.KafkaTestContainersConfiguration.class) +@SpringBootTest(classes = KafkaProducerConsumerApplication.class) +@DirtiesContext +public class KafkaTestContainersIntegrationTest { + + @ClassRule + public static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:5.4.3")); + + @Autowired + public KafkaTemplate template; + + @Autowired + private KafkaConsumer consumer; + + @Autowired + private KafkaProducer producer; + + @Value("${test.topic}") + private String topic; + + @Test + public void givenKafkaDockerContainer_whenSendingtoDefaultTemplate_thenMessageReceived() throws Exception { + template.send(topic, "Sending with default template"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + + @Test + public void givenKafkaDockerContainer_whenSendingtoSimpleProducer_thenMessageReceived() throws Exception { + producer.send(topic, "Sending with own controller"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + + @TestConfiguration + static class KafkaTestContainersConfiguration { + + @Bean + ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } + + @Bean + public ConsumerFactory consumerFactory() { + return new DefaultKafkaConsumerFactory<>(consumerConfigs()); + } + + @Bean + public Map consumerConfigs() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers()); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "baeldung"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + return props; + } + + @Bean + public ProducerFactory producerFactory() { + Map configProps = new HashMap<>(); + configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers()); + configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + return new DefaultKafkaProducerFactory<>(configProps); + } + + @Bean + public KafkaTemplate kafkaTemplate() { + return new KafkaTemplate<>(producerFactory()); + } + + } + +} diff --git a/spring-kafka/src/test/resources/application.yml b/spring-kafka/src/test/resources/application.yml new file mode 100644 index 0000000000..7d7997c6fd --- /dev/null +++ b/spring-kafka/src/test/resources/application.yml @@ -0,0 +1,7 @@ +spring: + kafka: + consumer: + auto-offset-reset: earliest + group-id: baeldung +test: + topic: embedded-test-topic \ No newline at end of file diff --git a/spring-kafka/src/test/resources/logback.xml b/spring-kafka/src/test/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-kafka/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file From 810736bf23364c4983177b1fe9a33a7bc4ab7e6b Mon Sep 17 00:00:00 2001 From: kwoyke Date: Sat, 14 Nov 2020 00:28:03 +0100 Subject: [PATCH 17/24] BAEL-3565: Using enums in JPQL examples (#10248) --- .../baeldung/jpa/enums/ArticleUnitTest.java | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java index 82f3abc04d..9d98d6b86f 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java @@ -7,7 +7,9 @@ import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; +import javax.persistence.TypedQuery; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -19,7 +21,7 @@ public class ArticleUnitTest { @BeforeClass public static void setup() { - Map properties = new HashMap(); + Map properties = new HashMap<>(); properties.put("hibernate.show_sql", "true"); properties.put("hibernate.format_sql", "true"); emFactory = Persistence.createEntityManagerFactory("jpa-h2", properties); @@ -115,4 +117,53 @@ public class ArticleUnitTest { assertEquals(Category.MUSIC, persistedArticle.getCategory()); } + @Test + public void shouldFindArticleByCategory() { + // given + Article article = new Article(); + article.setId(5); + article.setTitle("static"); + article.setCategory(Category.SPORT); + + EntityTransaction tx = em.getTransaction(); + tx.begin(); + em.persist(article); + tx.commit(); + + String jpql = "select a from Article a where a.category = com.baeldung.jpa.enums.Category.SPORT"; + + // when + List
articles = em.createQuery(jpql, Article.class).getResultList(); + + // then + assertEquals(1, articles.size()); + assertEquals(Category.SPORT, articles.get(0).getCategory()); + assertEquals("static", articles.get(0).getTitle()); + } + + @Test + public void shouldFindArticleByCategoryParameter() { + // given + Article article = new Article(); + article.setId(6); + article.setTitle("dynamic"); + article.setCategory(Category.TECHNOLOGY); + + EntityTransaction tx = em.getTransaction(); + tx.begin(); + em.persist(article); + tx.commit(); + + String jpql = "select a from Article a where a.category = :category"; + + // when + TypedQuery
query = em.createQuery(jpql, Article.class); + query.setParameter("category", Category.TECHNOLOGY); + List
articles = query.getResultList(); + + // then + assertEquals(1, articles.size()); + assertEquals(Category.TECHNOLOGY, articles.get(0).getCategory()); + assertEquals("dynamic", articles.get(0).getTitle()); + } } \ No newline at end of file From cc0e244ce4b2f67972ffced007cc0a04390ea2a0 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Sun, 15 Nov 2020 15:00:16 +0530 Subject: [PATCH 18/24] JAVA-2423 Move/rename module spring-rest-compress - Removing spring-rest-compress module as its contents have been moved to spring-resttemplate-2 --- pom.xml | 2 - spring-rest-compress/README.md | 6 -- spring-rest-compress/pom.xml | 65 ------------------- ...mpressingClientHttpRequestInterceptor.java | 38 ----------- .../spring/rest/compress/GzipUtils.java | 52 --------------- .../compress/JettyWebServerConfiguration.java | 38 ----------- .../spring/rest/compress/Message.java | 29 --------- .../rest/compress/MessageController.java | 38 ----------- .../compress/RestTemplateConfiguration.java | 21 ------ .../SpringCompressRequestApplication.java | 15 ----- .../rest/compress/GzipUtilsUnitTest.java | 19 ------ .../compress/MessageControllerUnitTest.java | 56 ---------------- 12 files changed, 379 deletions(-) delete mode 100644 spring-rest-compress/README.md delete mode 100644 spring-rest-compress/pom.xml delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/GzipUtils.java delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/JettyWebServerConfiguration.java delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/Message.java delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/MessageController.java delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/RestTemplateConfiguration.java delete mode 100644 spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/SpringCompressRequestApplication.java delete mode 100644 spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/GzipUtilsUnitTest.java delete mode 100644 spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/MessageControllerUnitTest.java diff --git a/pom.xml b/pom.xml index 6c96d8d77e..82e242b9af 100644 --- a/pom.xml +++ b/pom.xml @@ -697,7 +697,6 @@ spring-reactor spring-remoting spring-rest-angular - spring-rest-compress spring-rest-http spring-rest-http-2 spring-rest-query-language @@ -1200,7 +1199,6 @@ spring-reactor spring-remoting spring-rest-angular - spring-rest-compress spring-rest-http spring-rest-query-language spring-rest-shell diff --git a/spring-rest-compress/README.md b/spring-rest-compress/README.md deleted file mode 100644 index ce627d8595..0000000000 --- a/spring-rest-compress/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Spring REST Compress - -This module contains articles about request compression with Spring - -### Relevant Articles: -- [How to compress requests using the Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-compressing-requests) diff --git a/spring-rest-compress/pom.xml b/spring-rest-compress/pom.xml deleted file mode 100644 index 9ff0be9682..0000000000 --- a/spring-rest-compress/pom.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - 4.0.0 - spring-rest-compress - 0.0.1-SNAPSHOT - spring-rest-compress - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - - - org.springframework.boot - spring-boot-starter-jetty - - - - org.apache.httpcomponents - httpclient - - - - commons-io - commons-io - ${commons-io.version} - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - 1.8 - 2.6 - - - diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java deleted file mode 100644 index 78b77256af..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; - -import java.io.IOException; - -public class CompressingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { - - private static final Logger LOG = LoggerFactory.getLogger(CompressingClientHttpRequestInterceptor.class); - - private static final String GZIP_ENCODING = "gzip"; - - /** - * Compress a request body using Gzip and add Http headers. - * - * @param req - * @param body - * @param exec - * @return - * @throws IOException - */ - @Override - public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec) - throws IOException { - LOG.info("Compressing request..."); - HttpHeaders httpHeaders = req.getHeaders(); - httpHeaders.add(HttpHeaders.CONTENT_ENCODING, GZIP_ENCODING); - httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING); - return exec.execute(req, GzipUtils.compress(body)); - } - -} diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/GzipUtils.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/GzipUtils.java deleted file mode 100644 index b9731535b2..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/GzipUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.apache.commons.codec.Charsets; -import org.apache.commons.io.IOUtils; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -public class GzipUtils { - - /** - * Gzip a string. - * - * @param text - * @return - * @throws Exception - */ - public static byte[] compress(String text) throws Exception { - return GzipUtils.compress(text.getBytes(Charsets.UTF_8)); - } - - /** - * Gzip a byte array. - * - * @param body - * @return - * @throws IOException - */ - public static byte[] compress(byte[] body) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos)) { - gzipOutputStream.write(body); - } - return baos.toByteArray(); - } - - /** - * Decompress a Gzipped byte array to a String. - * - * @param body - * @return - * @throws IOException - */ - public static String decompress(byte[] body) throws IOException { - try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(body))) { - return IOUtils.toString(gzipInputStream, Charsets.UTF_8); - } - } -} diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/JettyWebServerConfiguration.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/JettyWebServerConfiguration.java deleted file mode 100644 index 8de8e5b523..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/JettyWebServerConfiguration.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.server.handler.gzip.GzipHandler; -import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configure Jetty web server so it handles compressed requests. - */ -@Configuration -public class JettyWebServerConfiguration { - - private static final int MIN_BYTES = 1; - - /** - * Customise the Jetty web server to automatically decompress requests. - */ - @Bean - public JettyServletWebServerFactory jettyServletWebServerFactory() { - - JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); - factory.addServerCustomizers(server -> { - - GzipHandler gzipHandler = new GzipHandler(); - // Enable request decompression - gzipHandler.setInflateBufferSize(MIN_BYTES); - gzipHandler.setHandler(server.getHandler()); - - HandlerCollection handlerCollection = new HandlerCollection(gzipHandler); - server.setHandler(handlerCollection); - }); - - return factory; - } - -} diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/Message.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/Message.java deleted file mode 100644 index 24272a4fca..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/Message.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.spring.rest.compress; - -public class Message { - - private String text; - - public Message() { - } - - public Message(String text) { - this.text = text; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Message {"); - sb.append("text='").append(text).append('\''); - sb.append('}'); - return sb.toString(); - } -} diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/MessageController.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/MessageController.java deleted file mode 100644 index 2fc2ca8272..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/MessageController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Map; - -@RestController -public class MessageController { - - protected static final String PROCESSED = "Processed "; - - protected static final String REQUEST_MAPPING = "process"; - - private static final Logger LOG = LoggerFactory.getLogger(MessageController.class); - - /** - * A simple endpoint that responds with "Processed " + supplied Message content. - * - * @param headers - * @param message - * @return - */ - @PostMapping(value = REQUEST_MAPPING) - public ResponseEntity processMessage(@RequestHeader Map headers, - @RequestBody Message message) { - - // Print headers - headers.forEach((k, v) -> LOG.info(k + "=" + v)); - - return ResponseEntity.ok(PROCESSED + message.getText()); - } -} diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/RestTemplateConfiguration.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/RestTemplateConfiguration.java deleted file mode 100644 index c1e3c89ae9..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/RestTemplateConfiguration.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; - -@Configuration -public class RestTemplateConfiguration { - - /** - * A RestTemplate that compresses requests. - * - * @return RestTemplate - */ - @Bean - public RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor()); - return restTemplate; - } -} diff --git a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/SpringCompressRequestApplication.java b/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/SpringCompressRequestApplication.java deleted file mode 100644 index 9b1b71979d..0000000000 --- a/spring-rest-compress/src/main/java/com/baeldung/spring/rest/compress/SpringCompressRequestApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -@EnableAutoConfiguration -public class SpringCompressRequestApplication { - - public static void main(String[] args) { - SpringApplication.run(SpringCompressRequestApplication.class, args); - } - -} diff --git a/spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/GzipUtilsUnitTest.java b/spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/GzipUtilsUnitTest.java deleted file mode 100644 index 431758d358..0000000000 --- a/spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/GzipUtilsUnitTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class GzipUtilsUnitTest { - - @Test - public void givenCompressedText_whenDecompressed_thenSuccessful() throws Exception { - final String expectedText = "Hello Baeldung!"; - byte[] compressedText = GzipUtils.compress(expectedText); - String decompressedText = GzipUtils.decompress(compressedText); - assertNotNull(compressedText); - assertEquals(expectedText, decompressedText); - } - -} \ No newline at end of file diff --git a/spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/MessageControllerUnitTest.java b/spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/MessageControllerUnitTest.java deleted file mode 100644 index 50b2b7ccd7..0000000000 --- a/spring-rest-compress/src/test/java/com/baeldung/spring/rest/compress/MessageControllerUnitTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.baeldung.spring.rest.compress; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class MessageControllerUnitTest { - - private static final Logger LOG = LoggerFactory.getLogger(MessageControllerUnitTest.class); - - @Autowired - private RestTemplate restTemplate; - - @LocalServerPort - private int randomServerPort; - - /** - * As a further test you can intercept the request body, using a tool like - * Wireshark, to see the request body is actually gzipped. - * - * @throws Exception - */ - @Test - public void givenRestTemplate_whenPostCompressedRequest_thenRespondsSuccessfully() throws Exception { - - final String text = "Hello Baeldung!"; - Message message = new Message(text); - - HttpEntity request = new HttpEntity<>(message); - String uri = String.format("http://localhost:%s/%s", randomServerPort, MessageController.REQUEST_MAPPING); - - ResponseEntity responseEntity = restTemplate.postForEntity(uri, request, String.class); - - String response = responseEntity.getBody(); - LOG.info("Got response [{}]", response); - - assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); - assertNotNull(response); - assertEquals(MessageController.PROCESSED + text, response); - } - -} From f440cf900c3837a661dcb513a73eeaa95421afec Mon Sep 17 00:00:00 2001 From: Jordan Simpson Date: Sun, 15 Nov 2020 23:24:07 -0600 Subject: [PATCH 19/24] BAEL-4731 (article improvement) (#10251) * Instead of using .onDisconnect().block() to keep the app alive, make the app a web server. * Add article reference to README --- discord4j/.gitignore | 1 - discord4j/README.md | 7 +++++++ discord4j/pom.xml | 8 ++++++++ .../java/com/baeldung/discordbot/BotConfiguration.java | 2 -- 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 discord4j/README.md diff --git a/discord4j/.gitignore b/discord4j/.gitignore index b56f1dd0d0..7ed0d6b679 100644 --- a/discord4j/.gitignore +++ b/discord4j/.gitignore @@ -1,4 +1,3 @@ -README.md target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ diff --git a/discord4j/README.md b/discord4j/README.md new file mode 100644 index 0000000000..58a9924666 --- /dev/null +++ b/discord4j/README.md @@ -0,0 +1,7 @@ +## DISCORD4J + +This module contains articles about Discord4J + +### Relevant Articles: + +- [Creating a Discord Bot with Discord4J + Spring Boot](https://www.baeldung.com/spring-discord4j-bot) \ No newline at end of file diff --git a/discord4j/pom.xml b/discord4j/pom.xml index 7687f63ad5..664692f60a 100644 --- a/discord4j/pom.xml +++ b/discord4j/pom.xml @@ -23,6 +23,14 @@ org.springframework.boot spring-boot-starter + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-actuator + org.springframework.boot diff --git a/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java b/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java index a60005e9b5..901308605b 100644 --- a/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java +++ b/discord4j/src/main/java/com/baeldung/discordbot/BotConfiguration.java @@ -36,8 +36,6 @@ public class BotConfiguration { .onErrorResume(listener::handleError) .subscribe(); } - - client.onDisconnect().block(); } catch ( Exception exception ) { log.error( "Be sure to use a valid bot token!", exception ); From ad30d29ed6d48d29f020164687135876c1193f8f Mon Sep 17 00:00:00 2001 From: Mateusz Szablak Date: Mon, 16 Nov 2020 06:26:38 +0100 Subject: [PATCH 20/24] BAEL-4723 Defining Indexes in JPA #2 (#10254) * BAEL-4723 Defining Indexes in JPA * unit -> integration test * whitespaces fix * tab to space Co-authored-by: mateusz.szablak --- .../java/com/baeldung/jpa/index/Student.java | 14 +++++----- .../main/resources/META-INF/persistence.xml | 28 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java index 0a77cfbc9e..45de3f3fc4 100644 --- a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/index/Student.java @@ -10,13 +10,13 @@ import java.util.Objects; @Entity @Table(indexes = { - @Index(columnList = "firstName"), - @Index(name = "fn_index", columnList = "id"), - @Index(name = "multiIndex1", columnList = "firstName, lastName"), - @Index(name = "multiIndex2", columnList = "lastName, firstName"), - @Index(name = "multiSortIndex", columnList = "firstName, lastName DESC"), - @Index(name = "uniqueIndex", columnList = "firstName", unique = true), - @Index(name = "uniqueMultiIndex", columnList = "firstName, lastName", unique = true) + @Index(columnList = "firstName"), + @Index(name = "fn_index", columnList = "id"), + @Index(name = "multiIndex1", columnList = "firstName, lastName"), + @Index(name = "multiIndex2", columnList = "lastName, firstName"), + @Index(name = "multiSortIndex", columnList = "firstName, lastName DESC"), + @Index(name = "uniqueIndex", columnList = "firstName", unique = true), + @Index(name = "uniqueMultiIndex", columnList = "firstName, lastName", unique = true) }) public class Student implements Serializable { @Id diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml index 8fe3a8bbf1..1a53fb8e82 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml @@ -41,18 +41,18 @@ - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.index.Student - true - - - - - - - - - - - + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.index.Student + true + + + + + + + + + + + From 69c4d136f5d51f1d7a24860bebdafcacd86d4b9b Mon Sep 17 00:00:00 2001 From: Carlos Cavero Date: Mon, 16 Nov 2020 14:45:31 +0100 Subject: [PATCH 21/24] Update pom.xml Use the correct indentation --- docker/docker-internal-dto/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/docker-internal-dto/pom.xml b/docker/docker-internal-dto/pom.xml index 01b92f81dc..55cef257fe 100644 --- a/docker/docker-internal-dto/pom.xml +++ b/docker/docker-internal-dto/pom.xml @@ -10,6 +10,6 @@ docker-internal-dto - docker-internal-dto + docker-internal-dto - \ No newline at end of file + From 600896e8423a423e6067b3065faf10bfc6ac1c65 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Mon, 16 Nov 2020 19:03:15 +0100 Subject: [PATCH 22/24] [BAEL-4617] extending enums (#10130) --- .../core-java-lang-oop-types/pom.xml | 10 ++++- .../enums/extendenum/Application.java | 35 +++++++++++++++ .../enums/extendenum/ApplicationWithEx.java | 26 +++++++++++ .../extendenum/BasicStringOperation.java | 33 ++++++++++++++ .../extendenum/ExtendedStringOperation.java | 31 +++++++++++++ .../enums/extendenum/ImmutableOperation.java | 6 +++ .../baeldung/enums/extendenum/Operator.java | 5 +++ .../enums/extendenum/StringOperation.java | 7 +++ .../enums/extendenum/ExtendEnumUnitTest.java | 43 +++++++++++++++++++ 9 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Application.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ApplicationWithEx.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/BasicStringOperation.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ExtendedStringOperation.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ImmutableOperation.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Operator.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/StringOperation.java create mode 100644 core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/enums/extendenum/ExtendEnumUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-types/pom.xml b/core-java-modules/core-java-lang-oop-types/pom.xml index ee167bbae2..c4efd9b8d2 100644 --- a/core-java-modules/core-java-lang-oop-types/pom.xml +++ b/core-java-modules/core-java-lang-oop-types/pom.xml @@ -12,12 +12,20 @@ core-java-lang-oop-types core-java-lang-oop-types jar - + org.apache.commons commons-lang3 ${commons-lang3.version} + + commons-codec + commons-codec + ${commons-codec.version} + + + 1.15 + \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Application.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Application.java new file mode 100644 index 0000000000..ad3d861d6a --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Application.java @@ -0,0 +1,35 @@ +package com.baeldung.enums.extendenum; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; + +public class Application { + private static final Map OPERATION_MAP; + + static { + OPERATION_MAP = new EnumMap<>(ImmutableOperation.class); + OPERATION_MAP.put(ImmutableOperation.TO_LOWER, String::toLowerCase); + OPERATION_MAP.put(ImmutableOperation.INVERT_CASE, StringUtils::swapCase); + OPERATION_MAP.put(ImmutableOperation.REMOVE_WHITESPACES, input -> input.replaceAll("\\s", "")); + + if (Arrays.stream(ImmutableOperation.values()).anyMatch(it -> !OPERATION_MAP.containsKey(it))) { + throw new IllegalStateException("Unmapped enum constant found!"); + } + } + + public String applyImmutableOperation(ImmutableOperation operation, String input) { + return OPERATION_MAP.get(operation).apply(input); + } + + public String getDescription(StringOperation stringOperation) { + return stringOperation.getDescription(); + } + + public String applyOperation(StringOperation operation, String input) { + return operation.apply(input); + } + +} diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ApplicationWithEx.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ApplicationWithEx.java new file mode 100644 index 0000000000..e9cbad6b7c --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ApplicationWithEx.java @@ -0,0 +1,26 @@ +package com.baeldung.enums.extendenum; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; + +public class ApplicationWithEx { + private static final Map OPERATION_MAP; + + static { + OPERATION_MAP = new EnumMap<>(ImmutableOperation.class); + OPERATION_MAP.put(ImmutableOperation.TO_LOWER, String::toLowerCase); + OPERATION_MAP.put(ImmutableOperation.INVERT_CASE, StringUtils::swapCase); + // ImmutableOperation.REMOVE_WHITESPACES is not mapped + + if (Arrays.stream(ImmutableOperation.values()).anyMatch(it -> !OPERATION_MAP.containsKey(it))) { + throw new IllegalStateException("Unmapped enum constant found!"); + } + } + + public String applyImmutableOperation(ImmutableOperation operation, String input) { + return OPERATION_MAP.get(operation).apply(input); + } +} diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/BasicStringOperation.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/BasicStringOperation.java new file mode 100644 index 0000000000..267b02daf4 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/BasicStringOperation.java @@ -0,0 +1,33 @@ +package com.baeldung.enums.extendenum; + +public enum BasicStringOperation implements StringOperation { + TRIM("Removing leading and trailing spaces.") { + @Override + public String apply(String input) { + return input.trim(); + } + }, + TO_UPPER("Changing all characters into upper case.") { + @Override + public String apply(String input) { + return input.toUpperCase(); + } + }, + REVERSE("Reversing the given string.") { + @Override + public String apply(String input) { + return new StringBuilder(input).reverse().toString(); + } + }; + + private String description; + + public String getDescription() { + return description; + } + + BasicStringOperation(String description) { + this.description = description; + } +} + diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ExtendedStringOperation.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ExtendedStringOperation.java new file mode 100644 index 0000000000..6184837b26 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ExtendedStringOperation.java @@ -0,0 +1,31 @@ +package com.baeldung.enums.extendenum; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; + +public enum ExtendedStringOperation implements StringOperation { + MD5_ENCODE("Encoding the given string using the MD5 algorithm.") { + @Override + public String apply(String input) { + return DigestUtils.md5Hex(input); + } + }, + BASE64_ENCODE("Encoding the given string using the BASE64 algorithm.") { + @Override + public String apply(String input) { + return new String(new Base64().encode(input.getBytes())); + } + }; + + private String description; + + ExtendedStringOperation(String description) { + this.description = description; + } + + + @Override + public String getDescription() { + return description; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ImmutableOperation.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ImmutableOperation.java new file mode 100644 index 0000000000..66f26a4806 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/ImmutableOperation.java @@ -0,0 +1,6 @@ +package com.baeldung.enums.extendenum; + +public enum ImmutableOperation { + REMOVE_WHITESPACES, TO_LOWER, INVERT_CASE +} + diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Operator.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Operator.java new file mode 100644 index 0000000000..a65fea4f92 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/Operator.java @@ -0,0 +1,5 @@ +package com.baeldung.enums.extendenum; + +public interface Operator { + String apply(String input); +} diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/StringOperation.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/StringOperation.java new file mode 100644 index 0000000000..faf4f38274 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/enums/extendenum/StringOperation.java @@ -0,0 +1,7 @@ +package com.baeldung.enums.extendenum; + +public interface StringOperation { + String getDescription(); + + String apply(String input); +} diff --git a/core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/enums/extendenum/ExtendEnumUnitTest.java b/core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/enums/extendenum/ExtendEnumUnitTest.java new file mode 100644 index 0000000000..0b5ed1e826 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/enums/extendenum/ExtendEnumUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.enums.extendenum; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ExtendEnumUnitTest { + private Application app = new Application(); + + @Test + public void givenAStringAndOperation_whenApplyOperation_thenGetExpectedResult() { + String input = " hello"; + String expectedToUpper = " HELLO"; + String expectedReverse = "olleh "; + String expectedTrim = "hello"; + String expectedBase64 = "IGhlbGxv"; + String expectedMd5 = "292a5af68d31c10e31ad449bd8f51263"; + assertEquals(expectedTrim, app.applyOperation(BasicStringOperation.TRIM, input)); + assertEquals(expectedToUpper, app.applyOperation(BasicStringOperation.TO_UPPER, input)); + assertEquals(expectedReverse, app.applyOperation(BasicStringOperation.REVERSE, input)); + assertEquals(expectedBase64, app.applyOperation(ExtendedStringOperation.BASE64_ENCODE, input)); + assertEquals(expectedMd5, app.applyOperation(ExtendedStringOperation.MD5_ENCODE, input)); + } + + @Test + public void givenAStringAndImmutableOperation_whenApplyOperation_thenGetExpectedResult() { + String input = " He ll O "; + String expectedToLower = " he ll o "; + String expectedRmWhitespace = "HellO"; + String expectedInvertCase = " hE LL o "; + assertEquals(expectedToLower, app.applyImmutableOperation(ImmutableOperation.TO_LOWER, input)); + assertEquals(expectedRmWhitespace, app.applyImmutableOperation(ImmutableOperation.REMOVE_WHITESPACES, input)); + assertEquals(expectedInvertCase, app.applyImmutableOperation(ImmutableOperation.INVERT_CASE, input)); + } + + @Test + public void givenUnmappedImmutableOperationValue_whenAppStarts_thenGetException() { + Throwable throwable = assertThrows(ExceptionInInitializerError.class, () -> { + ApplicationWithEx appEx = new ApplicationWithEx(); + }); + assertTrue(throwable.getCause() instanceof IllegalStateException); + } +} \ No newline at end of file From c6f8c565722415f191bee2a6b31d2a09e93f066e Mon Sep 17 00:00:00 2001 From: vatsalgosar Date: Mon, 16 Nov 2020 23:33:49 +0530 Subject: [PATCH 23/24] IsLetter / isAlphabetic method unit tests (#10097) --- .../character/IsLetterOrAlphabetUnitTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 core-java-modules/core-java-14/src/test/java/com/baeldung/java14/character/IsLetterOrAlphabetUnitTest.java diff --git a/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/character/IsLetterOrAlphabetUnitTest.java b/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/character/IsLetterOrAlphabetUnitTest.java new file mode 100644 index 0000000000..44c712a17f --- /dev/null +++ b/core-java-modules/core-java-14/src/test/java/com/baeldung/java14/character/IsLetterOrAlphabetUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.java14.character; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +public class IsLetterOrAlphabetUnitTest { + + @Test + public void givenACharacter_whenLetter_thenAssertIsLetterTrue() { + assertTrue(Character.isLetter(65)); + } + + @Test + public void givenACharacter_whenLetter_thenAssertIsAlphabeticTrue() { + assertTrue(Character.isAlphabetic(65)); + } + + @Test + public void givenACharacter_whenAlphabeticAndNotLetter_thenAssertIsLetterFalse() { + assertFalse(Character.isLetter(837)); + } + + @Test + public void givenACharacter_whenAlphabeticAndNotLetter_thenAssertIsAlphabeticTrue() { + assertTrue(Character.isAlphabetic(837)); + } + +} \ No newline at end of file From 43fad6ba9570481a560f8c1e62e1e2f76552e863 Mon Sep 17 00:00:00 2001 From: developerDiv <34768329+developerDiv@users.noreply.github.com> Date: Mon, 16 Nov 2020 18:08:49 +0000 Subject: [PATCH 24/24] Bael 4215 creating generic array (#10178) * Initial commit for generic arrays, using T[] and Object[] * Add CollectionsList * Create generic arrays example with a Stack * Remove custom exception classes + throw RuntimeException instead. --- .../com/baeldung/genericarrays/MyStack.java | 30 +++++++++++++ .../genericarrays/ListToArrayUnitTest.java | 24 ++++++++++ .../genericarrays/MyStackUnitTest.java | 44 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 core-java-modules/core-java-arrays-guides/src/main/java/com/baeldung/genericarrays/MyStack.java create mode 100644 core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java create mode 100644 core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/MyStackUnitTest.java diff --git a/core-java-modules/core-java-arrays-guides/src/main/java/com/baeldung/genericarrays/MyStack.java b/core-java-modules/core-java-arrays-guides/src/main/java/com/baeldung/genericarrays/MyStack.java new file mode 100644 index 0000000000..02659f13bc --- /dev/null +++ b/core-java-modules/core-java-arrays-guides/src/main/java/com/baeldung/genericarrays/MyStack.java @@ -0,0 +1,30 @@ +package com.baeldung.genericarrays; + +import java.lang.reflect.Array; + +public class MyStack { + private E[] elements; + private int size = 0; + + public MyStack(Class clazz, int capacity) { + elements = (E[]) Array.newInstance(clazz, capacity); + } + + public void push(E item) { + if (size == elements.length) { + throw new RuntimeException(); + } + elements[size++] = item; + } + + public E pop() { + if (size == 0) { + throw new RuntimeException(); + } + return elements[--size]; + } + + public E[] getAllElements() { + return elements; + } +} diff --git a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java new file mode 100644 index 0000000000..5fd0385181 --- /dev/null +++ b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.genericarrays; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class ListToArrayUnitTest { + + @Test + public void givenListOfItems_whenToArray_thenReturnArrayOfItems() { + List items = new LinkedList<>(); + items.add("first item"); + items.add("second item"); + + String[] itemsAsArray = items.toArray(new String[0]); + + assertEquals("first item", itemsAsArray[0]); + assertEquals("second item", itemsAsArray[1]); + } +} diff --git a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/MyStackUnitTest.java b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/MyStackUnitTest.java new file mode 100644 index 0000000000..e36c5169a5 --- /dev/null +++ b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/MyStackUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.genericarrays; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MyStackUnitTest { + + @Test + public void givenStackWithTwoItems_whenPop_thenReturnLastAdded() { + MyStack myStack = new MyStack<>(String.class, 2); + myStack.push("hello"); + myStack.push("example"); + + assertEquals("example", myStack.pop()); + } + + @Test (expected = RuntimeException.class) + public void givenStackWithFixedCapacity_whenExceedCapacity_thenThrowException() { + MyStack myStack = new MyStack<>(Integer.class, 2); + myStack.push(100); + myStack.push(200); + myStack.push(300); + } + + @Test(expected = RuntimeException.class) + public void givenStack_whenPopOnEmptyStack_thenThrowException() { + MyStack myStack = new MyStack<>(Integer.class, 1); + myStack.push(100); + myStack.pop(); + myStack.pop(); + } + + @Test + public void givenStackWithItems_whenGetAllElements_thenSizeShouldEqualTotal() { + MyStack myStack = new MyStack<>(String.class, 2); + myStack.push("hello"); + myStack.push("example"); + + String[] items = myStack.getAllElements(); + + assertEquals(2, items.length); + } +}