From ace948a705fc62c23b2d81e6f89aecbd9c340517 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Sun, 1 Jul 2018 17:25:39 +0800 Subject: [PATCH 01/59] BAEL-1846: Java Image to Base64 String --- .../FileToBase64StringConversion.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java diff --git a/core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java b/core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java new file mode 100644 index 0000000000..aa3bc9adee --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java @@ -0,0 +1,32 @@ +package com.baeldung.fileToBase64StringConversion; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Base64; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; + +public class FileToBase64StringConversion { + public static void main(String[] args) throws FileNotFoundException, IOException { + //read file path from first argument + String filePath = args[0]; + + byte[] fileContent = FileUtils.readFileToByteArray(new File(filePath)); + String encodedString = Base64.getEncoder().encodeToString(fileContent); + + //print encoded base64 String + System.out.println(encodedString); + + //construct output file name + String extension = FilenameUtils.getExtension(filePath); + String baseFileName = FilenameUtils.getBaseName(filePath); + String directory = new File(filePath).getParentFile().getAbsolutePath(); + String outputFileName = directory+File.separator+baseFileName+"_copy."+extension; + + //decode the string and write to file + byte[] decodedBytes = Base64.getDecoder().decode(encodedString); + FileUtils.writeByteArrayToFile(new File(outputFileName), decodedBytes); + } +} From 7de2556d6b35381b087744e849e8e455038b0237 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Tue, 3 Jul 2018 17:33:01 +0800 Subject: [PATCH 02/59] Move from using main method to Junit test --- .../FileToBase64StringConversion.java | 32 ----------- .../FileToBase64StringConversionTest.java | 53 +++++++++++++++++++ 2 files changed, 53 insertions(+), 32 deletions(-) delete mode 100644 core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java create mode 100644 core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java diff --git a/core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java b/core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java deleted file mode 100644 index aa3bc9adee..0000000000 --- a/core-java-8/src/main/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversion.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.baeldung.fileToBase64StringConversion; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Base64; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.FilenameUtils; - -public class FileToBase64StringConversion { - public static void main(String[] args) throws FileNotFoundException, IOException { - //read file path from first argument - String filePath = args[0]; - - byte[] fileContent = FileUtils.readFileToByteArray(new File(filePath)); - String encodedString = Base64.getEncoder().encodeToString(fileContent); - - //print encoded base64 String - System.out.println(encodedString); - - //construct output file name - String extension = FilenameUtils.getExtension(filePath); - String baseFileName = FilenameUtils.getBaseName(filePath); - String directory = new File(filePath).getParentFile().getAbsolutePath(); - String outputFileName = directory+File.separator+baseFileName+"_copy."+extension; - - //decode the string and write to file - byte[] decodedBytes = Base64.getDecoder().decode(encodedString); - FileUtils.writeByteArrayToFile(new File(outputFileName), decodedBytes); - } -} diff --git a/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java new file mode 100644 index 0000000000..4e023fbe64 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java @@ -0,0 +1,53 @@ +package com.baeldung.fileToBase64StringConversion; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collection; + +import org.apache.commons.io.FileUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class FileToBase64StringConversionTest { + + private String inputFilePath; + private String outputFilePath; + + public FileToBase64StringConversionTest(String inputFilePath, String outputFilePath) { + this.inputFilePath = inputFilePath; + this.outputFilePath = outputFilePath; + } + + @Parameterized.Parameters + public static Collection parameters() { + return Arrays.asList(new String[][] { { "", "" } }); + } + + @Test + public void fileToBase64StringConversion() throws FileNotFoundException, IOException { + File outputFile = new File(outputFilePath); + File inputFile = new File(inputFilePath); + + if (!inputFile.exists()) + return; + + byte[] fileContent = FileUtils.readFileToByteArray(inputFile); + String encodedString = Base64.getEncoder().encodeToString(fileContent); + + // print encoded base64 String + System.out.println(encodedString); + + // decode the string and write to file + byte[] decodedBytes = Base64.getDecoder().decode(encodedString); + FileUtils.writeByteArrayToFile(outputFile, decodedBytes); + + assertTrue(outputFile.length() == fileContent.length); + } +} From 06f9a5f445d2235c4ebeaeccc9dfd972b7abf445 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Tue, 3 Jul 2018 23:38:07 +0800 Subject: [PATCH 03/59] Update to use environment variables for testing --- ...FileToBase64StringConversionUnitTest.java} | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) rename core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/{FileToBase64StringConversionTest.java => FileToBase64StringConversionUnitTest.java} (62%) diff --git a/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java similarity index 62% rename from core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java rename to core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java index 4e023fbe64..1842554534 100644 --- a/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionTest.java +++ b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java @@ -5,33 +5,29 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Arrays; import java.util.Base64; -import java.util.Collection; import org.apache.commons.io.FileUtils; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -@RunWith(Parameterized.class) -public class FileToBase64StringConversionTest { +public class FileToBase64StringConversionUnitTest { - private String inputFilePath; - private String outputFilePath; - - public FileToBase64StringConversionTest(String inputFilePath, String outputFilePath) { - this.inputFilePath = inputFilePath; - this.outputFilePath = outputFilePath; - } - - @Parameterized.Parameters - public static Collection parameters() { - return Arrays.asList(new String[][] { { "", "" } }); - } + private String inputFilePath = ""; + private String outputFilePath = ""; @Test + // file paths are from environment arguments: + // mvn test + // -Dtest=com.baeldung.fileToBase64StringConversion.FileToBase64StringConversionUnitTest + // -DinputFilePath="abc.png" -DoutFilePath="abc.png" + public void fileToBase64StringConversion() throws FileNotFoundException, IOException { + inputFilePath = System.getProperty("inputFilePath"); + outputFilePath = System.getProperty("outputFilePath"); + + if (inputFilePath == null || outputFilePath == null) + return; + File outputFile = new File(outputFilePath); File inputFile = new File(inputFilePath); From f325351275eee451ec78c1a5cbfe79e8268f0b24 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Thu, 5 Jul 2018 21:03:43 +0800 Subject: [PATCH 04/59] reformat and add test file --- .../FileToBase64StringConversionUnitTest.java | 54 ++++++++---------- core-java-8/src/test/resources/test_image.jpg | Bin 0 -> 2865 bytes 2 files changed, 24 insertions(+), 30 deletions(-) create mode 100644 core-java-8/src/test/resources/test_image.jpg diff --git a/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java index 1842554534..eef21a98c9 100644 --- a/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java @@ -3,7 +3,6 @@ package com.baeldung.fileToBase64StringConversion; import static org.junit.Assert.assertTrue; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.Base64; @@ -12,38 +11,33 @@ import org.junit.Test; public class FileToBase64StringConversionUnitTest { - private String inputFilePath = ""; - private String outputFilePath = ""; + private String inputFilePath = "test_image.jpg"; + private String outputFilePath = "test_image_copy.jpg"; - @Test - // file paths are from environment arguments: - // mvn test - // -Dtest=com.baeldung.fileToBase64StringConversion.FileToBase64StringConversionUnitTest - // -DinputFilePath="abc.png" -DoutFilePath="abc.png" + @Test + public void fileToBase64StringConversion() throws IOException { + //load file from /src/test/resources + ClassLoader classLoader = getClass().getClassLoader(); + File inputFile = new File(classLoader + .getResource(inputFilePath) + .getFile()); - public void fileToBase64StringConversion() throws FileNotFoundException, IOException { - inputFilePath = System.getProperty("inputFilePath"); - outputFilePath = System.getProperty("outputFilePath"); + byte[] fileContent = FileUtils.readFileToByteArray(inputFile); + String encodedString = Base64 + .getEncoder() + .encodeToString(fileContent); - if (inputFilePath == null || outputFilePath == null) - return; + //create output file + File outputFile = new File(inputFile + .getParentFile() + .getAbsolutePath() + File.pathSeparator + outputFilePath); - File outputFile = new File(outputFilePath); - File inputFile = new File(inputFilePath); + // decode the string and write to file + byte[] decodedBytes = Base64 + .getDecoder() + .decode(encodedString); + FileUtils.writeByteArrayToFile(outputFile, decodedBytes); - if (!inputFile.exists()) - return; - - byte[] fileContent = FileUtils.readFileToByteArray(inputFile); - String encodedString = Base64.getEncoder().encodeToString(fileContent); - - // print encoded base64 String - System.out.println(encodedString); - - // decode the string and write to file - byte[] decodedBytes = Base64.getDecoder().decode(encodedString); - FileUtils.writeByteArrayToFile(outputFile, decodedBytes); - - assertTrue(outputFile.length() == fileContent.length); - } + assertTrue(FileUtils.contentEquals(inputFile, outputFile)); + } } diff --git a/core-java-8/src/test/resources/test_image.jpg b/core-java-8/src/test/resources/test_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d0db1627c9b8a4db0fb023a7229e64b282b9a70a GIT binary patch literal 2865 zcmbVO3v5$m6h8OW4u%bbvBAJ`83QI^OUEX362SGbtpi5sHW0D|y6$$ptZU1?w;K>N zFj0_@@bZCVi98hzi2(%xH8Mm{g8_uW251BknSudP#0Ol@fBPIkQ2(a?{q8y6fBy5G zdwTz>9qKpGyS&6+0u%*Mh96Kbz+&5c(E~7L3XBARB;cq%z#yXV15^fZ8U`q*2F9?H z%877jfMp`E5zZ{Ul7W%Q>d2MeNXHnd8<{vJRP`E|9NvHukiCH*Uyx@6li5CnB@uCG zc$fxzpL%p<=PKC6b}jC){_1V>GwMbC6}!bU+u@vAVxMf&MCm(R!Jv=k0UG^^pOvl0gwzCknD2H!D5GFGKopJTI_Dqt>%$m*kXjqY%Qa4w(}J8<#0Iz5Rfl*7 z;!(8;_WA@I&H))1r&RC@lIZ41EgVw7Bl-l*5uP66PGCL=Hu^%SSsR0K?j<)=PQq&r zYF}FCvJ#w!c!%3%t3;fQ_-vCny&{6|1{Jdt@o)e-E7VY3j2L^7F7rqw)rc_;EqOy_ zQM_THw`vC3)6jmblLh>Z`qjO#54#XLVFABa=!pFUszk-S*k^`IR z_f?R6aWB>?$eLb^!)7Ypsxq|WzN}A?sv>LI)gH0L9^vouN@c`O)}9Uev>wIWI9duh ziFVwJ%X3M#Qp6aOa|r%wQcr@LU^?Xj0Rm8qvm5+y2Y7HoDVXsZ1PMJJ5W$BQ0lflR z1iXuKa*mTy&7T|XrJDDBNn%E-X*@^6v>;%?|)*^OXEVcvJL=};Ix^S0poO!sT zpz)@o_BPb0fD7jf$OwQOi_onqt2075aZighTXY{=bv>b0BCc$RF>Y>=P2a-AIE0QP>u)>DL0>S);0dZdTPhTQL54fCE1D0Hh>ADx@-07SJga zlR~M70FN4qqqGqT3>3|8G}OGat)KJ6_3VOLsijBHwDkT1GKLKwk@MKd!pFyqH5EN!vD!*X%k1Tq zRn^mHpgeb-;HmeDb7dve)I5K|!e^I0_x!TuFRWO*?!}j0er5fu8#Zs*y6yEhw!it- zu6N$uz308X`}QCF_|PYZk9_*s=U<*Y)qeU+N9WlK7r(vq-R1AEbp3GS=bOL$dh55_ zzyCpWQNV;{;T%?WkFFHdMYAl!>WMCjZYIK0SZ+wZu21nay=z|ItkFx7Qq5~N?QH8Y zw7_}2U#)baXIggQg<&^{G)>vR6V~#-l*NR_b)Cb*V30P9g9aI`Mx)VMW5rRU)R3X9 zRJ5@&GPY~u5E`e1{td~?vHAc2 literal 0 HcmV?d00001 From e92843493f1b8d2ff34a4f377e56f6472e5ff47b Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Mon, 6 Aug 2018 11:33:13 +0800 Subject: [PATCH 05/59] spring boot jsp security taglibs --- spring-boot-security-taglibs/.gitignore | 13 +++ spring-boot-security-taglibs/README.md | 19 +++++ spring-boot-security-taglibs/pom.xml | 84 +++++++++++++++++++ .../org/baeldung/security/Application.java | 23 +++++ .../org/baeldung/security/HomeController.java | 18 ++++ .../org/baeldung/security/SecurityConfig.java | 70 ++++++++++++++++ .../src/main/resources/application.properties | 8 ++ .../src/main/webapp/WEB-INF/views/home.jsp | 20 +++++ .../baeldung/security/HomeControllerTest.java | 27 ++++++ 9 files changed, 282 insertions(+) create mode 100644 spring-boot-security-taglibs/.gitignore create mode 100644 spring-boot-security-taglibs/README.md create mode 100644 spring-boot-security-taglibs/pom.xml create mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java create mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java create mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java create mode 100644 spring-boot-security-taglibs/src/main/resources/application.properties create mode 100644 spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp create mode 100644 spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java diff --git a/spring-boot-security-taglibs/.gitignore b/spring-boot-security-taglibs/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-boot-security-taglibs/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-boot-security-taglibs/README.md b/spring-boot-security-taglibs/README.md new file mode 100644 index 0000000000..f7eb314869 --- /dev/null +++ b/spring-boot-security-taglibs/README.md @@ -0,0 +1,19 @@ +========= + +## Spring Security Login Example Project + +###The Course +The "Learn Spring Security" Classes: http://github.learnspringsecurity.com + +### Relevant Articles: +- [Spring Security Form Login](http://www.baeldung.com/spring-security-login) +- [Spring Security Logout](http://www.baeldung.com/spring-security-logout) +- [Spring Security Expressions – hasRole Example](http://www.baeldung.com/spring-security-expressions-basic) +- [Spring HTTP/HTTPS Channel Security](http://www.baeldung.com/spring-channel-security-https) +- [Spring Security - Customize the 403 Forbidden/Access Denied Page](http://www.baeldung.com/spring-security-custom-access-denied-page) +- [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login) + +### Build the Project +``` +mvn clean install +``` diff --git a/spring-boot-security-taglibs/pom.xml b/spring-boot-security-taglibs/pom.xml new file mode 100644 index 0000000000..bd04ec3c0b --- /dev/null +++ b/spring-boot-security-taglibs/pom.xml @@ -0,0 +1,84 @@ + + 4.0.0 + + spring-boot-security-taglibs + jar + spring-boot-security-taglibs + spring 5 security sample project + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.security + spring-security-taglibs + + + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + javax.servlet + jstl + + + + net.sourceforge.htmlunit + htmlunit + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + spring-5-security-taglibs + + + src/main/resources + true + + + + + + + + + + UTF-8 + UTF-8 + 1.8 + + + \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java new file mode 100644 index 0000000000..eef41bd375 --- /dev/null +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java @@ -0,0 +1,23 @@ +package org.baeldung.security; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class Application extends SpringBootServletInitializer { + + public Application() { + super(); + } + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { + return builder.sources(Application.class); + } +} diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java new file mode 100644 index 0000000000..0eb6ee242d --- /dev/null +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java @@ -0,0 +1,18 @@ +package org.baeldung.security; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Controller +@RequestMapping("/") +public class HomeController { + + @RequestMapping("") + public String home(HttpServletRequest request, HttpServletResponse response) { + return "home"; + } + +} diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java new file mode 100644 index 0000000000..f6df516a0a --- /dev/null +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java @@ -0,0 +1,70 @@ +package org.baeldung.security; + +import java.util.HashSet; +import java.util.Set; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.BeanIds; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + private static final String ROLE_PREFIX = "ROLE_"; + public static final String DEFAULT_PASSWORD = "password"; + @Bean + static PasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(10); + } + + @Bean + UserDetailsService customUserDetailsService() { + return new UserDetailsService() { + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + //authenticate and return dummy user + Set authorities = new HashSet(); + authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + username)); + return new User(username, bCryptPasswordEncoder().encode(DEFAULT_PASSWORD), authorities); + } + }; + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(customUserDetailsService()).passwordEncoder(bCryptPasswordEncoder()); + + } + + @Bean(name = BeanIds.AUTHENTICATION_MANAGER) + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManager(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf(); + http.headers().frameOptions().sameOrigin(); + + http.antMatcher("/**").userDetailsService(customUserDetailsService()) + .authorizeRequests() + .antMatchers("/**").permitAll() + .and() + .httpBasic(); + } +} diff --git a/spring-boot-security-taglibs/src/main/resources/application.properties b/spring-boot-security-taglibs/src/main/resources/application.properties new file mode 100644 index 0000000000..9c49bd2137 --- /dev/null +++ b/spring-boot-security-taglibs/src/main/resources/application.properties @@ -0,0 +1,8 @@ +#jsp config +spring.mvc.view.prefix: /WEB-INF/views/ +spring.mvc.view.suffix: .jsp +spring.http.encoding.charset=UTF-8 +# Enable http encoding support. +spring.http.encoding.enabled=true +# Force the encoding to the configured charset on HTTP requests and responses. +spring.http.encoding.force=true diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp new file mode 100644 index 0000000000..9f5d8c34a3 --- /dev/null +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -0,0 +1,20 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1"%> +<%@ taglib prefix="security" + uri="http://www.springframework.org/security/tags" %> + + + + + +Home Page + + + + AUTHENTICATED + + + ADMIN ROLE + + + \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java new file mode 100644 index 0000000000..f13b23a10d --- /dev/null +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -0,0 +1,27 @@ +package org.baeldung.security; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class HomeControllerTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void home() throws Exception { + String body = this.restTemplate.withBasicAuth("ADMIN", SecurityConfig.DEFAULT_PASSWORD).getForEntity("/", String.class).getBody(); + System.out.println(body); + assertTrue(body.contains("AUTHENTICATED")); + assertTrue(body.contains("ADMIN ROLE")); + } +} From 4e4d11574ac5f3719d6eb8620ef54bda31b689ca Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Sat, 11 Aug 2018 16:10:53 +0800 Subject: [PATCH 06/59] add more test --- .../src/main/webapp/WEB-INF/views/home.jsp | 25 ++++++++++----- .../baeldung/security/HomeControllerTest.java | 31 ++++++++++++++----- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index 9f5d8c34a3..1117749ded 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -1,20 +1,29 @@ <%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="security" - uri="http://www.springframework.org/security/tags" %> - + pageEncoding="ISO-8859-1"%> +<%@ taglib prefix="sec" + uri="http://www.springframework.org/security/tags"%> + + Home Page - + AUTHENTICATED - - + + ADMIN ROLE - + + +

principal.username:

+ +
+ + Text Field:
+ + \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index f13b23a10d..dfdfda6234 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -13,15 +13,30 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class HomeControllerTest { - + @Autowired private TestRestTemplate restTemplate; - @Test - public void home() throws Exception { - String body = this.restTemplate.withBasicAuth("ADMIN", SecurityConfig.DEFAULT_PASSWORD).getForEntity("/", String.class).getBody(); - System.out.println(body); - assertTrue(body.contains("AUTHENTICATED")); - assertTrue(body.contains("ADMIN ROLE")); - } + @Test + public void home() throws Exception { + String body = this.restTemplate.withBasicAuth("ADMIN", SecurityConfig.DEFAULT_PASSWORD) + .getForEntity("/", String.class) + .getBody(); + System.out.println(body); + + // test + assertTrue(body.contains("AUTHENTICATED")); + + // test + assertTrue(body.contains("ADMIN ROLE")); + + // test + assertTrue(body.contains("principal.username: ADMIN")); + + // test + assertTrue(body.contains(" + assertTrue(body.contains("")); + } } From 7b2dec656dfeb434881e1ad7205e23c18b7d7986 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Sat, 11 Aug 2018 16:15:49 +0800 Subject: [PATCH 07/59] add more test --- .../org/baeldung/security/SecurityConfig.java | 35 +++++++++++-------- .../baeldung/security/HomeControllerTest.java | 4 +-- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java index f6df516a0a..99c5f1e892 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java @@ -25,28 +25,29 @@ import org.springframework.security.crypto.password.PasswordEncoder; public class SecurityConfig extends WebSecurityConfigurerAdapter { private static final String ROLE_PREFIX = "ROLE_"; public static final String DEFAULT_PASSWORD = "password"; + @Bean static PasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(10); } - + @Bean UserDetailsService customUserDetailsService() { return new UserDetailsService() { - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - //authenticate and return dummy user - Set authorities = new HashSet(); - authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + username)); - return new User(username, bCryptPasswordEncoder().encode(DEFAULT_PASSWORD), authorities); - } - }; + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + // authenticate, grant ADMIN role and return dummy user + Set authorities = new HashSet(); + authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + "ADMIN")); + return new User(username, bCryptPasswordEncoder().encode(DEFAULT_PASSWORD), authorities); + } + }; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(customUserDetailsService()).passwordEncoder(bCryptPasswordEncoder()); + auth.userDetailsService(customUserDetailsService()) + .passwordEncoder(bCryptPasswordEncoder()); } @@ -59,11 +60,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf(); - http.headers().frameOptions().sameOrigin(); - - http.antMatcher("/**").userDetailsService(customUserDetailsService()) + http.headers() + .frameOptions() + .sameOrigin(); + + http.antMatcher("/**") + .userDetailsService(customUserDetailsService()) .authorizeRequests() - .antMatchers("/**").permitAll() + .antMatchers("/**") + .permitAll() .and() .httpBasic(); } diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index dfdfda6234..995d5fa3df 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -19,7 +19,7 @@ public class HomeControllerTest { @Test public void home() throws Exception { - String body = this.restTemplate.withBasicAuth("ADMIN", SecurityConfig.DEFAULT_PASSWORD) + String body = this.restTemplate.withBasicAuth("testUser", SecurityConfig.DEFAULT_PASSWORD) .getForEntity("/", String.class) .getBody(); System.out.println(body); @@ -31,7 +31,7 @@ public class HomeControllerTest { assertTrue(body.contains("ADMIN ROLE")); // test - assertTrue(body.contains("principal.username: ADMIN")); + assertTrue(body.contains("principal.username: testUser")); // test assertTrue(body.contains(" Date: Tue, 14 Aug 2018 14:41:06 +0800 Subject: [PATCH 08/59] refactor spring config --- .../org/baeldung/security/Application.java | 23 ------ .../baeldung/security/ApplicationConfig.java | 40 ++++++++++ .../org/baeldung/security/HomeController.java | 2 - .../org/baeldung/security/SecurityConfig.java | 75 ------------------- .../src/main/webapp/WEB-INF/views/home.jsp | 28 ++++--- .../baeldung/security/HomeControllerTest.java | 2 +- 6 files changed, 54 insertions(+), 116 deletions(-) delete mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java create mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java delete mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java deleted file mode 100644 index eef41bd375..0000000000 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/Application.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.baeldung.security; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; - -@SpringBootApplication -public class Application extends SpringBootServletInitializer { - - public Application() { - super(); - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { - return builder.sources(Application.class); - } -} diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java new file mode 100644 index 0000000000..6283a102aa --- /dev/null +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java @@ -0,0 +1,40 @@ +package org.baeldung.security; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; + +@SpringBootApplication +@Configuration +@EnableWebSecurity +public class ApplicationConfig extends WebSecurityConfigurerAdapter { + public static final String DEFAULT_PASSWORD = "password"; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + + auth.inMemoryAuthentication() + .passwordEncoder(encoder) + .withUser("testUser") + .password(encoder.encode(DEFAULT_PASSWORD)) + .roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf(); + + http.authorizeRequests() + .antMatchers("/**") + .permitAll() + .and() + .httpBasic(); + } +} diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java index 0eb6ee242d..e697e7e301 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java @@ -9,10 +9,8 @@ import javax.servlet.http.HttpServletResponse; @Controller @RequestMapping("/") public class HomeController { - @RequestMapping("") public String home(HttpServletRequest request, HttpServletResponse response) { return "home"; } - } diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java deleted file mode 100644 index 99c5f1e892..0000000000 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/SecurityConfig.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.baeldung.security; - -import java.util.HashSet; -import java.util.Set; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.BeanIds; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - private static final String ROLE_PREFIX = "ROLE_"; - public static final String DEFAULT_PASSWORD = "password"; - - @Bean - static PasswordEncoder bCryptPasswordEncoder() { - return new BCryptPasswordEncoder(10); - } - - @Bean - UserDetailsService customUserDetailsService() { - return new UserDetailsService() { - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - // authenticate, grant ADMIN role and return dummy user - Set authorities = new HashSet(); - authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + "ADMIN")); - return new User(username, bCryptPasswordEncoder().encode(DEFAULT_PASSWORD), authorities); - } - }; - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(customUserDetailsService()) - .passwordEncoder(bCryptPasswordEncoder()); - - } - - @Bean(name = BeanIds.AUTHENTICATION_MANAGER) - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManager(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf(); - http.headers() - .frameOptions() - .sameOrigin(); - - http.antMatcher("/**") - .userDetailsService(customUserDetailsService()) - .authorizeRequests() - .antMatchers("/**") - .permitAll() - .and() - .httpBasic(); - } -} diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index 1117749ded..fff93186a0 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -1,8 +1,5 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="sec" - uri="http://www.springframework.org/security/tags"%> - +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> +<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> @@ -11,19 +8,20 @@ Home Page - + AUTHENTICATED - + ADMIN ROLE - -

principal.username:

- -
- - Text Field:
- - +

+ principal.username: + +

+
+ + Text Field:
+ + \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index 995d5fa3df..c9c8698254 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -19,7 +19,7 @@ public class HomeControllerTest { @Test public void home() throws Exception { - String body = this.restTemplate.withBasicAuth("testUser", SecurityConfig.DEFAULT_PASSWORD) + String body = this.restTemplate.withBasicAuth("testUser", ApplicationConfig.DEFAULT_PASSWORD) .getForEntity("/", String.class) .getBody(); System.out.println(body); From d11fbc73adc2df6501ec9b8eb25d75cf6295d577 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Tue, 14 Aug 2018 14:46:35 +0800 Subject: [PATCH 09/59] refactor spring config --- spring-boot-security-taglibs/pom.xml | 132 +++++++++++++-------------- 1 file changed, 62 insertions(+), 70 deletions(-) diff --git a/spring-boot-security-taglibs/pom.xml b/spring-boot-security-taglibs/pom.xml index bd04ec3c0b..447f0c4be9 100644 --- a/spring-boot-security-taglibs/pom.xml +++ b/spring-boot-security-taglibs/pom.xml @@ -1,84 +1,76 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - spring-boot-security-taglibs - jar - spring-boot-security-taglibs - spring 5 security sample project + spring-boot-security-taglibs + jar + spring-boot-security-taglibs + spring 5 security sample project - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 - + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + - + - - org.springframework.boot - spring-boot-starter-security - + + org.springframework.boot + spring-boot-starter-security + - - org.springframework.boot - spring-boot-starter-web - + + org.springframework.boot + spring-boot-starter-web + - - - org.springframework.security - spring-security-taglibs - + + + org.springframework.security + spring-security-taglibs + - - - org.apache.tomcat.embed - tomcat-embed-jasper - provided - - - javax.servlet - jstl - - - - net.sourceforge.htmlunit - htmlunit - + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + javax.servlet + jstl + - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.security - spring-security-test - test - + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + - + - - spring-5-security-taglibs - - - src/main/resources - true - - + + spring-5-security-taglibs + + + src/main/resources + true + + + - - - - - - - UTF-8 - UTF-8 - 1.8 - + + UTF-8 + UTF-8 + 1.8 + \ No newline at end of file From bdad13227e25b4c76ce8ca8c70e9fef51795f195 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Tue, 14 Aug 2018 15:10:05 +0800 Subject: [PATCH 10/59] Update README.md --- spring-boot-security-taglibs/README.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/spring-boot-security-taglibs/README.md b/spring-boot-security-taglibs/README.md index f7eb314869..8b13789179 100644 --- a/spring-boot-security-taglibs/README.md +++ b/spring-boot-security-taglibs/README.md @@ -1,19 +1 @@ -========= -## Spring Security Login Example Project - -###The Course -The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - -### Relevant Articles: -- [Spring Security Form Login](http://www.baeldung.com/spring-security-login) -- [Spring Security Logout](http://www.baeldung.com/spring-security-logout) -- [Spring Security Expressions – hasRole Example](http://www.baeldung.com/spring-security-expressions-basic) -- [Spring HTTP/HTTPS Channel Security](http://www.baeldung.com/spring-channel-security-https) -- [Spring Security - Customize the 403 Forbidden/Access Denied Page](http://www.baeldung.com/spring-security-custom-access-denied-page) -- [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login) - -### Build the Project -``` -mvn clean install -``` From 4b1f9559808e42099f57d1272b0c6f11cb06bc72 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Tue, 14 Aug 2018 22:57:17 +0800 Subject: [PATCH 11/59] fi alignment --- .../src/main/webapp/WEB-INF/views/home.jsp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index fff93186a0..c13590a3df 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -10,7 +10,7 @@ AUTHENTICATED - +
ADMIN ROLE @@ -20,7 +20,8 @@
- Text Field:
+ Text Field: +
From 0d684eed97acea7aaf326d3b399c64c5b0c5090b Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Sat, 18 Aug 2018 17:23:07 +0800 Subject: [PATCH 12/59] fix requested comments --- .../baeldung/security/ApplicationConfig.java | 39 ++++++++++--------- .../org/baeldung/security/HomeController.java | 6 ++- .../src/main/resources/application.properties | 5 --- .../src/main/webapp/WEB-INF/views/home.jsp | 35 +++++++++-------- .../baeldung/security/HomeControllerTest.java | 23 +++++++++-- 5 files changed, 62 insertions(+), 46 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java index 6283a102aa..763422e6df 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java @@ -1,40 +1,41 @@ package org.baeldung.security; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; -import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; @SpringBootApplication @Configuration @EnableWebSecurity public class ApplicationConfig extends WebSecurityConfigurerAdapter { - public static final String DEFAULT_PASSWORD = "password"; + // Using withDefaultPasswordEncoder and InMemoryUserDetailsManager for demonstration and testing purpose + @Bean @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + public UserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("testUser") + .password("password") + .roles("ADMIN") + .build(); - auth.inMemoryAuthentication() - .passwordEncoder(encoder) - .withUser("testUser") - .password(encoder.encode(DEFAULT_PASSWORD)) - .roles("ADMIN"); + return new InMemoryUserDetailsManager(user); } @Override protected void configure(HttpSecurity http) throws Exception { - http.csrf(); - - http.authorizeRequests() - .antMatchers("/**") - .permitAll() - .and() - .httpBasic(); + // @formatter:off + http.csrf() + .and() + .authorizeRequests() + .anyRequest().permitAll().and().httpBasic(); + // @formatter:on } } diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java index e697e7e301..cdd4c3f42b 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java @@ -1,6 +1,7 @@ package org.baeldung.security; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @@ -9,8 +10,9 @@ import javax.servlet.http.HttpServletResponse; @Controller @RequestMapping("/") public class HomeController { - @RequestMapping("") - public String home(HttpServletRequest request, HttpServletResponse response) { + + @GetMapping + public String home() { return "home"; } } diff --git a/spring-boot-security-taglibs/src/main/resources/application.properties b/spring-boot-security-taglibs/src/main/resources/application.properties index 9c49bd2137..218868405f 100644 --- a/spring-boot-security-taglibs/src/main/resources/application.properties +++ b/spring-boot-security-taglibs/src/main/resources/application.properties @@ -1,8 +1,3 @@ #jsp config spring.mvc.view.prefix: /WEB-INF/views/ spring.mvc.view.suffix: .jsp -spring.http.encoding.charset=UTF-8 -# Enable http encoding support. -spring.http.encoding.enabled=true -# Force the encoding to the configured charset on HTTP requests and responses. -spring.http.encoding.force=true diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index c13590a3df..7291608e3e 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -1,5 +1,7 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="sec" + uri="http://www.springframework.org/security/tags"%> @@ -8,21 +10,22 @@ Home Page + + ANONYMOUS + - AUTHENTICATED + AUTHENTICATED + + ADMIN ROLE + +

+ principal.username: + +

+
+ + Text Field:
+
- - ADMIN ROLE - -

- principal.username: - -

-
- - Text Field: -
- - \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index c9c8698254..c005185c92 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -1,5 +1,6 @@ package org.baeldung.security; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -18,11 +19,13 @@ public class HomeControllerTest { private TestRestTemplate restTemplate; @Test - public void home() throws Exception { - String body = this.restTemplate.withBasicAuth("testUser", ApplicationConfig.DEFAULT_PASSWORD) + public void whenUserIsAuthenticatedThenAuthenticatedSectionsShowOnSite() throws Exception { + String body = this.restTemplate.withBasicAuth("testUser", "password") .getForEntity("/", String.class) .getBody(); - System.out.println(body); + + // test + assertFalse(body.contains("ANONYMOUS")); // test assertTrue(body.contains("AUTHENTICATED")); @@ -31,7 +34,7 @@ public class HomeControllerTest { assertTrue(body.contains("ADMIN ROLE")); // test - assertTrue(body.contains("principal.username: testUser")); + assertTrue(body.contains("testUser")); // test assertTrue(body.contains(" assertTrue(body.contains("")); } + + @Test + public void whenUserIsNotAuthenticatedThenOnlyAnonymousSectionsShowOnSite() throws Exception { + String body = this.restTemplate.getForEntity("/", String.class) + .getBody(); + + // test + assertTrue(body.contains("ANONYMOUS")); + + // test + assertFalse(body.contains("AUTHENTICATED")); + } } From 3f8eddad332a4b7e3013e977ca9c57de12050ebc Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Sun, 19 Aug 2018 17:24:43 +0800 Subject: [PATCH 13/59] additional tests and content --- .../main/java/org/baeldung/security/ApplicationConfig.java | 1 + .../src/main/webapp/WEB-INF/views/home.jsp | 7 +++++-- .../java/org/baeldung/security/HomeControllerTest.java | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java index 763422e6df..6419da3bdd 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java @@ -35,6 +35,7 @@ public class ApplicationConfig extends WebSecurityConfigurerAdapter { http.csrf() .and() .authorizeRequests() + .antMatchers("/adminOnlyURL").hasRole("ADMIN") .anyRequest().permitAll().and().httpBasic(); // @formatter:on } diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index 7291608e3e..eed24182e2 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -14,9 +14,9 @@ ANONYMOUS - AUTHENTICATED + AUTHENTICATED Content - ADMIN ROLE + Content for users who have the "ADMIN" role.

principal.username: @@ -26,6 +26,9 @@ Text Field:
+ + Go to Admin Only URL + \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index c005185c92..78b3089fba 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -31,11 +31,14 @@ public class HomeControllerTest { assertTrue(body.contains("AUTHENTICATED")); // test - assertTrue(body.contains("ADMIN ROLE")); + assertTrue(body.contains("Content for users who have the \"ADMIN\" role.")); // test assertTrue(body.contains("testUser")); + // test + assertTrue(body.contains("")); + // test assertTrue(body.contains(" Date: Sun, 19 Aug 2018 17:34:29 +0800 Subject: [PATCH 14/59] additional tests and content --- .../src/main/webapp/WEB-INF/views/home.jsp | 5 ++--- .../test/java/org/baeldung/security/HomeControllerTest.java | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index eed24182e2..9bb96fe5fd 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -11,7 +11,7 @@ - ANONYMOUS + ANONYMOUS Content AUTHENTICATED Content @@ -19,8 +19,7 @@ Content for users who have the "ADMIN" role.

- principal.username: - + Welcome back,

diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index 78b3089fba..189a691496 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -28,7 +28,7 @@ public class HomeControllerTest { assertFalse(body.contains("ANONYMOUS")); // test - assertTrue(body.contains("AUTHENTICATED")); + assertTrue(body.contains("AUTHENTICATED Content")); // test assertTrue(body.contains("Content for users who have the \"ADMIN\" role.")); @@ -52,9 +52,9 @@ public class HomeControllerTest { .getBody(); // test - assertTrue(body.contains("ANONYMOUS")); + assertTrue(body.contains("ANONYMOUS Content")); // test - assertFalse(body.contains("AUTHENTICATED")); + assertFalse(body.contains("AUTHENTICATED Content")); } } From 7263e223c5c2cfd5f8c81be494eb47710098dbd2 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Tue, 21 Aug 2018 22:31:44 +0800 Subject: [PATCH 15/59] update examples --- .../baeldung/security/ApplicationConfig.java | 2 +- .../src/main/webapp/WEB-INF/views/home.jsp | 24 +++++++++++-------- .../baeldung/security/HomeControllerTest.java | 16 ++++++------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java index 6419da3bdd..e8a95af5ce 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java @@ -35,7 +35,7 @@ public class ApplicationConfig extends WebSecurityConfigurerAdapter { http.csrf() .and() .authorizeRequests() - .antMatchers("/adminOnlyURL").hasRole("ADMIN") + .antMatchers("/userManagement").hasRole("ADMIN") .anyRequest().permitAll().and().httpBasic(); // @formatter:on } diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index 9bb96fe5fd..70440e8dc9 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -9,24 +9,28 @@ Home Page - - - ANONYMOUS Content + + + Login + + + Logout + + - AUTHENTICATED Content - - Content for users who have the "ADMIN" role. -

Welcome back, -

+

+ + Manage Users + Text Field:
- -
Go to Admin Only URL + + Manage Users
diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java index 189a691496..e085fb4083 100644 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java @@ -24,20 +24,20 @@ public class HomeControllerTest { .getForEntity("/", String.class) .getBody(); - // test - assertFalse(body.contains("ANONYMOUS")); + // test + assertFalse(body.contains("Login")); // test - assertTrue(body.contains("AUTHENTICATED Content")); + assertTrue(body.contains("Logout")); // test - assertTrue(body.contains("Content for users who have the \"ADMIN\" role.")); + assertTrue(body.contains("Manage Users")); // test assertTrue(body.contains("testUser")); // test - assertTrue(body.contains("")); + assertTrue(body.contains("")); // test assertTrue(body.contains(" - assertTrue(body.contains("ANONYMOUS Content")); + // test + assertTrue(body.contains("Login")); // test - assertFalse(body.contains("AUTHENTICATED Content")); + assertFalse(body.contains("Logout")); } } From 221ecbdae68b7e706e99236754b727d506e5943f Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Wed, 22 Aug 2018 22:07:20 +0800 Subject: [PATCH 16/59] Delete Readme file --- spring-boot-security-taglibs/README.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 spring-boot-security-taglibs/README.md diff --git a/spring-boot-security-taglibs/README.md b/spring-boot-security-taglibs/README.md deleted file mode 100644 index 8b13789179..0000000000 --- a/spring-boot-security-taglibs/README.md +++ /dev/null @@ -1 +0,0 @@ - From fe7b8bf4ba67ce520c764049da162af307837443 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Wed, 22 Aug 2018 23:19:31 +0800 Subject: [PATCH 17/59] edit form example --- .../src/main/java/org/baeldung/security/HomeController.java | 6 +----- .../src/main/webapp/WEB-INF/views/home.jsp | 3 ++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java index cdd4c3f42b..7e70c269cb 100644 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java +++ b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java @@ -1,17 +1,13 @@ package org.baeldung.security; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - @Controller @RequestMapping("/") public class HomeController { - @GetMapping + @RequestMapping public String home() { return "home"; } diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp index 70440e8dc9..80ecd61cb5 100644 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp @@ -25,9 +25,10 @@ Manage Users -
+ Text Field:
+
Manage Users From b1fd7611b236a48b26e520ee11ccea1668a329ef Mon Sep 17 00:00:00 2001 From: Filipe Martins Date: Thu, 23 Aug 2018 08:44:03 -0300 Subject: [PATCH 18/59] Update FindKthLargest.java Fix random pivot --- .../java/com/baeldung/algorithms/kthlargest/FindKthLargest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java b/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java index 822abdae02..7054979ada 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java @@ -98,7 +98,7 @@ public class FindKthLargest { private int randomPartition(Integer arr[], int left, int right) { int n = right - left + 1; - int pivot = (int) (Math.random()) % n; + int pivot = (int) (Math.random() * n); swap(arr, left + pivot, right); return partition(arr, left, right); } From 8e5586ca48f7d12b2666a47d269dad9bc21d527d Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Fri, 24 Aug 2018 23:46:12 +0800 Subject: [PATCH 19/59] adding example for spring boot security tag libs --- spring-boot-security/pom.xml | 17 ++++++ .../springsecuritytaglibs/HomeController.java | 14 +++++ .../SpringBootSecurityTagLibsApplication.java | 9 +++ .../SpringBootSecurityTagLibsConfig.java | 31 ++++++++++ .../resources/application-taglibs.properties | 3 + .../src/main/resources/application.properties | 2 +- .../src/main/webapp/WEB-INF/views/home.jsp | 38 ++++++++++++ .../HomeControllerUnitTest.java | 60 +++++++++++++++++++ 8 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java create mode 100644 spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java create mode 100644 spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java create mode 100644 spring-boot-security/src/main/resources/application-taglibs.properties create mode 100644 spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp create mode 100644 spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java diff --git a/spring-boot-security/pom.xml b/spring-boot-security/pom.xml index 12f51eec94..b1673d383e 100644 --- a/spring-boot-security/pom.xml +++ b/spring-boot-security/pom.xml @@ -44,6 +44,23 @@ org.springframework.boot spring-boot-starter-web + + + + org.springframework.security + spring-security-taglibs + + + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + javax.servlet + jstl + org.springframework.boot diff --git a/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java new file mode 100644 index 0000000000..eca093a76f --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java @@ -0,0 +1,14 @@ +package com.baeldung.springsecuritytaglibs; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/") +public class HomeController { + + @RequestMapping + public String home() { + return "home"; + } +} diff --git a/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java new file mode 100644 index 0000000000..397ea47f96 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java @@ -0,0 +1,9 @@ +package com.baeldung.springsecuritytaglibs; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-taglibs.properties") +public class SpringBootSecurityTagLibsApplication { +} diff --git a/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java new file mode 100644 index 0000000000..665dd0bce9 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java @@ -0,0 +1,31 @@ +package com.baeldung.springsecuritytaglibs.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +public class SpringBootSecurityTagLibsConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("testUser") + .password("password") + .roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.csrf() + .and() + .authorizeRequests() + .antMatchers("/userManagement").hasRole("ADMIN") + .anyRequest().permitAll().and().httpBasic(); + // @formatter:on + } +} \ No newline at end of file diff --git a/spring-boot-security/src/main/resources/application-taglibs.properties b/spring-boot-security/src/main/resources/application-taglibs.properties new file mode 100644 index 0000000000..218868405f --- /dev/null +++ b/spring-boot-security/src/main/resources/application-taglibs.properties @@ -0,0 +1,3 @@ +#jsp config +spring.mvc.view.prefix: /WEB-INF/views/ +spring.mvc.view.suffix: .jsp diff --git a/spring-boot-security/src/main/resources/application.properties b/spring-boot-security/src/main/resources/application.properties index c2b8d70dc6..e776132359 100644 --- a/spring-boot-security/src/main/resources/application.properties +++ b/spring-boot-security/src/main/resources/application.properties @@ -1,4 +1,4 @@ #spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration #security.user.password=password #security.oauth2.client.client-id=client -#security.oauth2.client.client-secret=secret +#security.oauth2.client.client-secret=secret \ No newline at end of file diff --git a/spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp new file mode 100644 index 0000000000..80ecd61cb5 --- /dev/null +++ b/spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp @@ -0,0 +1,38 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="sec" + uri="http://www.springframework.org/security/tags"%> + + + + + +Home Page + + + + Login + + + + Logout + + + +

+ Welcome back, +

+ + Manage Users + +
+ + Text Field:
+ + + + Manage Users + +
+ + \ No newline at end of file diff --git a/spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java b/spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java new file mode 100644 index 0000000000..0585c06a59 --- /dev/null +++ b/spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.springsecuritytaglibs; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = SpringBootSecurityTagLibsApplication.class) +public class HomeControllerUnitTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void whenUserIsAuthenticatedThenAuthenticatedSectionsShowOnSite() throws Exception { + String body = this.restTemplate.withBasicAuth("testUser", "password") + .getForEntity("/", String.class) + .getBody(); + + // test + assertFalse(body.contains("Login")); + + // test + assertTrue(body.contains("Logout")); + + // test + assertTrue(body.contains("Manage Users")); + + // test + assertTrue(body.contains("testUser")); + + // test + assertTrue(body.contains("")); + + // test + assertTrue(body.contains(" + assertTrue(body.contains("")); + } + + @Test + public void whenUserIsNotAuthenticatedThenOnlyAnonymousSectionsShowOnSite() throws Exception { + String body = this.restTemplate.getForEntity("/", String.class) + .getBody(); + + // test + assertTrue(body.contains("Login")); + + // test + assertFalse(body.contains("Logout")); + } +} From afdb37eb02b5f833a6278d2b8fdd651d8d0e436d Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Fri, 24 Aug 2018 23:48:20 +0800 Subject: [PATCH 20/59] Remove old tag libs module --- spring-boot-security-taglibs/.gitignore | 13 ---- spring-boot-security-taglibs/pom.xml | 76 ------------------- .../baeldung/security/ApplicationConfig.java | 42 ---------- .../org/baeldung/security/HomeController.java | 14 ---- .../src/main/resources/application.properties | 3 - .../src/main/webapp/WEB-INF/views/home.jsp | 38 ---------- .../baeldung/security/HomeControllerTest.java | 60 --------------- 7 files changed, 246 deletions(-) delete mode 100644 spring-boot-security-taglibs/.gitignore delete mode 100644 spring-boot-security-taglibs/pom.xml delete mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java delete mode 100644 spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java delete mode 100644 spring-boot-security-taglibs/src/main/resources/application.properties delete mode 100644 spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp delete mode 100644 spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java diff --git a/spring-boot-security-taglibs/.gitignore b/spring-boot-security-taglibs/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/spring-boot-security-taglibs/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/spring-boot-security-taglibs/pom.xml b/spring-boot-security-taglibs/pom.xml deleted file mode 100644 index 447f0c4be9..0000000000 --- a/spring-boot-security-taglibs/pom.xml +++ /dev/null @@ -1,76 +0,0 @@ - - 4.0.0 - - spring-boot-security-taglibs - jar - spring-boot-security-taglibs - spring 5 security sample project - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 - - - - - - org.springframework.boot - spring-boot-starter-security - - - - org.springframework.boot - spring-boot-starter-web - - - - - org.springframework.security - spring-security-taglibs - - - - - org.apache.tomcat.embed - tomcat-embed-jasper - provided - - - javax.servlet - jstl - - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.security - spring-security-test - test - - - - - - spring-5-security-taglibs - - - src/main/resources - true - - - - - - UTF-8 - UTF-8 - 1.8 - - - \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java deleted file mode 100644 index e8a95af5ce..0000000000 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/ApplicationConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.security; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -@SpringBootApplication -@Configuration -@EnableWebSecurity -public class ApplicationConfig extends WebSecurityConfigurerAdapter { - - // Using withDefaultPasswordEncoder and InMemoryUserDetailsManager for demonstration and testing purpose - @Bean - @Override - public UserDetailsService userDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("testUser") - .password("password") - .roles("ADMIN") - .build(); - - return new InMemoryUserDetailsManager(user); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http.csrf() - .and() - .authorizeRequests() - .antMatchers("/userManagement").hasRole("ADMIN") - .anyRequest().permitAll().and().httpBasic(); - // @formatter:on - } -} diff --git a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java b/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java deleted file mode 100644 index 7e70c269cb..0000000000 --- a/spring-boot-security-taglibs/src/main/java/org/baeldung/security/HomeController.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.security; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -@RequestMapping("/") -public class HomeController { - - @RequestMapping - public String home() { - return "home"; - } -} diff --git a/spring-boot-security-taglibs/src/main/resources/application.properties b/spring-boot-security-taglibs/src/main/resources/application.properties deleted file mode 100644 index 218868405f..0000000000 --- a/spring-boot-security-taglibs/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -#jsp config -spring.mvc.view.prefix: /WEB-INF/views/ -spring.mvc.view.suffix: .jsp diff --git a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp deleted file mode 100644 index 80ecd61cb5..0000000000 --- a/spring-boot-security-taglibs/src/main/webapp/WEB-INF/views/home.jsp +++ /dev/null @@ -1,38 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" - pageEncoding="UTF-8"%> -<%@ taglib prefix="sec" - uri="http://www.springframework.org/security/tags"%> - - - - - -Home Page - - - - Login - - - - Logout - - - -

- Welcome back, -

- - Manage Users - -
- - Text Field:
- - - -
Manage Users -
-
- - \ No newline at end of file diff --git a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java b/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java deleted file mode 100644 index e085fb4083..0000000000 --- a/spring-boot-security-taglibs/src/test/java/org/baeldung/security/HomeControllerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.baeldung.security; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -public class HomeControllerTest { - - @Autowired - private TestRestTemplate restTemplate; - - @Test - public void whenUserIsAuthenticatedThenAuthenticatedSectionsShowOnSite() throws Exception { - String body = this.restTemplate.withBasicAuth("testUser", "password") - .getForEntity("/", String.class) - .getBody(); - - // test - assertFalse(body.contains("Login")); - - // test - assertTrue(body.contains("Logout")); - - // test - assertTrue(body.contains("Manage Users")); - - // test - assertTrue(body.contains("testUser")); - - // test - assertTrue(body.contains("")); - - // test - assertTrue(body.contains(" - assertTrue(body.contains("")); - } - - @Test - public void whenUserIsNotAuthenticatedThenOnlyAnonymousSectionsShowOnSite() throws Exception { - String body = this.restTemplate.getForEntity("/", String.class) - .getBody(); - - // test - assertTrue(body.contains("Login")); - - // test - assertFalse(body.contains("Logout")); - } -} From 2ee3d2ffd9c627f39e0cbcb0df0e5a23741a4be0 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Mon, 10 Sep 2018 19:05:14 +0800 Subject: [PATCH 21/59] BAEL-2147 Add GsonTest --- .../com/baeldung/kotlin/gson/GsonUnitTest.kt | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt new file mode 100644 index 0000000000..fce3225ef8 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt @@ -0,0 +1,34 @@ +package com.baeldung.kotlin.gson + +import com.baeldung.datetime.UsePeriod +import com.google.gson.Gson +import com.google.gson.annotations.SerializedName +import java.time.LocalDate +import java.time.Period + +import org.junit.Assert +import org.junit.Test + +class GsonUnitTest { + + var gson = Gson() + + @Test + fun givenObject_thenGetJSONString() { + var jsonString = gson.toJson(TestModel(1,"Test")) + Assert.assertEquals(jsonString, "{\"id\":1,\"description\":\"Test\"}") + } + + @Test + fun givenJSONString_thenGetObject() { + var jsonString = "{\"id\":1,\"description\":\"Test\"}"; + var testModel = gson.fromJson(jsonString, TestModel::class.java) + Assert.assertEquals(testModel.id, 1) + Assert.assertEquals(testModel.description, "Test") + } + + data class TestModel( + val id: Int, + val description: String + ) +} \ No newline at end of file From 8962f0a3b6fc985712db3605b3520ff095076eb5 Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Mon, 10 Sep 2018 19:11:44 +0800 Subject: [PATCH 22/59] BAEL-2147 Remove unused import --- .../src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt index fce3225ef8..bdf44d3b49 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt @@ -1,10 +1,6 @@ package com.baeldung.kotlin.gson -import com.baeldung.datetime.UsePeriod import com.google.gson.Gson -import com.google.gson.annotations.SerializedName -import java.time.LocalDate -import java.time.Period import org.junit.Assert import org.junit.Test From acbd7ea6b2e8b5cfe534a01c3fe2388dd3bdc970 Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Sat, 15 Sep 2018 22:07:27 +0200 Subject: [PATCH 23/59] added link --- libraries-data/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries-data/README.md b/libraries-data/README.md index 652ae0e04c..63ee5f9947 100644 --- a/libraries-data/README.md +++ b/libraries-data/README.md @@ -11,3 +11,4 @@ - [Apache Ignite with Spring Data](http://www.baeldung.com/apache-ignite-spring-data) - [Guide to JMapper](https://www.baeldung.com/jmapper) - [A Guide to Apache Crunch](https://www.baeldung.com/apache-crunch) +- [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline) From 68618ed5e03a2f24869d59067e15e2a7e26076f5 Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Sat, 15 Sep 2018 22:08:35 +0200 Subject: [PATCH 24/59] added link --- java-strings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/java-strings/README.md b/java-strings/README.md index 233d986d98..8f0ab60a53 100644 --- a/java-strings/README.md +++ b/java-strings/README.md @@ -27,3 +27,4 @@ - [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string) - [Java Check a String for Lowercase/Uppercase Letter, Special Character and Digit](https://www.baeldung.com/java-lowercase-uppercase-special-character-digit-regex) - [Convert java.util.Date to String](https://www.baeldung.com/java-util-date-to-string) +- [Get Substring from String in Java](https://www.baeldung.com/java-substring) From 69f149835bed8f569019829af163504ffbb232b0 Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Sun, 16 Sep 2018 22:23:43 +0200 Subject: [PATCH 25/59] added link --- hibernate5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/hibernate5/README.md b/hibernate5/README.md index 8f2f8eb469..e42229a152 100644 --- a/hibernate5/README.md +++ b/hibernate5/README.md @@ -14,3 +14,4 @@ - [Bootstrapping JPA Programmatically in Java](http://www.baeldung.com/java-bootstrap-jpa) - [Optimistic Locking in JPA](http://www.baeldung.com/jpa-optimistic-locking) - [Hibernate Entity Lifecycle](https://www.baeldung.com/hibernate-entity-lifecycle) +- [Mapping A Hibernate Query to a Custom Class](https://www.baeldung.com/hibernate-query-to-custom-class) From 7b1e4c8e759329d78fc7999691f4d684666378e6 Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Sun, 16 Sep 2018 22:25:10 +0200 Subject: [PATCH 26/59] added link --- jersey/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/jersey/README.md b/jersey/README.md index 3121c560cf..89e93107f7 100644 --- a/jersey/README.md +++ b/jersey/README.md @@ -1,2 +1,3 @@ - [Jersey Filters and Interceptors](http://www.baeldung.com/jersey-filters-interceptors) - [Jersey MVC Support](https://www.baeldung.com/jersey-mvc) +- [Bean Validation in Jersey](https://www.baeldung.com/jersey-bean-validation) From 9280b9e81bd0e0ca2b3589e03ff3218f0db6f516 Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Mon, 17 Sep 2018 20:21:35 +0200 Subject: [PATCH 27/59] added link --- core-java-collections/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-collections/README.md b/core-java-collections/README.md index f187141712..4502998c52 100644 --- a/core-java-collections/README.md +++ b/core-java-collections/README.md @@ -49,3 +49,4 @@ - [Collections.emptyList() vs. New List Instance](https://www.baeldung.com/java-collections-emptylist-new-list) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) - [](https://www.baeldung.com/java-hashset-arraylist-contains-performance) +- [Differences Between Collection.clear() and Collection.removeAll()](https://www.baeldung.com/java-collection-clear-vs-removeall) From af993076f16d079bf50f71ec005f2cefd1011dca Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Wed, 26 Sep 2018 23:24:26 +0800 Subject: [PATCH 28/59] LoopTest class --- .../kotlin/com/baeldung/kotlin/LoopTest.kt | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt new file mode 100644 index 0000000000..e95592590b --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt @@ -0,0 +1,79 @@ +package com.baeldung.kotlin + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +class LoopTest { + + @Test + fun givenLoop_whenBreak_thenComplete() { + var value = 0 + + for (i in 1..100) { + value = i + if (value == 30) + break; + } + + assertEquals(value, 30) + + outer_loop@ for (i in 1..10) { + for (j in 1..10) { + value = i * j + if (value == 30) + break@outer_loop; + } + } + + assertEquals(value, 30) + } + + @Test + fun givenLambda_whenReturn_thenComplete() { + listOf(1, 2, 3, 4, 5).forEach { + if (it == 3) return // non-local return directly to the caller + assert(it < 3) + } + //this point is unreachable + assert(false); + } + + @Test + fun givenLambda_whenReturnWithExplicitLabel_thenComplete() { + var result = mutableListOf(); + + listOf(1, 2, 3, 4, 5).forEach lit@{ + if (it == 3){ + // local return to the caller of the lambda, i.e. the forEach loop + return@lit + } + result.add(it) + } + + assert(1 in result + && 2 in result + && 4 in result + && 5 in result) + assertFalse(3 in result) + } + + @Test + fun givenLambda_whenReturnWithImplicitLabel_thenComplete() { + var result = mutableListOf(); + + listOf(1, 2, 3, 4, 5).forEach { + if (it == 3){ + // local return to the caller of the lambda, i.e. the forEach loop + return@forEach + } + result.add(it) + } + + assert(1 in result + && 2 in result + && 4 in result + && 5 in result) + assertFalse(3 in result) + } +} \ No newline at end of file From df99b29fb3756f5a01bda012553760666d84fed6 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Fri, 28 Sep 2018 10:00:44 +0800 Subject: [PATCH 29/59] test cases --- .../kotlin/com/baeldung/kotlin/LoopTest.kt | 72 +++++++++++++++---- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt index e95592590b..3f1afb19c3 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt @@ -10,14 +10,16 @@ class LoopTest { fun givenLoop_whenBreak_thenComplete() { var value = 0 - for (i in 1..100) { + //break loop without label + for (i in 1..10) { value = i - if (value == 30) + if (value == 3) break; } - assertEquals(value, 30) + assertEquals(value, 3) + //break loop with label outer_loop@ for (i in 1..10) { for (j in 1..10) { value = i * j @@ -29,6 +31,31 @@ class LoopTest { assertEquals(value, 30) } + @Test + fun givenLoop_whenContinue_thenComplete() { + var processedList = mutableListOf() + //continue loop without label + for (i in 1..10) { + if (i == 3) + continue; + processedList.add(i) + } + + assert(processedList.all { it -> it != 3 }) + + //continue loop with label + processedList = mutableListOf() + outer_loop@ for (i in 1..10) { + for (j in 1..10) { + if (i == 3) + continue@outer_loop; + processedList.add(i*j) + } + } + + assertEquals(processedList.size, 90) + } + @Test fun givenLambda_whenReturn_thenComplete() { listOf(1, 2, 3, 4, 5).forEach { @@ -44,18 +71,14 @@ class LoopTest { var result = mutableListOf(); listOf(1, 2, 3, 4, 5).forEach lit@{ - if (it == 3){ + if (it == 3) { // local return to the caller of the lambda, i.e. the forEach loop return@lit } result.add(it) } - assert(1 in result - && 2 in result - && 4 in result - && 5 in result) - assertFalse(3 in result) + assert(result.all { it -> it != 3 }); } @Test @@ -63,17 +86,36 @@ class LoopTest { var result = mutableListOf(); listOf(1, 2, 3, 4, 5).forEach { - if (it == 3){ + if (it == 3) { // local return to the caller of the lambda, i.e. the forEach loop return@forEach } result.add(it) } - assert(1 in result - && 2 in result - && 4 in result - && 5 in result) - assertFalse(3 in result) + assert(result.all { it -> it != 3 }); + } + + @Test + fun givenAnonymousFunction_return_thenComplete() { + var result = mutableListOf(); + listOf(1, 2, 3, 4, 5).forEach(fun(element: Int) { + if (element == 3) return // local return to the caller of the anonymous fun, i.e. the forEach loop + result.add(element); + }) + + assert(result.all { it -> it != 3 }); + } + + @Test + fun givenAnonymousFunction_returnToLabel_thenComplete() { + var value = 0; + run loop@{ + listOf(1, 2, 3, 4, 5).forEach { + value = it; + if (it == 3) return@loop // non-local return from the lambda passed to run + } + } + assertEquals(value, 3) } } \ No newline at end of file From 6c0c94449d7e43eadd0406fa65dcc2897179da1b Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Fri, 28 Sep 2018 10:01:45 +0800 Subject: [PATCH 30/59] StructuralJumpTest --- .../com/baeldung/kotlin/{LoopTest.kt => StructuralJumpTest.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename core-kotlin/src/test/kotlin/com/baeldung/kotlin/{LoopTest.kt => StructuralJumpTest.kt} (99%) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt similarity index 99% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt index 3f1afb19c3..55b90deaa4 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LoopTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt @@ -4,7 +4,7 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -class LoopTest { +class StructuralJumpTest { @Test fun givenLoop_whenBreak_thenComplete() { From 03f28236b8b51812a6fad8cc9b20d4bed7764498 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Fri, 28 Sep 2018 15:08:08 +0400 Subject: [PATCH 31/59] merge maps first example --- .../com/baeldung/map/java_8/MergeMaps.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java new file mode 100644 index 0000000000..2137bd9094 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -0,0 +1,41 @@ +package com.baeldung.map.java_8; + +import com.baeldung.sort.Employee; + +import java.util.HashMap; +import java.util.Map; + +public class MergeMaps { + + private static Map map1 = new HashMap<>(); + private static Map map2 = new HashMap<>(); + + public static void main(String[] args) { + + initialize(); + + Map map3 = new HashMap<>(map1); + + map2.forEach( + (key, value) -> map3.merge(key, value, (v1, v2) -> + new Employee(v1.getId(),v2.getName())) + ); + + map3.entrySet().forEach(System.out::println); + } + + private static void initialize() { + Employee employee1 = new Employee(1L, "Henry"); + map1.put(employee1.getName(), employee1); + Employee employee2 = new Employee(22L, "Annie"); + map1.put(employee2.getName(), employee2); + Employee employee3 = new Employee(8L, "John"); + map1.put(employee3.getName(), employee3); + + Employee employee4 = new Employee(2L, "George"); + map2.put(employee4.getName(), employee4); + Employee employee5 = new Employee(1L, "Henry"); + map2.put(employee5.getName(), employee5); + } + +} From ee7fa854b45148eb01fb9bc7adb9c633eb705873 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Fri, 28 Sep 2018 17:32:11 +0400 Subject: [PATCH 32/59] merge maps more examples --- .../com/baeldung/map/java_8/MergeMaps.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java index 2137bd9094..a5dada4152 100644 --- a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -4,6 +4,8 @@ import com.baeldung.sort.Employee; import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class MergeMaps { @@ -14,16 +16,50 @@ public class MergeMaps { initialize(); + //mergeFunction(); + + //streamConcat(); + + streamOf(); + } + + private static void streamOf() { + Map map3 = Stream.of(map1, map2) + .flatMap(map -> map.entrySet().stream()) + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (v1, v2) -> new Employee(v1.getId(), v2.getName()) + ) + ); + + map3.entrySet().forEach(System.out::println); + } + + private static void streamConcat() { + Map result = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (value1, value2) -> new Employee(value1.getId(), value2.getName()) + )); + + result.entrySet().forEach(System.out::println); + } + + private static void mergeFunction() { Map map3 = new HashMap<>(map1); map2.forEach( - (key, value) -> map3.merge(key, value, (v1, v2) -> - new Employee(v1.getId(),v2.getName())) + (key, value) -> map3.merge(key, value, (v1, v2) -> + new Employee(v1.getId(),v2.getName())) ); map3.entrySet().forEach(System.out::println); } + + private static void initialize() { Employee employee1 = new Employee(1L, "Henry"); map1.put(employee1.getName(), employee1); From 91efa72938f10da095eb4d7ab477020889a947df Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 30 Sep 2018 20:58:06 +0530 Subject: [PATCH 33/59] [BAEL-9460] - Added code examples of Add section in 'Comparison with Lambdas' article --- .../com/baeldung/java8/Java8SortUnitTest.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java index f371c0d7da..71ec5b147f 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java @@ -1,16 +1,18 @@ package com.baeldung.java8; -import com.baeldung.java8.entity.Human; -import com.google.common.collect.Lists; -import com.google.common.primitives.Ints; -import org.junit.Assert; -import org.junit.Test; +import static org.hamcrest.Matchers.equalTo; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; -import static org.hamcrest.Matchers.equalTo; +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.java8.entity.Human; +import com.google.common.collect.Lists; +import com.google.common.primitives.Ints; public class Java8SortUnitTest { @@ -111,5 +113,22 @@ public class Java8SortUnitTest { humans.sort(Comparator.comparing(Human::getName)); Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); } + + @Test + public final void givenStreamNaturalOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + final List letters = Lists.newArrayList("B", "A", "C"); + + final List sortedLetters = letters.stream().sorted().collect(Collectors.toList()); + Assert.assertThat(sortedLetters.get(0), equalTo("A")); + } + @Test + public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + final Comparator nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName()); + + final List sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList()); + Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); + } } From 3b4e23cedf14ce23de22b56d8346d64f8afada2b Mon Sep 17 00:00:00 2001 From: "nnhai1991@gmail.com" Date: Sun, 30 Sep 2018 23:40:19 +0800 Subject: [PATCH 34/59] refactor some code --- .../com/baeldung/kotlin/StructuralJumpTest.kt | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt index 55b90deaa4..076adfb94e 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt @@ -14,7 +14,7 @@ class StructuralJumpTest { for (i in 1..10) { value = i if (value == 3) - break; + break } assertEquals(value, 3) @@ -24,7 +24,7 @@ class StructuralJumpTest { for (j in 1..10) { value = i * j if (value == 30) - break@outer_loop; + break@outer_loop } } @@ -37,7 +37,7 @@ class StructuralJumpTest { //continue loop without label for (i in 1..10) { if (i == 3) - continue; + continue processedList.add(i) } @@ -48,7 +48,7 @@ class StructuralJumpTest { outer_loop@ for (i in 1..10) { for (j in 1..10) { if (i == 3) - continue@outer_loop; + continue@outer_loop processedList.add(i*j) } } @@ -63,12 +63,12 @@ class StructuralJumpTest { assert(it < 3) } //this point is unreachable - assert(false); + assert(false) } @Test fun givenLambda_whenReturnWithExplicitLabel_thenComplete() { - var result = mutableListOf(); + var result = mutableListOf() listOf(1, 2, 3, 4, 5).forEach lit@{ if (it == 3) { @@ -78,12 +78,12 @@ class StructuralJumpTest { result.add(it) } - assert(result.all { it -> it != 3 }); + assert(result.all { it -> it != 3 }) } @Test fun givenLambda_whenReturnWithImplicitLabel_thenComplete() { - var result = mutableListOf(); + var result = mutableListOf() listOf(1, 2, 3, 4, 5).forEach { if (it == 3) { @@ -93,26 +93,26 @@ class StructuralJumpTest { result.add(it) } - assert(result.all { it -> it != 3 }); + assert(result.all { it -> it != 3 }) } @Test fun givenAnonymousFunction_return_thenComplete() { - var result = mutableListOf(); + var result = mutableListOf() listOf(1, 2, 3, 4, 5).forEach(fun(element: Int) { if (element == 3) return // local return to the caller of the anonymous fun, i.e. the forEach loop - result.add(element); + result.add(element) }) - assert(result.all { it -> it != 3 }); + assert(result.all { it -> it != 3 }) } @Test fun givenAnonymousFunction_returnToLabel_thenComplete() { - var value = 0; + var value = 0 run loop@{ listOf(1, 2, 3, 4, 5).forEach { - value = it; + value = it if (it == 3) return@loop // non-local return from the lambda passed to run } } From f0e93ad8fad29d103c55a1ffbdfd3921edd88ddb Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Mon, 1 Oct 2018 15:20:32 +0400 Subject: [PATCH 35/59] StreamEx example --- core-java-collections/pom.xml | 5 +++++ .../com/baeldung/map/java_8/MergeMaps.java | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/core-java-collections/pom.xml b/core-java-collections/pom.xml index d0c3c25beb..06b79fff22 100644 --- a/core-java-collections/pom.xml +++ b/core-java-collections/pom.xml @@ -68,6 +68,11 @@ commons-exec 1.3
+ + one.util + streamex + 0.6.5 + diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java index a5dada4152..e62e95b634 100644 --- a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -1,8 +1,13 @@ package com.baeldung.map.java_8; import com.baeldung.sort.Employee; +import one.util.streamex.EntryStream; +import one.util.streamex.IntCollector; +import one.util.streamex.StreamEx; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -20,7 +25,18 @@ public class MergeMaps { //streamConcat(); - streamOf(); + //streamOf(); + + streamEx(); + } + + private static void streamEx() { + Map map3 = EntryStream.of(map1) + .append(EntryStream.of(map2)) + .toMap((e1, e2) -> e1); + + System.out.println(map3); + } private static void streamOf() { From 7773f968dabe55c7e96f455829e0ec65a13772e6 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Mon, 1 Oct 2018 16:38:10 +0400 Subject: [PATCH 36/59] uncomment the methods --- .../src/main/java/com/baeldung/map/java_8/MergeMaps.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java index e62e95b634..4bf7b6ba5a 100644 --- a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -21,11 +21,11 @@ public class MergeMaps { initialize(); - //mergeFunction(); + mergeFunction(); - //streamConcat(); + streamConcat(); - //streamOf(); + streamOf(); streamEx(); } From 2c6a3a69b09ed2d901a452304030d21f5d3ca58a Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Tue, 2 Oct 2018 10:43:04 +0800 Subject: [PATCH 37/59] change example --- .../com/baeldung/kotlin/StructuralJumpTest.kt | 126 +++++++++--------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt index 076adfb94e..6866816517 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt @@ -4,118 +4,118 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -class StructuralJumpTest { +class StructuralJumpTest { @Test fun givenLoop_whenBreak_thenComplete() { - var value = 0 - - //break loop without label - for (i in 1..10) { - value = i - if (value == 3) + var value = "" + for (i in 'a'..'e') { + value += i.toString() + if (i == 'c') break } - - assertEquals(value, 3) - - //break loop with label - outer_loop@ for (i in 1..10) { - for (j in 1..10) { - value = i * j - if (value == 30) + assertEquals("abc", value) + } + @Test + fun givenLoop_whenBreakWithLabel_thenComplete() { + var value = "" + outer_loop@ for (i in 'a'..'d') { + for (j in 1..3) { + value += "" + i + j + if (i == 'b' && j == 1) break@outer_loop } } - - assertEquals(value, 30) + assertEquals("a1a2a3b1", value) } @Test fun givenLoop_whenContinue_thenComplete() { - var processedList = mutableListOf() - //continue loop without label - for (i in 1..10) { - if (i == 3) + var result = "" + for (i in 'a'..'d') { + if (i == 'b') continue - processedList.add(i) + result += i } - - assert(processedList.all { it -> it != 3 }) - - //continue loop with label - processedList = mutableListOf() - outer_loop@ for (i in 1..10) { - for (j in 1..10) { - if (i == 3) + assertEquals("acd", result) + } + @Test + fun givenLoop_whenContinueWithLabel_thenComplete() { + var result = "" + outer_loop@ for (i in 'a'..'c') { + for (j in 1..3) { + if (i == 'b') continue@outer_loop - processedList.add(i*j) + result += "" + i + j } } - - assertEquals(processedList.size, 90) + assertEquals("a1a2a3c1c2c3", result) } @Test fun givenLambda_whenReturn_thenComplete() { - listOf(1, 2, 3, 4, 5).forEach { - if (it == 3) return // non-local return directly to the caller - assert(it < 3) + var result = returnInLambda(); + assertEquals("hello", result) + } + + private fun returnInLambda(): String { + var result = "" + "hello_world".forEach { + // non-local return directly to the caller + if (it == '_') return result + result += it.toString() } - //this point is unreachable - assert(false) + //this line won't be reached + return result; } @Test fun givenLambda_whenReturnWithExplicitLabel_thenComplete() { - var result = mutableListOf() - - listOf(1, 2, 3, 4, 5).forEach lit@{ - if (it == 3) { + var result = "" + "hello_world".forEach lit@{ + if (it == 'o') { // local return to the caller of the lambda, i.e. the forEach loop return@lit } - result.add(it) + result += it.toString() } - - assert(result.all { it -> it != 3 }) + assertEquals("hell_wrld", result) } @Test fun givenLambda_whenReturnWithImplicitLabel_thenComplete() { - var result = mutableListOf() - - listOf(1, 2, 3, 4, 5).forEach { - if (it == 3) { + var result = "" + "hello_world".forEach { + if (it == 'o') { // local return to the caller of the lambda, i.e. the forEach loop return@forEach } - result.add(it) + result += it.toString() } - - assert(result.all { it -> it != 3 }) + assertEquals("hell_wrld", result) } @Test fun givenAnonymousFunction_return_thenComplete() { - var result = mutableListOf() - listOf(1, 2, 3, 4, 5).forEach(fun(element: Int) { - if (element == 3) return // local return to the caller of the anonymous fun, i.e. the forEach loop - result.add(element) + var result = "" + "hello_world".forEach(fun(element) { + // local return to the caller of the anonymous fun, i.e. the forEach loop + if (element == 'o') return + result += element.toString() }) - - assert(result.all { it -> it != 3 }) + assertEquals("hell_wrld", result) } @Test fun givenAnonymousFunction_returnToLabel_thenComplete() { - var value = 0 + var result = "" run loop@{ - listOf(1, 2, 3, 4, 5).forEach { - value = it - if (it == 3) return@loop // non-local return from the lambda passed to run + "hello_world".forEach { + // non-local return from the lambda passed to run + if (it == '_') return@loop + result += it.toString() } } - assertEquals(value, 3) + assertEquals("hello", result) } } \ No newline at end of file From 9eb81e705999bf44e0ec5fdffe6cc8d1aa9d1d57 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Tue, 2 Oct 2018 10:45:31 +0800 Subject: [PATCH 38/59] change example --- .../com/baeldung/kotlin/StructuralJumpTest.kt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt index 6866816517..b5183d3568 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt @@ -9,12 +9,12 @@ class StructuralJumpTest { @Test fun givenLoop_whenBreak_thenComplete() { var value = "" - for (i in 'a'..'e') { - value += i.toString() - if (i == 'c') + for (i in "hello_world") { + if (i == '_') break + value += i.toString() } - assertEquals("abc", value) + assertEquals("hello", value) } @Test fun givenLoop_whenBreakWithLabel_thenComplete() { @@ -32,12 +32,12 @@ class StructuralJumpTest { @Test fun givenLoop_whenContinue_thenComplete() { var result = "" - for (i in 'a'..'d') { - if (i == 'b') + for (i in "hello_world") { + if (i == '_') continue result += i } - assertEquals("acd", result) + assertEquals("helloworld", result) } @Test fun givenLoop_whenContinueWithLabel_thenComplete() { @@ -73,26 +73,26 @@ class StructuralJumpTest { fun givenLambda_whenReturnWithExplicitLabel_thenComplete() { var result = "" "hello_world".forEach lit@{ - if (it == 'o') { + if (it == '_') { // local return to the caller of the lambda, i.e. the forEach loop return@lit } result += it.toString() } - assertEquals("hell_wrld", result) + assertEquals("helloworld", result) } @Test fun givenLambda_whenReturnWithImplicitLabel_thenComplete() { var result = "" "hello_world".forEach { - if (it == 'o') { + if (it == '_') { // local return to the caller of the lambda, i.e. the forEach loop return@forEach } result += it.toString() } - assertEquals("hell_wrld", result) + assertEquals("helloworld", result) } @Test @@ -100,10 +100,10 @@ class StructuralJumpTest { var result = "" "hello_world".forEach(fun(element) { // local return to the caller of the anonymous fun, i.e. the forEach loop - if (element == 'o') return + if (element == '_') return result += element.toString() }) - assertEquals("hell_wrld", result) + assertEquals("helloworld", result) } @Test From 1f1baf97e96b45026d0e0ecc53c67c7bde56ce4f Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Tue, 2 Oct 2018 11:42:11 +0400 Subject: [PATCH 39/59] add one map to another --- .../com/baeldung/map/java_8/MergeMaps.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java index 4bf7b6ba5a..5138d44feb 100644 --- a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -28,6 +28,24 @@ public class MergeMaps { streamOf(); streamEx(); + + streamMerge(); + } + + private static void streamMerge() { + + Map map3 = map2.entrySet() + .stream() + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (v1, v2) -> new Employee(v1.getId(), v2.getName()), + () -> new HashMap<>(map1) + ) + ); + + System.out.println(map3); } private static void streamEx() { @@ -55,9 +73,9 @@ public class MergeMaps { private static void streamConcat() { Map result = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (value1, value2) -> new Employee(value1.getId(), value2.getName()) + Map.Entry::getKey, + Map.Entry::getValue, + (value1, value2) -> new Employee(value1.getId(), value2.getName()) )); result.entrySet().forEach(System.out::println); @@ -68,14 +86,13 @@ public class MergeMaps { map2.forEach( (key, value) -> map3.merge(key, value, (v1, v2) -> - new Employee(v1.getId(),v2.getName())) + new Employee(v1.getId(), v2.getName())) ); map3.entrySet().forEach(System.out::println); } - private static void initialize() { Employee employee1 = new Employee(1L, "Henry"); map1.put(employee1.getName(), employee1); From 5f2b7d5fef2f068eae525145ab52480e4513912c Mon Sep 17 00:00:00 2001 From: eelhazati Date: Tue, 2 Oct 2018 21:35:45 +0100 Subject: [PATCH 40/59] Maven polyglot --- .../.mvn/extensions.xml | 8 ++ .../maven-polyglot-json-app/pom.json | 34 ++++++ .../polyglot/MavenPolyglotApplication.java | 19 +++ .../src/main/resources/model.json | 109 ++++++++++++++++++ .../maven-polyglot-json-extension/pom.xml | 47 ++++++++ .../demo/polyglot/CustomModelProcessor.java | 62 ++++++++++ .../.mvn/extensions.xml | 8 ++ maven-polyglot/maven-polyglot-yml-app/pom.yml | 7 ++ .../maven/polyglot/YamlDemoApplication.java | 7 ++ .../src/main/resources/model.json | 109 ++++++++++++++++++ 10 files changed, 410 insertions(+) create mode 100644 maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml create mode 100644 maven-polyglot/maven-polyglot-json-app/pom.json create mode 100644 maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java create mode 100644 maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json create mode 100644 maven-polyglot/maven-polyglot-json-extension/pom.xml create mode 100644 maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java create mode 100644 maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml create mode 100644 maven-polyglot/maven-polyglot-yml-app/pom.yml create mode 100644 maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java create mode 100644 maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json diff --git a/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml b/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml new file mode 100644 index 0000000000..c06b76e1b2 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + com.baeldung.maven.polyglot + maven-polyglot-json-extension + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-json-app/pom.json b/maven-polyglot/maven-polyglot-json-app/pom.json new file mode 100644 index 0000000000..abd58f3127 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/pom.json @@ -0,0 +1,34 @@ +{ + "modelVersion": "4.0.0", + "groupId": "com.baeldung.maven.polyglot", + "artifactId": "maven-polyglot-json-app", + "version": "1.0-SNAPSHOT", + "name": "Json Maven Polyglot", + "parent": { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-parent", + "version": "2.0.5.RELEASE", + "relativePath": null + }, + "properties": { + "project.build.sourceEncoding": "UTF-8", + "project.reporting.outputEncoding": "UTF-8", + "maven.compiler.source": "1.8", + "maven.compiler.target": "1.8", + "java.version": "1.8" + }, + "dependencies": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-web" + } + ], + "build": { + "plugins": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-maven-plugin" + } + ] + } +} \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java b/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java new file mode 100644 index 0000000000..d03116889f --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.maven.polyglot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.GetMapping; + +@RestController +@SpringBootApplication +public class MavenPolyglotApplication { + public static void main(String[] args) { + SpringApplication.run(MavenPolyglotApplication.class, args); + } + + @GetMapping("/") + public String home(){ + return "Hello JSON Maven Model !"; + } +} diff --git a/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json b/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json new file mode 100644 index 0000000000..f006582c12 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json @@ -0,0 +1,109 @@ +{ + "modules": [], + "distributionManagement": null, + "properties": { + "project.reporting.outputEncoding": "UTF-8", + "java.version": "1.8", + "maven.compiler.source": "1.8", + "project.build.sourceEncoding": "UTF-8", + "maven.compiler.target": "1.8" + }, + "dependencyManagement": null, + "dependencies": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-web", + "version": null, + "type": "jar", + "classifier": null, + "scope": null, + "systemPath": null, + "exclusions": [], + "optional": null, + "managementKey": "org.springframework.boot:spring-boot-starter-web:jar" + } + ], + "repositories": [], + "pluginRepositories": [], + "reports": null, + "reporting": null, + "modelVersion": "4.0.0", + "parent": { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-parent", + "version": "2.0.5.RELEASE", + "relativePath": "", + "id": "org.springframework.boot:spring-boot-starter-parent:pom:2.0.5.RELEASE" + }, + "groupId": "com.demo.polyglot", + "artifactId": "maven-polyglot-app", + "version": "1.0.1", + "packaging": "jar", + "name": "Json Maven Polyglot", + "description": null, + "url": null, + "inceptionYear": null, + "organization": null, + "licenses": [], + "developers": [], + "contributors": [], + "mailingLists": [], + "prerequisites": null, + "scm": null, + "issueManagement": null, + "ciManagement": null, + "build": { + "plugins": [ + { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + ], + "pluginManagement": null, + "defaultGoal": null, + "resources": [], + "testResources": [], + "directory": null, + "finalName": null, + "filters": [], + "sourceDirectory": null, + "scriptSourceDirectory": null, + "testSourceDirectory": null, + "outputDirectory": null, + "testOutputDirectory": null, + "extensions": [], + "pluginsAsMap": { + "org.liquibase:liquibase-maven-plugin": { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + } + }, + "profiles": [], + "modelEncoding": "UTF-8", + "pomFile": null, + "id": "com.demo.polyglot:maven-polyglot-app:jar:1.0.1", + "projectDirectory": null +} diff --git a/maven-polyglot/maven-polyglot-json-extension/pom.xml b/maven-polyglot/maven-polyglot-json-extension/pom.xml new file mode 100644 index 0000000000..d5c5b7ab55 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-extension/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + com.baeldung.maven.polyglot + maven-polyglot-json-extension + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + org.apache.maven + maven-core + 3.5.4 + provided + + + com.fasterxml.jackson.core + jackson-databind + 2.9.6 + + + + + + + org.codehaus.plexus + plexus-component-metadata + 1.7.1 + + + + generate-metadata + + + + + + + + \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java b/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java new file mode 100644 index 0000000000..a1756192e9 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java @@ -0,0 +1,62 @@ +package com.demo.polyglot; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.maven.model.Model; +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelProcessor; +import org.apache.maven.model.io.ModelParseException; +import org.apache.maven.model.io.ModelReader; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.util.ReaderFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.util.Map; + +@Component(role = ModelProcessor.class) +public class CustomModelProcessor implements ModelProcessor { + + private static final String XML_POM = "pom.xml"; + private static final String JSON_POM = "pom.json"; + private static final String JSON_EXT = ".json"; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Requirement + private ModelReader modelReader; + + @Override + public File locatePom(File projectDirectory) { + File pomFile = new File(projectDirectory, JSON_POM); + if (!pomFile.exists()) { + pomFile = new File(projectDirectory, XML_POM); + } + return pomFile; + } + + @Override + public Model read(InputStream input, Map options) throws IOException, ModelParseException { + try (final Reader in = ReaderFactory.newPlatformReader(input)) { + return read(in, options); + } + } + + @Override + public Model read(Reader reader, Map options) throws IOException, ModelParseException { + FileModelSource source = (options != null) ? (FileModelSource) options.get(SOURCE) : null; + if (source != null && source.getLocation().endsWith(JSON_EXT)) { + Model model = objectMapper.readValue(reader, Model.class); + return model; + } + //It's a normal maven project with a pom.xml file + return modelReader.read(reader, options); + } + + @Override + public Model read(File input, Map options) throws IOException, ModelParseException { + return null; + } +} \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml b/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml new file mode 100644 index 0000000000..cfc6275681 --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + io.takari.polyglot + polyglot-yaml + 0.3.1 + + \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/pom.yml b/maven-polyglot/maven-polyglot-yml-app/pom.yml new file mode 100644 index 0000000000..445e2eec3b --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/pom.yml @@ -0,0 +1,7 @@ +modelVersion: 4.0.0 +groupId: com.baeldung.maven.polyglot +artifactId: maven-polyglot-yml-app +version: 1.0-SNAPSHOT +name: 'YAML Demo' + +properties: {maven.compiler.source: 1.8, maven.compiler.target: 1.8} \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java b/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java new file mode 100644 index 0000000000..2142c7f9b8 --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java @@ -0,0 +1,7 @@ +package com.baeldung.maven.polyglot; + +public class YamlDemoApplication { + public static void main(String[] args) { + System.out.println("Hello Maven Polyglot YAML !"); + } +} diff --git a/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json b/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json new file mode 100644 index 0000000000..f006582c12 --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json @@ -0,0 +1,109 @@ +{ + "modules": [], + "distributionManagement": null, + "properties": { + "project.reporting.outputEncoding": "UTF-8", + "java.version": "1.8", + "maven.compiler.source": "1.8", + "project.build.sourceEncoding": "UTF-8", + "maven.compiler.target": "1.8" + }, + "dependencyManagement": null, + "dependencies": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-web", + "version": null, + "type": "jar", + "classifier": null, + "scope": null, + "systemPath": null, + "exclusions": [], + "optional": null, + "managementKey": "org.springframework.boot:spring-boot-starter-web:jar" + } + ], + "repositories": [], + "pluginRepositories": [], + "reports": null, + "reporting": null, + "modelVersion": "4.0.0", + "parent": { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-parent", + "version": "2.0.5.RELEASE", + "relativePath": "", + "id": "org.springframework.boot:spring-boot-starter-parent:pom:2.0.5.RELEASE" + }, + "groupId": "com.demo.polyglot", + "artifactId": "maven-polyglot-app", + "version": "1.0.1", + "packaging": "jar", + "name": "Json Maven Polyglot", + "description": null, + "url": null, + "inceptionYear": null, + "organization": null, + "licenses": [], + "developers": [], + "contributors": [], + "mailingLists": [], + "prerequisites": null, + "scm": null, + "issueManagement": null, + "ciManagement": null, + "build": { + "plugins": [ + { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + ], + "pluginManagement": null, + "defaultGoal": null, + "resources": [], + "testResources": [], + "directory": null, + "finalName": null, + "filters": [], + "sourceDirectory": null, + "scriptSourceDirectory": null, + "testSourceDirectory": null, + "outputDirectory": null, + "testOutputDirectory": null, + "extensions": [], + "pluginsAsMap": { + "org.liquibase:liquibase-maven-plugin": { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + } + }, + "profiles": [], + "modelEncoding": "UTF-8", + "pomFile": null, + "id": "com.demo.polyglot:maven-polyglot-app:jar:1.0.1", + "projectDirectory": null +} From 450709d13b47e05d675ce8239cd5336319ffda42 Mon Sep 17 00:00:00 2001 From: Krzysztof Majewski Date: Wed, 3 Oct 2018 16:59:44 +0000 Subject: [PATCH 41/59] Using Math.sin with Degrees Issue: BAEL-2157 --- .../com/baeldung/maths/MathSinUnitTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java diff --git a/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java new file mode 100644 index 0000000000..111b2f4465 --- /dev/null +++ b/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.maths; + +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; + +public class MathSinUnitTest { + + @Test + public void givenAnAngleInDegrees_whenUsingToRadians_thenResultIsInRadians() { + double angleInDegrees = 30; + double sinForDegrees = Math.sin(Math.toRadians(angleInDegrees)); // 0.5 + + double thirtyDegreesInRadians = 1/6 * Math.PI; + double sinForRadians = Math.sin(thirtyDegreesInRadians); // 0.5 + + assertTrue(sinForDegrees == sinForRadians); + } + +} From 0b792c58f21e55904e53600ab577b2cdefb92b3b Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Wed, 3 Oct 2018 21:29:42 +0300 Subject: [PATCH 42/59] Update and rename StructuralJumpTest.kt to StructuralJumpUnitTest.kt --- .../{StructuralJumpTest.kt => StructuralJumpUnitTest.kt} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename core-kotlin/src/test/kotlin/com/baeldung/kotlin/{StructuralJumpTest.kt => StructuralJumpUnitTest.kt} (98%) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt similarity index 98% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt index b5183d3568..436dc9e2ba 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt @@ -4,7 +4,7 @@ import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -class StructuralJumpTest { +class StructuralJumpUnitTest { @Test fun givenLoop_whenBreak_thenComplete() { @@ -118,4 +118,4 @@ class StructuralJumpTest { } assertEquals("hello", result) } -} \ No newline at end of file +} From 0093ee4c3a388eea91f32ed450a9ce20be38cb15 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Wed, 3 Oct 2018 22:13:41 +0300 Subject: [PATCH 43/59] Create README.md --- maven-polyglot/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 maven-polyglot/README.md diff --git a/maven-polyglot/README.md b/maven-polyglot/README.md new file mode 100644 index 0000000000..589315efd1 --- /dev/null +++ b/maven-polyglot/README.md @@ -0,0 +1,3 @@ +To run the maven-polyglot-json-app successfully, you first have to build the maven-polyglot-json-extension module using: mvn clean install. + +Related Articles: From b4f2f430bf328f89f67c6922cfb6679cc09b717f Mon Sep 17 00:00:00 2001 From: Divyum Rastogi Date: Thu, 4 Oct 2018 00:54:56 +0530 Subject: [PATCH 44/59] remove duplicate and broken Java UUID tutorial link --- core-java/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java/README.md b/core-java/README.md index fbfcb1117c..f415a98098 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -37,7 +37,6 @@ - [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) - [How to Perform a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) - [Call Methods at Runtime Using Java Reflection](http://www.baeldung.com/java-method-reflection) -- [Guide to UUID in JAVA](http://www.baeldung.com/guide-to-uuid-in-java) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) - [Iterating Over Enum Values in Java](http://www.baeldung.com/java-enum-iteration) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) From c79e64844258f0f76701c842a9e106d71f8ca027 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Thu, 4 Oct 2018 12:16:40 +0400 Subject: [PATCH 45/59] changes after review --- .../src/main/java/com/baeldung/map/java_8/MergeMaps.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java index 5138d44feb..052cfb8bad 100644 --- a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -2,12 +2,7 @@ package com.baeldung.map.java_8; import com.baeldung.sort.Employee; import one.util.streamex.EntryStream; -import one.util.streamex.IntCollector; -import one.util.streamex.StreamEx; - -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -75,7 +70,7 @@ public class MergeMaps { Map result = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, - (value1, value2) -> new Employee(value1.getId(), value2.getName()) + (value1, value2) -> new Employee(value2.getId(), value1.getName()) )); result.entrySet().forEach(System.out::println); @@ -103,7 +98,7 @@ public class MergeMaps { Employee employee4 = new Employee(2L, "George"); map2.put(employee4.getName(), employee4); - Employee employee5 = new Employee(1L, "Henry"); + Employee employee5 = new Employee(3L, "Henry"); map2.put(employee5.getName(), employee5); } From 75f1d41340bb409c5a01676d52371ce4b9e8e3be Mon Sep 17 00:00:00 2001 From: Eugen Date: Thu, 4 Oct 2018 18:51:37 +0100 Subject: [PATCH 46/59] Update README.md --- README.md | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d20968b455..ac52f72f5e 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,14 @@ And here's the Master Class of Learn Spring Security:
-Spring Tutorials +Java and Spring Tutorials ================ -This project is **a collection of small and focused tutorials** each covering a single and well defined area of development. -Most of the tutorial projects are focused on the `Spring Framework` (and `Spring Security`). +This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem. +A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Securiyt. In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`. + Building the project ==================== To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false` @@ -28,15 +29,3 @@ Any IDE can be used to work with the projects, but if you're using Eclipse, cons - import the included **formatter** in Eclipse: `https://github.com/eugenp/tutorials/tree/master/eclipse` - - -CI - Jenkins -================================ -This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/tutorials-unit/)** - -### Relevant Articles: -================================ - -- [Apache Maven Standard Directory Layout](http://www.baeldung.com/maven-directory-structure) -- [Apache Maven Tutorial](http://www.baeldung.com/maven) -- [Designing a User Friendly Java Library](http://www.baeldung.com/design-a-user-friendly-java-library) From 950631923c649f8f3c35d2ee55157cc6d36338f9 Mon Sep 17 00:00:00 2001 From: Eugen Date: Thu, 4 Oct 2018 18:52:03 +0100 Subject: [PATCH 47/59] Update README.md --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index ac52f72f5e..06363da79d 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,3 @@ In additional to Spring, the following technologies are in focus: `core Java`, ` Building the project ==================== To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false` - - -Working with the code in Eclipse -================================ -Any IDE can be used to work with the projects, but if you're using Eclipse, consider the following. - -- import the included **formatter** in Eclipse: -`https://github.com/eugenp/tutorials/tree/master/eclipse` From c63187b581108587668dbacc0fa704605e5ca2ac Mon Sep 17 00:00:00 2001 From: Eugen Date: Thu, 4 Oct 2018 19:01:20 +0100 Subject: [PATCH 48/59] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06363da79d..ea6f4c2243 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The "REST with Spring" Classes ============================== -Here's the Master Class of REST With Spring (price changes permanently next Friday):
+Here's the Master Class of REST With Spring (along with the newly announced Boot 2 material):
**[>> THE REST WITH SPRING MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** And here's the Master Class of Learn Spring Security:
From 01a38b89b90f1f792190fe0831861b5da363a589 Mon Sep 17 00:00:00 2001 From: Eugen Date: Thu, 4 Oct 2018 19:01:50 +0100 Subject: [PATCH 49/59] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea6f4c2243..adb17ca7e5 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ The "REST with Spring" Classes ============================== Here's the Master Class of REST With Spring (along with the newly announced Boot 2 material):
-**[>> THE REST WITH SPRING MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** +**[>> THE REST WITH SPRING - MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** And here's the Master Class of Learn Spring Security:
-**[>> LEARN SPRING SECURITY MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** +**[>> LEARN SPRING SECURITY - MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** From bfe1429851f91d8439530d2fdaef2bc9cdc54e44 Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Thu, 4 Oct 2018 19:19:33 +0100 Subject: [PATCH 50/59] moving modules between profiles --- pom.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index ef34881cef..a499aac7ee 100644 --- a/pom.xml +++ b/pom.xml @@ -551,18 +551,6 @@ spring-security-rest spring-security-sso spring-security-x509 - spring-session - spring-sleuth - spring-social-login - spring-spel - spring-state-machine - spring-thymeleaf - spring-userservice - spring-zuul - spring-remoting - spring-reactor - spring-vertx - spring-jinq @@ -601,6 +589,18 @@ parent-java parent-kotlin + spring-session + spring-sleuth + spring-social-login + spring-spel + spring-state-machine + spring-thymeleaf + spring-userservice + spring-zuul + spring-remoting + spring-reactor + spring-vertx + spring-jinq spring-rest-embedded-tomcat testing-modules/testing testing-modules/testng From e65d77a47aba6b1300d177746057ec09c8731b5f Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 4 Oct 2018 22:18:12 +0300 Subject: [PATCH 51/59] upgrade spring-data-mongodb --- spring-data-mongodb/pom.xml | 42 ++++++++- .../java/com/baeldung/config/MongoConfig.java | 24 +++-- .../baeldung/config/SimpleMongoConfig.java | 6 +- .../baeldung/repository/UserRepository.java | 13 +-- .../src/main/resources/mongoConfig.xml | 16 ++-- .../aggregation/ZipsAggregationLiveTest.java | 62 +++++++------ .../com/baeldung/gridfs/GridFSLiveTest.java | 91 ++++++++++--------- .../repository/UserRepositoryLiveTest.java | 12 +-- 8 files changed, 158 insertions(+), 108 deletions(-) diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 332245adc8..bf72e70b25 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -8,9 +8,9 @@ com.baeldung - parent-spring-4 + parent-spring-5 0.0.1-SNAPSHOT - ../parent-spring-4 + ../parent-spring-5 @@ -19,6 +19,28 @@ spring-data-mongodb ${org.springframework.data.version} + + + org.springframework.data + spring-data-releasetrain + Lovelace-M3 + pom + import + + + + org.mongodb + mongodb-driver-reactivestreams + 1.9.2 + + + + io.projectreactor + reactor-test + 3.2.0.RELEASE + test + + org.springframework spring-core @@ -48,6 +70,17 @@ + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + @@ -70,10 +103,11 @@ - 1.10.4.RELEASE - 2.9.0 + 2.1.0.RELEASE 4.1.4 1.1.3 + 5.1.0.RELEASE + diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java index 551a9142a6..8221d299ed 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java @@ -1,20 +1,22 @@ package com.baeldung.config; -import com.mongodb.Mongo; -import com.mongodb.MongoClient; -import com.baeldung.converter.UserWriterConverter; -import com.baeldung.event.CascadeSaveMongoEventListener; -import com.baeldung.event.UserCascadeSaveMongoEventListener; +import java.util.ArrayList; +import java.util.List; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.MongoTransactionManager; import org.springframework.data.mongodb.config.AbstractMongoConfiguration; import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; -import java.util.ArrayList; -import java.util.List; +import com.baeldung.converter.UserWriterConverter; +import com.baeldung.event.CascadeSaveMongoEventListener; +import com.baeldung.event.UserCascadeSaveMongoEventListener; +import com.mongodb.MongoClient; @Configuration @EnableMongoRepositories(basePackages = "com.baeldung.repository") @@ -28,7 +30,7 @@ public class MongoConfig extends AbstractMongoConfiguration { } @Override - public Mongo mongo() throws Exception { + public MongoClient mongoClient() { return new MongoClient("127.0.0.1", 27017); } @@ -57,4 +59,10 @@ public class MongoConfig extends AbstractMongoConfiguration { public GridFsTemplate gridFsTemplate() throws Exception { return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter()); } + + @Bean + MongoTransactionManager transactionManager(MongoDbFactory dbFactory) { + return new MongoTransactionManager(dbFactory); + } + } diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java index 95f192811f..c3ddad5a82 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java @@ -1,18 +1,18 @@ package com.baeldung.config; -import com.mongodb.Mongo; -import com.mongodb.MongoClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import com.mongodb.MongoClient; + @Configuration @EnableMongoRepositories(basePackages = "com.baeldung.repository") public class SimpleMongoConfig { @Bean - public Mongo mongo() throws Exception { + public MongoClient mongo() throws Exception { return new MongoClient("localhost"); } diff --git a/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java b/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java index e9dc0f5c95..4c69d7f9c6 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java @@ -1,13 +1,14 @@ package com.baeldung.repository; -import com.baeldung.model.User; -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.data.mongodb.repository.Query; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; - import java.util.List; -public interface UserRepository extends MongoRepository, QueryDslPredicateExecutor { +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; + +import com.baeldung.model.User; + +public interface UserRepository extends MongoRepository, QuerydslPredicateExecutor { @Query("{ 'name' : ?0 }") List findUsersByName(String name); diff --git a/spring-data-mongodb/src/main/resources/mongoConfig.xml b/spring-data-mongodb/src/main/resources/mongoConfig.xml index 2b32863fb6..324f7f60c2 100644 --- a/spring-data-mongodb/src/main/resources/mongoConfig.xml +++ b/spring-data-mongodb/src/main/resources/mongoConfig.xml @@ -3,17 +3,17 @@ xmlns:p="http://www.springframework.org/schema/p" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.2.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/mongo - http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd + http://www.springframework.org/schema/data/mongo/spring-mongo.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-3.2.xsd" + http://www.springframework.org/schema/context/spring-context.xsd" > - + - + @@ -27,12 +27,12 @@ - + - + - + diff --git a/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java index a4bea45fcf..bb54a5487f 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java @@ -1,12 +1,24 @@ package com.baeldung.aggregation; -import com.mongodb.DB; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; -import com.mongodb.MongoClient; -import com.mongodb.util.JSON; -import com.baeldung.aggregation.model.StatePopulation; -import com.baeldung.config.MongoConfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.group; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.limit; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.match; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.project; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.sort; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.bson.Document; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -26,23 +38,13 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.group; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.limit; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.match; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.project; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.sort; +import com.baeldung.aggregation.model.StatePopulation; +import com.baeldung.config.MongoConfig; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; +import com.mongodb.util.JSON; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -140,13 +142,13 @@ public class ZipsAggregationLiveTest { Aggregation aggregation = newAggregation(sumZips, sortByCount, groupFirstAndLast); - AggregationResults result = mongoTemplate.aggregate(aggregation, "zips", DBObject.class); - DBObject dbObject = result.getUniqueMappedResult(); + AggregationResults result = mongoTemplate.aggregate(aggregation, "zips", Document.class); + Document document = result.getUniqueMappedResult(); - assertEquals("DC", dbObject.get("minZipState")); - assertEquals(24, dbObject.get("minZipCount")); - assertEquals("TX", dbObject.get("maxZipState")); - assertEquals(1671, dbObject.get("maxZipCount")); + assertEquals("DC", document.get("minZipState")); + assertEquals(24, document.get("minZipCount")); + assertEquals("TX", document.get("maxZipState")); + assertEquals(1671, document.get("maxZipCount")); } } diff --git a/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java index 02485e8517..7befaf8fbd 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java @@ -1,8 +1,19 @@ package com.baeldung.gridfs; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.mongodb.gridfs.GridFSDBFile; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.bson.types.ObjectId; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -16,18 +27,9 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.client.gridfs.model.GridFSFile; @ContextConfiguration("file:src/main/resources/mongoConfig.xml") @RunWith(SpringJUnit4ClassRunner.class) @@ -40,8 +42,9 @@ public class GridFSLiveTest { @After public void tearDown() { - List fileList = gridFsTemplate.find(null); - for (GridFSDBFile file : fileList) { + List fileList = new ArrayList(); + gridFsTemplate.find(new Query()).into(fileList); + for (GridFSFile file : fileList) { gridFsTemplate.delete(new Query(Criteria.where("filename").is(file.getFilename()))); } } @@ -54,7 +57,7 @@ public class GridFSLiveTest { String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { @@ -75,10 +78,10 @@ public class GridFSLiveTest { DBObject metaData = new BasicDBObject(); metaData.put("user", "alex"); InputStream inputStream = null; - String id = ""; + ObjectId id = null; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { @@ -91,22 +94,22 @@ public class GridFSLiveTest { } } - GridFSDBFile gridFSDBFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id))); + GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id))); - assertNotNull(gridFSDBFile); - assertNotNull(gridFSDBFile.getInputStream()); - assertThat(gridFSDBFile.numChunks(), is(1)); - assertThat(gridFSDBFile.containsField("filename"), is(true)); - assertThat(gridFSDBFile.get("filename"), is("test.png")); - assertThat(gridFSDBFile.getId(), is(id)); - assertThat(gridFSDBFile.keySet().size(), is(9)); - assertNotNull(gridFSDBFile.getMD5()); - assertNotNull(gridFSDBFile.getUploadDate()); - assertNull(gridFSDBFile.getAliases()); - assertNotNull(gridFSDBFile.getChunkSize()); - assertThat(gridFSDBFile.getContentType(), is("image/png")); - assertThat(gridFSDBFile.getFilename(), is("test.png")); - assertThat(gridFSDBFile.getMetaData().get("user"), is("alex")); + assertNotNull(gridFSFile); +// assertNotNull(gridFSFile.getInputStream()); +// assertThat(gridFSFile.numChunks(), is(1)); +// assertThat(gridFSFile.containsField("filename"), is(true)); + assertThat(gridFSFile.getFilename(), is("test.png")); + assertThat(gridFSFile.getObjectId(), is(id)); +// assertThat(gridFSFile.keySet().size(), is(9)); +// assertNotNull(gridFSFile.getMD5()); + assertNotNull(gridFSFile.getUploadDate()); +// assertNull(gridFSFile.getAliases()); + assertNotNull(gridFSFile.getChunkSize()); + assertThat(gridFSFile.getMetadata().get("_contentType"), is("image/png")); + assertThat(gridFSFile.getFilename(), is("test.png")); + assertThat(gridFSFile.getMetadata().get("user"), is("alex")); } @Test @@ -133,10 +136,11 @@ public class GridFSLiveTest { } } - List gridFSDBFiles = gridFsTemplate.find(null); + List gridFSFiles = new ArrayList(); + gridFsTemplate.find(new Query()).into(gridFSFiles); - assertNotNull(gridFSDBFiles); - assertThat(gridFSDBFiles.size(), is(2)); + assertNotNull(gridFSFiles); + assertThat(gridFSFiles.size(), is(2)); } @Test @@ -163,10 +167,11 @@ public class GridFSLiveTest { } } - List gridFSDBFiles = gridFsTemplate.find(new Query(Criteria.where("metadata.user").is("alex"))); + List gridFSFiles = new ArrayList(); + gridFsTemplate.find(new Query(Criteria.where("metadata.user").is("alex"))).into(gridFSFiles); - assertNotNull(gridFSDBFiles); - assertThat(gridFSDBFiles.size(), is(1)); + assertNotNull(gridFSFiles); + assertThat(gridFSFiles.size(), is(1)); } @Test @@ -177,7 +182,7 @@ public class GridFSLiveTest { String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { @@ -203,7 +208,7 @@ public class GridFSLiveTest { String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { diff --git a/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java index da4e91baec..3daa58dd19 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java @@ -5,8 +5,6 @@ import static org.junit.Assert.assertThat; import java.util.List; -import com.baeldung.config.MongoConfig; -import com.baeldung.model.User; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -22,6 +20,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import com.baeldung.config.MongoConfig; +import com.baeldung.model.User; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) public class UserRepositoryLiveTest { @@ -72,8 +73,7 @@ public class UserRepositoryLiveTest { user.setName("Jim"); userRepository.save(user); - - assertThat(mongoOps.findAll(User.class).size(), is(2)); + assertThat(mongoOps.findAll(User.class).size(), is(1)); } @Test @@ -94,7 +94,7 @@ public class UserRepositoryLiveTest { mongoOps.insert(user); user = mongoOps.findOne(Query.query(Criteria.where("name").is("Chris")), User.class); - final User foundUser = userRepository.findOne(user.getId()); + final User foundUser = userRepository.findById(user.getId()).get(); assertThat(user.getName(), is(foundUser.getName())); } @@ -106,7 +106,7 @@ public class UserRepositoryLiveTest { mongoOps.insert(user); user = mongoOps.findOne(Query.query(Criteria.where("name").is("Harris")), User.class); - final boolean isExists = userRepository.exists(user.getId()); + final boolean isExists = userRepository.existsById(user.getId()); assertThat(isExists, is(true)); } From 9c544345b31e3e39a1457e59e36ef994fe96532c Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 4 Oct 2018 22:18:40 +0300 Subject: [PATCH 52/59] add mongodb transactions --- .../baeldung/config/MongoReactiveConfig.java | 23 +++++ .../reactive/repository/UserRepository.java | 9 ++ ...ngoTransactionReactiveIntegrationTest.java | 47 ++++++++++ ...ngoTransactionTemplateIntegrationTest.java | 68 ++++++++++++++ .../MongoTransactionalIntegrationTest.java | 90 +++++++++++++++++++ 5 files changed, 237 insertions(+) create mode 100644 spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java create mode 100644 spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java create mode 100644 spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java create mode 100644 spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java create mode 100644 spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java new file mode 100644 index 0000000000..b4042b5550 --- /dev/null +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration; +import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; + +import com.mongodb.reactivestreams.client.MongoClient; +import com.mongodb.reactivestreams.client.MongoClients; + +@Configuration +@EnableReactiveMongoRepositories(basePackages = "com.baeldung.reactive.repository") +public class MongoReactiveConfig extends AbstractReactiveMongoConfiguration { + + @Override + public MongoClient reactiveMongoClient() { + return MongoClients.create(); + } + + @Override + protected String getDatabaseName() { + return "reactive"; + } +} diff --git a/spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java b/spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java new file mode 100644 index 0000000000..7e754aa680 --- /dev/null +++ b/spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.reactive.repository; + +import org.springframework.data.mongodb.repository.ReactiveMongoRepository; + +import com.baeldung.model.User; + + +public interface UserRepository extends ReactiveMongoRepository { +} diff --git a/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java new file mode 100644 index 0000000000..43aa865e91 --- /dev/null +++ b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java @@ -0,0 +1,47 @@ +package com.baeldung.transaction; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.config.MongoReactiveConfig; +import com.baeldung.model.User; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MongoReactiveConfig.class) +public class MongoTransactionReactiveIntegrationTest { + + @Autowired + private ReactiveMongoOperations reactiveOps; + + @Before + public void testSetup() { + if (!reactiveOps.collectionExists(User.class) + .block()) { + reactiveOps.createCollection(User.class); + } + } + + @After + public void tearDown() { + System.out.println(reactiveOps.findAll(User.class) + .count() + .block()); + reactiveOps.dropCollection(User.class); + } + + @Test + public void whenPerformTransaction_thenSuccess() { + User user1 = new User("Jane", 23); + User user2 = new User("John", 34); + reactiveOps.inTransaction() + .execute(action -> action.insert(user1) + .then(action.insert(user2))); + } + +} diff --git a/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java new file mode 100644 index 0000000000..1dbe724d87 --- /dev/null +++ b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java @@ -0,0 +1,68 @@ +package com.baeldung.transaction; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.MongoTransactionManager; +import org.springframework.data.mongodb.SessionSynchronization; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +import com.baeldung.config.MongoConfig; +import com.baeldung.model.User; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MongoConfig.class) +public class MongoTransactionTemplateIntegrationTest { + + @Autowired + private MongoTemplate mongoTemplate; + + @Autowired + private MongoTransactionManager mongoTransactionManager; + + @Before + public void testSetup() { + if (!mongoTemplate.collectionExists(User.class)) { + mongoTemplate.createCollection(User.class); + } + } + + @After + public void tearDown() { + mongoTemplate.dropCollection(User.class); + } + + @Test + public void givenTransactionTemplate_whenPerformTransaction_thenSuccess() { + mongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); + TransactionTemplate transactionTemplate = new TransactionTemplate(mongoTransactionManager); + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + mongoTemplate.insert(new User("Kim", 20)); + mongoTemplate.insert(new User("Jack", 45)); + }; + }); + + Query query = new Query().addCriteria(Criteria.where("name") + .is("Jack")); + List users = mongoTemplate.find(query, User.class); + + assertThat(users.size(), is(1)); + } + +} diff --git a/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java new file mode 100644 index 0000000000..4d747789a0 --- /dev/null +++ b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java @@ -0,0 +1,90 @@ +package com.baeldung.transaction; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.MongoTransactionException; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.config.MongoConfig; +import com.baeldung.model.User; +import com.baeldung.repository.UserRepository; +import com.mongodb.MongoCommandException; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MongoConfig.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class MongoTransactionalIntegrationTest { + + @Autowired + private MongoTemplate mongoTemplate; + + @Autowired + private UserRepository userRepository; + + @Test + @Transactional + public void whenPerformMongoTransaction_thenSuccess() { + userRepository.save(new User("John", 30)); + userRepository.save(new User("Ringo", 35)); + Query query = new Query().addCriteria(Criteria.where("name") + .is("John")); + List users = mongoTemplate.find(query, User.class); + + assertThat(users.size(), is(1)); + } + + @Test(expected = MongoTransactionException.class) + @Transactional + public void whenListCollectionDuringMongoTransaction_thenException() { + if (mongoTemplate.collectionExists(User.class)) { + mongoTemplate.save(new User("John", 30)); + mongoTemplate.save(new User("Ringo", 35)); + } + } + + @Test(expected = MongoCommandException.class) + @Transactional + public void whenCountDuringMongoTransaction_thenException() { + userRepository.save(new User("John", 30)); + userRepository.save(new User("Ringo", 35)); + userRepository.count(); + } + + @Test + @Transactional + public void whenQueryDuringMongoTransaction_thenSuccess() { + userRepository.save(new User("Jane", 20)); + userRepository.save(new User("Nick", 33)); + List users = mongoTemplate.find(new Query(), User.class); + + assertTrue(users.size() > 1); + } + + // ==== Using test instead of before and after due to @transactional doesn't allow list collection + + @Test + public void setup() { + if (!mongoTemplate.collectionExists(User.class)) { + mongoTemplate.createCollection(User.class); + } + } + + @Test + public void ztearDown() { + mongoTemplate.dropCollection(User.class); + } +} From e92e71df1cda11cbae602b8dbf215720eefd92eb Mon Sep 17 00:00:00 2001 From: j-bennett Date: Fri, 5 Oct 2018 10:00:45 -0400 Subject: [PATCH 53/59] BAEL-1876: Hibernate 5 Naming Strategy Configuration (#5158) --- .../CustomPhysicalNamingStrategy.java | 47 ++++++++++++ .../hibernate/namingstrategy/Customer.java | 56 ++++++++++++++ .../NamingStrategyLiveTest.java | 75 +++++++++++++++++++ .../hibernate-namingstrategy.properties | 10 +++ 4 files changed, 188 insertions(+) create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java create mode 100644 hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java create mode 100644 hibernate5/src/test/resources/hibernate-namingstrategy.properties diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java new file mode 100644 index 0000000000..74bcb9e411 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.namingstrategy; + +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.model.naming.PhysicalNamingStrategy; +import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; + +public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy { + + @Override + public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + private Identifier convertToSnakeCase(final Identifier identifier) { + if (identifier == null) { + return identifier; + } + + final String regex = "([a-z])([A-Z])"; + final String replacement = "$1_$2"; + final String newName = identifier.getText() + .replaceAll(regex, replacement) + .toLowerCase(); + return Identifier.toIdentifier(newName); + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java new file mode 100644 index 0000000000..b3fb3b32b6 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java @@ -0,0 +1,56 @@ +package com.baeldung.hibernate.namingstrategy; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "Customers") +public class Customer { + + @Id + @GeneratedValue + private Long id; + + private String firstName; + + private String lastName; + + @Column(name = "email") + private String emailAddress; + + 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; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java new file mode 100644 index 0000000000..0d6aed3370 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java @@ -0,0 +1,75 @@ +package com.baeldung.hibernate.namingstrategy; + +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Properties; + +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistry; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class NamingStrategyLiveTest { + + private Session session; + + @Before + public void init() { + try { + Configuration configuration = new Configuration(); + + Properties properties = new Properties(); + properties.load(Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream("hibernate-namingstrategy.properties")); + + configuration.setProperties(properties); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) + .build(); + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addAnnotatedClass(Customer.class); + + SessionFactory factory = metadataSources.buildMetadata() + .buildSessionFactory(); + + session = factory.openSession(); + } catch (HibernateException | IOException e) { + fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]"); + } + } + + @After + public void close() { + if (session != null) + session.close(); + } + + @Test + public void testCustomPhysicalNamingStrategy() { + + Customer customer = new Customer(); + customer.setFirstName("first name"); + customer.setLastName("last name"); + customer.setEmailAddress("customer@example.com"); + + session.beginTransaction(); + + Long id = (Long) session.save(customer); + + session.flush(); + session.clear(); + + Object[] result = (Object[]) session.createNativeQuery("select c.first_name, c.last_name, c.email from customers c where c.id = :id") + .setParameter("id", id) + .getSingleResult(); + + } +} diff --git a/hibernate5/src/test/resources/hibernate-namingstrategy.properties b/hibernate5/src/test/resources/hibernate-namingstrategy.properties new file mode 100644 index 0000000000..f75a35bdfe --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-namingstrategy.properties @@ -0,0 +1,10 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.dialect=org.hibernate.dialect.H2Dialect + +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop + +hibernate.physical_naming_strategy=com.baeldung.hibernate.namingstrategy.CustomPhysicalNamingStrategy +hibernate.implicit_naming_strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl \ No newline at end of file From 166534ce5031a0c868f6ca9f71879a04ffdac427 Mon Sep 17 00:00:00 2001 From: Eugen Date: Fri, 5 Oct 2018 22:11:46 +0200 Subject: [PATCH 54/59] Update README.md --- core-java/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java/README.md b/core-java/README.md index fbfcb1117c..231d35aafc 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -25,7 +25,6 @@ - [The Traveling Salesman Problem in Java](http://www.baeldung.com/java-simulated-annealing-for-traveling-salesman) - [How to Create an Executable JAR with Maven](http://www.baeldung.com/executable-jar-with-maven) - [How to Design a Genetic Algorithm in Java](http://www.baeldung.com/java-genetic-algorithm) -- [Spring Security – Cache Control Headers](http://www.baeldung.com/spring-security-cache-control-headers) - [Basic Introduction to JMX](http://www.baeldung.com/java-management-extensions) - [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda) - [Introduction to Nashorn](http://www.baeldung.com/java-nashorn) From 86c9b89ed9acab22cf15add9fe127650262d563d Mon Sep 17 00:00:00 2001 From: DOHA Date: Sat, 6 Oct 2018 02:00:25 +0300 Subject: [PATCH 55/59] clean and upgrade --- spring-data-mongodb/pom.xml | 13 +++++++------ .../java/com/baeldung/config/MongoConfig.java | 6 +++--- .../aggregation/ZipsAggregationLiveTest.java | 17 +++++++---------- .../com/baeldung/gridfs/GridFSLiveTest.java | 3 +-- .../mongotemplate/DocumentQueryLiveTest.java | 19 ++++++++++--------- .../MongoTemplateQueryLiveTest.java | 19 ++++++++++--------- .../repository/UserRepositoryLiveTest.java | 2 +- 7 files changed, 39 insertions(+), 40 deletions(-) diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index bf72e70b25..ad70d987bb 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -31,16 +31,16 @@ org.mongodb mongodb-driver-reactivestreams - 1.9.2 + ${mongodb-reactivestreams.version} - + io.projectreactor reactor-test - 3.2.0.RELEASE + ${projectreactor.version} test - + org.springframework spring-core @@ -106,8 +106,9 @@ 2.1.0.RELEASE 4.1.4 1.1.3 - 5.1.0.RELEASE - + 5.1.0.RELEASE + 1.9.2 + 3.2.0.RELEASE diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java index 8221d299ed..f1048fa145 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java @@ -9,7 +9,7 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoTransactionManager; import org.springframework.data.mongodb.config.AbstractMongoConfiguration; -import org.springframework.data.mongodb.core.convert.CustomConversions; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @@ -50,9 +50,9 @@ public class MongoConfig extends AbstractMongoConfiguration { } @Override - public CustomConversions customConversions() { + public MongoCustomConversions customConversions() { converters.add(new UserWriterConverter()); - return new CustomConversions(converters); + return new MongoCustomConversions(converters); } @Bean diff --git a/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java index bb54a5487f..1da50d7cb4 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java @@ -40,11 +40,9 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.baeldung.aggregation.model.StatePopulation; import com.baeldung.config.MongoConfig; -import com.mongodb.DB; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; import com.mongodb.MongoClient; -import com.mongodb.util.JSON; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -58,23 +56,22 @@ public class ZipsAggregationLiveTest { @BeforeClass public static void setupTests() throws Exception { client = new MongoClient(); - DB testDB = client.getDB("test"); - DBCollection zipsCollection = testDB.getCollection("zips"); + MongoDatabase testDB = client.getDatabase("test"); + MongoCollection zipsCollection = testDB.getCollection("zips"); zipsCollection.drop(); InputStream zipsJsonStream = ZipsAggregationLiveTest.class.getResourceAsStream("/zips.json"); BufferedReader reader = new BufferedReader(new InputStreamReader(zipsJsonStream)); reader.lines() - .forEach(line -> zipsCollection.insert((DBObject) JSON.parse(line))); + .forEach(line -> zipsCollection.insertOne(Document.parse(line))); reader.close(); - } @AfterClass public static void tearDown() throws Exception { client = new MongoClient(); - DB testDB = client.getDB("test"); - DBCollection zipsCollection = testDB.getCollection("zips"); + MongoDatabase testDB = client.getDatabase("test"); + MongoCollection zipsCollection = testDB.getCollection("zips"); zipsCollection.drop(); client.close(); } diff --git a/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java index 7befaf8fbd..3a88a1e654 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java @@ -205,10 +205,9 @@ public class GridFSLiveTest { DBObject metaData = new BasicDBObject(); metaData.put("user", "alex"); InputStream inputStream = null; - String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); + gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { diff --git a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java index 7a61f9f98a..d05bde0f1b 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java @@ -1,8 +1,11 @@ package com.baeldung.mongotemplate; -import com.baeldung.config.MongoConfig; -import com.baeldung.model.EmailAddress; -import com.baeldung.model.User; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Iterator; +import java.util.List; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,11 +20,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Iterator; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import com.baeldung.config.MongoConfig; +import com.baeldung.model.EmailAddress; +import com.baeldung.model.User; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -152,7 +153,7 @@ public class DocumentQueryLiveTest { user.setAge(35); mongoTemplate.insert(user); - final Pageable pageableRequest = new PageRequest(0, 2); + final Pageable pageableRequest = PageRequest.of(0, 2); Query query = new Query(); query.with(pageableRequest); diff --git a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java index ee1d4f4760..fc78921b75 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java @@ -1,8 +1,11 @@ package com.baeldung.mongotemplate; -import com.baeldung.config.MongoConfig; -import com.baeldung.model.EmailAddress; -import com.baeldung.model.User; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.util.List; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -20,11 +23,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; +import com.baeldung.config.MongoConfig; +import com.baeldung.model.EmailAddress; +import com.baeldung.model.User; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -104,7 +105,7 @@ public class MongoTemplateQueryLiveTest { user.setAge(35); mongoTemplate.insert(user); - final Pageable pageableRequest = new PageRequest(0, 2); + final Pageable pageableRequest = PageRequest.of(0, 2); Query query = new Query(); query.with(pageableRequest); diff --git a/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java index 3daa58dd19..901610e42d 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java @@ -138,7 +138,7 @@ public class UserRepositoryLiveTest { user.setName("Adam"); mongoOps.insert(user); - final Pageable pageableRequest = new PageRequest(0, 1); + final Pageable pageableRequest = PageRequest.of(0, 1); final Page page = userRepository.findAll(pageableRequest); List users = page.getContent(); From cb6e84c59e505f20988e2fee91fde1442fc6077e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norberto=20Ritzmann=20J=C3=BAnior?= Date: Sat, 6 Oct 2018 00:09:13 -0300 Subject: [PATCH 56/59] New Article - ETL with Spring Cloud Data Flow (#5388) * Including the ETL files to the repository * Rename READMET.md to README.MD Renamed to correct README. * Update README.MD Additional line brakes * Formatting * Removing unecessary autogenerated files --- spring-cloud-data-flow/etl/README.MD | 9 +++ .../etl/customer-mongodb-sink/pom.xml | 75 +++++++++++++++++++ .../customermongodbsink/Customer.java | 27 +++++++ .../customermongodbsink/CustomerListener.java | 18 +++++ .../CustomerMongodbSinkApplication.java | 12 +++ .../CustomerRepository.java | 9 +++ .../src/main/resources/application.properties | 0 .../etl/customer-transform/pom.xml | 68 +++++++++++++++++ .../customer/customertransform/Customer.java | 29 +++++++ .../CustomerProcessorConfiguration.java | 16 ++++ .../CustomerTransformApplication.java | 12 +++ .../src/main/resources/application.properties | 0 spring-cloud-data-flow/etl/pom.xml | 20 +++++ spring-cloud-data-flow/pom.xml | 1 + 14 files changed, 296 insertions(+) create mode 100644 spring-cloud-data-flow/etl/README.MD create mode 100644 spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml create mode 100644 spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java create mode 100644 spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java create mode 100644 spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java create mode 100644 spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java create mode 100644 spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties create mode 100644 spring-cloud-data-flow/etl/customer-transform/pom.xml create mode 100644 spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java create mode 100644 spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java create mode 100644 spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java create mode 100644 spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties create mode 100644 spring-cloud-data-flow/etl/pom.xml diff --git a/spring-cloud-data-flow/etl/README.MD b/spring-cloud-data-flow/etl/README.MD new file mode 100644 index 0000000000..0cbb460b01 --- /dev/null +++ b/spring-cloud-data-flow/etl/README.MD @@ -0,0 +1,9 @@ +# Overview +This is an example of a ETL stream pipeline, mixing a starter application with custom transform and sink. + +# Applications +JDBC Source - Application Starter distributed by default + +customer-transform - Custom application to transform the data + +customer-mongodb-sink - Custom application to sink the data diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml b/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml new file mode 100644 index 0000000000..468d8e17d0 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + com.customer + customer-mongodb-sink + jar + + customer-mongodb-sink + Example ETL Load Project + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../../parent-boot-2 + + + + UTF-8 + UTF-8 + 1.8 + Finchley.SR1 + + + + + org.springframework.cloud + spring-cloud-stream + + + org.springframework.cloud + spring-cloud-stream-binder-rabbit + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java new file mode 100644 index 0000000000..cf44aec5b7 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java @@ -0,0 +1,27 @@ +package com.customer.customermongodbsink; + +import org.springframework.data.mongodb.core.mapping.Document; + +@Document(collection = "customer") +public class Customer { + + private Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java new file mode 100644 index 0000000000..c841daea8a --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java @@ -0,0 +1,18 @@ +package com.customer.customermongodbsink; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Sink; + +@EnableBinding(Sink.class) +public class CustomerListener { + + @Autowired + private CustomerRepository repository; + + @StreamListener(Sink.INPUT) + public void save(Customer customer) { + repository.save(customer); + } +} diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java new file mode 100644 index 0000000000..2ef311457e --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java @@ -0,0 +1,12 @@ +package com.customer.customermongodbsink; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomerMongodbSinkApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomerMongodbSinkApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java new file mode 100644 index 0000000000..f921ff51cf --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java @@ -0,0 +1,9 @@ +package com.customer.customermongodbsink; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CustomerRepository extends MongoRepository { + +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud-data-flow/etl/customer-transform/pom.xml b/spring-cloud-data-flow/etl/customer-transform/pom.xml new file mode 100644 index 0000000000..bc4b648907 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + com.customer + customer-transform + 0.0.1-SNAPSHOT + jar + + customer-transform + Example transform ETL step + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../../parent-boot-2 + + + + UTF-8 + UTF-8 + 1.8 + Finchley.SR1 + + + + + org.springframework.cloud + spring-cloud-stream-binder-rabbit + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java new file mode 100644 index 0000000000..f0e4d79388 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java @@ -0,0 +1,29 @@ +package com.customer.customertransform; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Customer { + + private Long id; + + private String name; + + @JsonProperty("customer_name") + public void setName(String name) { + this.name = name; + } + + @JsonProperty("name") + public String getName() { + return name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java new file mode 100644 index 0000000000..c99fcf55be --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java @@ -0,0 +1,16 @@ +package com.customer.customertransform; + + +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.integration.annotation.Transformer; + +@EnableBinding(Processor.class) +public class CustomerProcessorConfiguration { + + @Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) + public Customer convertToPojo(Customer payload) { + + return payload; + } +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java new file mode 100644 index 0000000000..8781f4da54 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java @@ -0,0 +1,12 @@ +package com.customer.customertransform; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomerTransformApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomerTransformApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties b/spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud-data-flow/etl/pom.xml b/spring-cloud-data-flow/etl/pom.xml new file mode 100644 index 0000000000..2b904f6e0d --- /dev/null +++ b/spring-cloud-data-flow/etl/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + org.baeldung.spring.cloud + etl-spring-cloud-data-flow + 0.0.1-SNAPSHOT + pom + + + org.baeldung.spring.cloud + spring-cloud-data-flow + 0.0.1-SNAPSHOT + + + + customer-mongodb-sink + customer-transform + + + diff --git a/spring-cloud-data-flow/pom.xml b/spring-cloud-data-flow/pom.xml index 5f24aa2cbd..5a007f3c7d 100644 --- a/spring-cloud-data-flow/pom.xml +++ b/spring-cloud-data-flow/pom.xml @@ -19,6 +19,7 @@ time-processor log-sink batch-job + etl From bed849289c51a2f364af4b7e67303535d5b4b451 Mon Sep 17 00:00:00 2001 From: puneetd30 Date: Sat, 6 Oct 2018 15:13:10 +0800 Subject: [PATCH 57/59] BAEL-2179 Java Map check if key exists (#5394) Add Unit test --- .../com/baeldung/java/map/KeyCheckTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckTest.java diff --git a/core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckTest.java b/core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckTest.java new file mode 100644 index 0000000000..024b2973d2 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckTest.java @@ -0,0 +1,44 @@ +package com.baeldung.java.map; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections4.MultiMap; +import org.apache.commons.collections4.MultiMapUtils; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.map.MultiValueMap; +import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; +import org.apache.commons.collections4.multimap.HashSetValuedHashMap; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; + + +public class KeyCheckTest { + + @Test + public void whenKeyIsPresent_thenContainsKeyReturnsTrue() { + Map map = Collections.singletonMap("key", "value"); + + assertTrue(map.containsKey("key")); + assertFalse(map.containsKey("missing")); + } + + @Test + public void whenKeyHasNullValue_thenGetStillWorks() { + Map map = Collections.singletonMap("nothing", null); + + assertTrue(map.containsKey("nothing")); + assertNull(map.get("nothing")); + } +} \ No newline at end of file From f046857975a53ba5169852ad6112d5711dfb192e Mon Sep 17 00:00:00 2001 From: Felipe Santiago Corro Date: Mon, 8 Oct 2018 03:36:38 -0300 Subject: [PATCH 58/59] BAEL-2237 Using Jackson to parse XML and return JSON (#5401) --- jackson/pom.xml | 2 +- .../com/baeldung/jackson/xmlToJson/Color.java | 5 ++ .../baeldung/jackson/xmlToJson/Flower.java | 42 ++++++++++++++ .../jackson/xmlToJson/XmlToJsonUnitTest.java | 56 +++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java create mode 100644 jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java create mode 100644 jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java diff --git a/jackson/pom.xml b/jackson/pom.xml index 9592e11961..e941ababc5 100644 --- a/jackson/pom.xml +++ b/jackson/pom.xml @@ -118,7 +118,7 @@ - 2.9.6 + 2.9.7 3.8 2.10 diff --git a/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java new file mode 100644 index 0000000000..19dabb30b0 --- /dev/null +++ b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java @@ -0,0 +1,5 @@ +package com.baeldung.jackson.xmlToJson; + +public enum Color { + PINK, BLUE, YELLOW, RED; +} diff --git a/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java new file mode 100644 index 0000000000..0b1ee1b16a --- /dev/null +++ b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java @@ -0,0 +1,42 @@ +package com.baeldung.jackson.xmlToJson; + +public class Flower { + + private String name; + + private Color color; + + private Integer petals; + + public Flower() { } + + public Flower(String name, Color color, Integer petals) { + this.name = name; + this.color = color; + this.petals = petals; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public Integer getPetals() { + return petals; + } + + public void setPetals(Integer petals) { + this.petals = petals; + } +} diff --git a/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java new file mode 100644 index 0000000000..295bb9d6e8 --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.jackson.xmlToJson; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.junit.Test; + +import static org.junit.Assert.*; + +import java.io.IOException; + +public class XmlToJsonUnitTest { + + @Test + public void givenAnXML_whenUseDataBidingToConvertToJSON_thenReturnDataOK() { + String flowerXML = "PoppyRED9"; + + try { + XmlMapper xmlMapper = new XmlMapper(); + Flower poppy = xmlMapper.readValue(flowerXML, Flower.class); + + assertEquals(poppy.getName(), "Poppy"); + assertEquals(poppy.getColor(), Color.RED); + assertEquals(poppy.getPetals(), new Integer(9)); + + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(poppy); + + assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":9}"); + System.out.println(json); + } catch(IOException e) { + e.printStackTrace(); + } + } + + @Test + public void givenAnXML_whenUseATreeConvertToJSON_thenReturnDataOK() { + String flowerXML = "PoppyRED9"; + + try { + XmlMapper xmlMapper = new XmlMapper(); + JsonNode node = xmlMapper.readTree(flowerXML.getBytes()); + + ObjectMapper jsonMapper = new ObjectMapper(); + String json = jsonMapper.writeValueAsString(node); + + System.out.println(json); + + assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":\"9\"}"); + } catch(IOException e) { + e.printStackTrace(); + } + } +} From 11dd36cb1a3b41da9b97720c71b4af27e8de56e0 Mon Sep 17 00:00:00 2001 From: Kumar Chandrakant Date: Mon, 8 Oct 2018 14:52:59 +0100 Subject: [PATCH 59/59] Adding files for the article BAEL-2257: Guide to OutputStream (#5386) --- .../baeldung/stream/OutputStreamExamples.java | 48 ++++++++++++ .../stream/OutputStreamExamplesTest.java | 76 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java create mode 100644 core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesTest.java diff --git a/core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java b/core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java new file mode 100644 index 0000000000..c7168c5b26 --- /dev/null +++ b/core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java @@ -0,0 +1,48 @@ +package com.baeldung.stream; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +public class OutputStreamExamples { + + public void fileOutputStreamByteSequence(String file, String data) throws IOException { + byte[] bytes = data.getBytes(); + try (OutputStream out = new FileOutputStream(file)) { + out.write(bytes); + } + } + + public void fileOutputStreamByteSubSequence(String file, String data) throws IOException { + byte[] bytes = data.getBytes(); + try (OutputStream out = new FileOutputStream(file)) { + out.write(bytes, 6, 5); + } + } + + public void fileOutputStreamByteSingle(String file, String data) throws IOException { + byte[] bytes = data.getBytes(); + try (OutputStream out = new FileOutputStream(file)) { + out.write(bytes[6]); + } + } + + public void bufferedOutputStream(String file, String... data) throws IOException { + try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { + for (String s : data) { + out.write(s.getBytes()); + out.write(" ".getBytes()); + } + } + } + + public void outputStreamWriter(String file, String data) throws IOException { + try (OutputStream out = new FileOutputStream(file); Writer writer = new OutputStreamWriter(out, "UTF-8")) { + writer.write(data); + } + } + +} diff --git a/core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesTest.java b/core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesTest.java new file mode 100644 index 0000000000..4ae1ce9aa7 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesTest.java @@ -0,0 +1,76 @@ +package com.baeldung.stream; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +public class OutputStreamExamplesTest { + + StringBuilder filePath = new StringBuilder(); + + @Before + public void init() { + filePath.append("src"); + filePath.append(File.separator); + filePath.append("test"); + filePath.append(File.separator); + filePath.append("resources"); + filePath.append(File.separator); + filePath.append("output_file.txt"); + } + + @Test + public void givenOutputStream_whenWriteSingleByteCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.fileOutputStreamByteSingle(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenOutputStream_whenWriteByteSequenceCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.fileOutputStreamByteSequence(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenOutputStream_whenWriteByteSubSequenceCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.fileOutputStreamByteSubSequence(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenBufferedOutputStream_whenCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.bufferedOutputStream(filePath.toString(), "Hello", "World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenOutputStreamWriter_whenCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.outputStreamWriter(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + +}