Merge pull request #1 from eugenp/master

Syncing
This commit is contained in:
soufiane-cheouati 2019-02-07 18:52:12 +00:00 committed by GitHub
commit 7f0e317513
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
145 changed files with 2331 additions and 130 deletions

View File

@ -15,3 +15,5 @@
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings) - [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters) - [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique) - [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)

View File

@ -1,3 +1,4 @@
### Relevant articles ### Relevant articles
- [Introduction to Apache Spark](http://www.baeldung.com/apache-spark) - [Introduction to Apache Spark](http://www.baeldung.com/apache-spark)
- [Building a Data Pipeline with Kafka, Spark Streaming and Cassandra](https://www.baeldung.com/kafka-spark-data-pipeline)

View File

@ -0,0 +1,43 @@
package com.baeldung.strings;
class Concatenate {
String first = 'Hello'
String last = 'Groovy'
String doSimpleConcat() {
return 'My name is ' + first + ' ' + last
}
String doConcatUsingGString() {
return "My name is $first $last"
}
String doConcatUsingGStringClosures() {
return "My name is ${-> first} ${-> last}"
}
String doConcatUsingStringConcatMethod() {
return 'My name is '.concat(first).concat(' ').concat(last)
}
String doConcatUsingLeftShiftOperator() {
return 'My name is ' << first << ' ' << last
}
String doConcatUsingArrayJoinMethod() {
return ['My name is', first, last].join(' ')
}
String doConcatUsingArrayInjectMethod() {
return [first,' ', last]
.inject(new StringBuffer('My name is '), { initial, name -> initial.append(name); return initial }).toString()
}
String doConcatUsingStringBuilder() {
return new StringBuilder().append('My name is ').append(first).append(' ').append(last)
}
String doConcatUsingStringBuffer() {
return new StringBuffer().append('My name is ').append(first).append(' ').append(last)
}
}

View File

@ -0,0 +1,101 @@
import com.baeldung.strings.Concatenate;
class ConcatenateTest extends GroovyTestCase {
void testSimpleConcat() {
def name = new Concatenate()
name.first = 'Joe';
name.last = 'Smith';
def expected = 'My name is Joe Smith'
assertToString(name.doSimpleConcat(), expected)
}
void testConcatUsingGString() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingGString(), expected)
}
void testConcatUsingGStringClosures() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingGStringClosures(), expected)
}
void testConcatUsingStringConcatMethod() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingStringConcatMethod(), expected)
}
void testConcatUsingLeftShiftOperator() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingLeftShiftOperator(), expected)
}
void testConcatUsingArrayJoinMethod() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingArrayJoinMethod(), expected)
}
void testConcatUsingArrayInjectMethod() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingArrayInjectMethod(), expected)
}
void testConcatUsingStringBuilder() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingStringBuilder(), expected)
}
void testConcatUsingStringBuffer() {
def name = new Concatenate()
name.first = "Joe";
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingStringBuffer(), expected)
}
void testConcatMultilineUsingStringConcatMethod() {
def name = new Concatenate()
name.first = '''Joe
Smith
''';
name.last = 'Junior';
def expected = '''My name is Joe
Smith
Junior''';
assertToString(name.doConcatUsingStringConcatMethod(), expected)
}
void testGStringvsClosure(){
def first = "Joe";
def last = "Smith";
def eagerGString = "My name is $first $last"
def lazyGString = "My name is ${-> first} ${-> last}"
assert eagerGString == "My name is Joe Smith"
assert lazyGString == "My name is Joe Smith"
first = "David";
assert eagerGString == "My name is Joe Smith"
assert lazyGString == "My name is David Smith"
}
}

View File

@ -3,3 +3,4 @@
- [Java 11 Single File Source Code](https://www.baeldung.com/java-single-file-source-code) - [Java 11 Single File Source Code](https://www.baeldung.com/java-single-file-source-code)
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params) - [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api) - [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)

View File

@ -39,6 +39,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class Java8CollectorsUnitTest { public class Java8CollectorsUnitTest {
private final List<String> givenList = Arrays.asList("a", "bb", "ccc", "dd"); private final List<String> givenList = Arrays.asList("a", "bb", "ccc", "dd");
private final List<String> listWithDuplicates = Arrays.asList("a", "bb", "c", "d", "bb");
@Test @Test
public void whenCollectingToList_shouldCollectToList() throws Exception { public void whenCollectingToList_shouldCollectToList() throws Exception {
@ -48,12 +49,19 @@ public class Java8CollectorsUnitTest {
} }
@Test @Test
public void whenCollectingToList_shouldCollectToSet() throws Exception { public void whenCollectingToSet_shouldCollectToSet() throws Exception {
final Set<String> result = givenList.stream().collect(toSet()); final Set<String> result = givenList.stream().collect(toSet());
assertThat(result).containsAll(givenList); assertThat(result).containsAll(givenList);
} }
@Test
public void givenContainsDuplicateElements_whenCollectingToSet_shouldAddDuplicateElementsOnlyOnce() throws Exception {
final Set<String> result = listWithDuplicates.stream().collect(toSet());
assertThat(result).hasSize(4);
}
@Test @Test
public void whenCollectingToCollection_shouldCollectToCollection() throws Exception { public void whenCollectingToCollection_shouldCollectToCollection() throws Exception {
final List<String> result = givenList.stream().collect(toCollection(LinkedList::new)); final List<String> result = givenList.stream().collect(toCollection(LinkedList::new));
@ -83,6 +91,13 @@ public class Java8CollectorsUnitTest {
assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2); assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2);
} }
@Test
public void givenContainsDuplicateElements_whenCollectingToMap_shouldThrowException() throws Exception {
assertThatThrownBy(() -> {
listWithDuplicates.stream().collect(toMap(Function.identity(), String::length));
}).isInstanceOf(IllegalStateException.class);
}
@Test @Test
public void whenCollectingAndThen_shouldCollect() throws Exception { public void whenCollectingAndThen_shouldCollect() throws Exception {
final List<String> result = givenList.stream().collect(collectingAndThen(toList(), ImmutableList::copyOf)); final List<String> result = givenList.stream().collect(collectingAndThen(toList(), ImmutableList::copyOf));

View File

@ -26,3 +26,4 @@
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api) - [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api) - [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)

View File

@ -14,3 +14,4 @@
- [Array Operations in Java](http://www.baeldung.com/java-common-array-operations) - [Array Operations in Java](http://www.baeldung.com/java-common-array-operations)
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection) - [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
- [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays) - [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays)
- [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array)

View File

@ -36,6 +36,22 @@
<version>${lombok.version}</version> <version>${lombok.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.1.0</version>
</dependency>
<dependency>
<groupId>colt</groupId>
<artifactId>colt</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>

View File

@ -0,0 +1,52 @@
package com.baeldung.list.primitive;
import com.google.common.primitives.ImmutableIntArray;
import com.google.common.primitives.Ints;
import gnu.trove.list.array.TIntArrayList;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.OptionalDouble;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
public class PrimitiveCollections {
public static void main(String[] args) {
int[] primitives = new int[] {5, 10, 0, 2, -8};
guavaPrimitives(primitives);
intStream(primitives);
TIntArrayList tList = new TIntArrayList(primitives);
cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList(primitives);
IntArrayList fastUtilList = new IntArrayList(primitives);
System.out.println(tList);
System.out.println(coltList);
System.out.println(fastUtilList);
}
private static void intStream(int[] primitives) {
IntStream stream = IntStream.of(5, 10, 0, 2, -8);
IntStream newStream = IntStream.of(primitives);
OptionalDouble average = stream.filter(i -> i > 0).average();
}
private static void guavaPrimitives(int[] primitives) {
ImmutableIntArray immutableIntArray = ImmutableIntArray.builder().addAll(primitives).build();
System.out.println(immutableIntArray);
}
}

View File

@ -31,3 +31,4 @@
- [A Guide to EnumMap](https://www.baeldung.com/java-enum-map) - [A Guide to EnumMap](https://www.baeldung.com/java-enum-map)
- [A Guide to Iterator in Java](http://www.baeldung.com/java-iterator) - [A Guide to Iterator in Java](http://www.baeldung.com/java-iterator)
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences) - [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)

View File

@ -37,3 +37,6 @@
- [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader) - [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader)
- [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension) - [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension)
- [Getting a Files Mime Type in Java](http://www.baeldung.com/java-file-mime-type) - [Getting a Files Mime Type in Java](http://www.baeldung.com/java-file-mime-type)
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
- [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files)

View File

@ -17,3 +17,4 @@
- [Java Switch Statement](https://www.baeldung.com/java-switch) - [Java Switch Statement](https://www.baeldung.com/java-switch)
- [The Modulo Operator in Java](https://www.baeldung.com/modulo-java) - [The Modulo Operator in Java](https://www.baeldung.com/modulo-java)
- [Ternary Operator In Java](https://www.baeldung.com/java-ternary-operator) - [Ternary Operator In Java](https://www.baeldung.com/java-ternary-operator)
- [Java instanceof Operator](https://www.baeldung.com/java-instanceof)

View File

@ -35,3 +35,9 @@
- [Retrieving a Class Name in Java](https://www.baeldung.com/java-class-name) - [Retrieving a Class Name in Java](https://www.baeldung.com/java-class-name)
- [Java Compound Operators](https://www.baeldung.com/java-compound-operators) - [Java Compound Operators](https://www.baeldung.com/java-compound-operators)
- [Guide to Java Packages](https://www.baeldung.com/java-packages) - [Guide to Java Packages](https://www.baeldung.com/java-packages)
- [The Java Native Keyword and Methods](https://www.baeldung.com/java-native)
- [If-Else Statement in Java](https://www.baeldung.com/java-if-else)
- [Control Structures in Java](https://www.baeldung.com/java-control-structures)
- [Java Interfaces](https://www.baeldung.com/java-interfaces)
- [Attaching Values to Java Enum](https://www.baeldung.com/java-enum-values)
- [Variable Scope in Java](https://www.baeldung.com/java-variable-scope)

View File

@ -1,4 +1,4 @@
package org.baeldung.variable.scope.examples; package com.baeldung.scope;
public class BracketScopeExample { public class BracketScopeExample {

View File

@ -1,4 +1,4 @@
package org.baeldung.variable.scope.examples; package com.baeldung.scope;
public class ClassScopeExample { public class ClassScopeExample {

View File

@ -1,4 +1,4 @@
package org.baeldung.variable.scope.examples; package com.baeldung.scope;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package org.baeldung.variable.scope.examples; package com.baeldung.scope;
public class MethodScopeExample { public class MethodScopeExample {

View File

@ -1,4 +1,4 @@
package org.baeldung.variable.scope.examples; package com.baeldung.scope;
public class NestedScopesExample { public class NestedScopesExample {

View File

@ -1,18 +1,43 @@
package com.baeldung.java.enumiteration; package com.baeldung.java.enumiteration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
public class EnumIterationExamples { public class EnumIterationExamples {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Enum iteration using forEach:"); System.out.println("Enum iteration using EnumSet:");
EnumSet.allOf(DaysOfWeekEnum.class).forEach(day -> System.out.println(day)); EnumSet.allOf(DaysOfWeekEnum.class).forEach(day -> System.out.println(day));
System.out.println("Enum iteration using Stream:"); System.out.println("Enum iteration using Stream:");
DaysOfWeekEnum.stream().filter(d -> d.getTypeOfDay().equals("off")).forEach(System.out::println); DaysOfWeekEnum.stream().filter(d -> d.getTypeOfDay().equals("off")).forEach(System.out::println);
System.out.println("Enum iteration using for loop:"); System.out.println("Enum iteration using a for loop:");
for (DaysOfWeekEnum day : DaysOfWeekEnum.values()) { for (DaysOfWeekEnum day : DaysOfWeekEnum.values()) {
System.out.println(day); System.out.println(day);
} }
System.out.println("Enum iteration using Arrays.asList():");
Arrays.asList(DaysOfWeekEnum.values()).forEach(day -> System.out.println(day));
System.out.println("Add Enum values to ArrayList:");
List<DaysOfWeekEnum> days = new ArrayList<>();
days.add(DaysOfWeekEnum.FRIDAY);
days.add(DaysOfWeekEnum.SATURDAY);
days.add(DaysOfWeekEnum.SUNDAY);
for (DaysOfWeekEnum day : days) {
System.out.println(day);
}
System.out.println("Remove SATURDAY from the list:");
days.remove(DaysOfWeekEnum.SATURDAY);
if (!days.contains(DaysOfWeekEnum.SATURDAY)) {
System.out.println("Saturday is no longer in the list");
}
for (DaysOfWeekEnum day : days) {
System.out.println(day);
}
} }
} }

View File

@ -6,3 +6,4 @@
- [Understanding Memory Leaks in Java](https://www.baeldung.com/java-memory-leaks) - [Understanding Memory Leaks in Java](https://www.baeldung.com/java-memory-leaks)
- [OutOfMemoryError: GC Overhead Limit Exceeded](http://www.baeldung.com/java-gc-overhead-limit-exceeded) - [OutOfMemoryError: GC Overhead Limit Exceeded](http://www.baeldung.com/java-gc-overhead-limit-exceeded)
- [Basic Introduction to JMX](http://www.baeldung.com/java-management-extensions) - [Basic Introduction to JMX](http://www.baeldung.com/java-management-extensions)
- [Monitoring Java Applications with Flight Recorder](https://www.baeldung.com/java-flight-recorder-monitoring)

View File

@ -9,3 +9,4 @@
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing) - [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
- [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures) - [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures)
- [SHA-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java) - [SHA-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
- [Enabling TLS v1.2 in Java 7](https://www.baeldung.com/java-7-tls-v12)

View File

@ -44,8 +44,8 @@
<!-- util --> <!-- util -->
<commons-lang3.version>3.8.1</commons-lang3.version> <commons-lang3.version>3.8.1</commons-lang3.version>
<bouncycastle.version>1.55</bouncycastle.version> <bouncycastle.version>1.60</bouncycastle.version>
<commons-codec.version>1.10</commons-codec.version> <commons-codec.version>1.11</commons-codec.version>
<!-- testing --> <!-- testing -->
<assertj-core.version>3.10.0</assertj-core.version> <assertj-core.version>3.10.0</assertj-core.version>

View File

@ -0,0 +1,9 @@
package com.baeldung.hashing;
public class DigestAlgorithms {
public static final String SHA3_256 = "SHA3-256";
public static final String SHA_256 = "SHA-256";
public static final String KECCAK_256 = "Keccak-256";
}

View File

@ -0,0 +1,30 @@
package com.baeldung.hashing;
import org.bouncycastle.jcajce.provider.digest.Keccak;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import static com.baeldung.hashing.DigestAlgorithms.KECCAK_256;
import static com.baeldung.hashing.SHACommonUtils.bytesToHex;
public class Keccak256Hashing {
public static String hashWithJavaMessageDigest(final String originalString) throws NoSuchAlgorithmException {
Security.addProvider(new BouncyCastleProvider());
final MessageDigest digest = MessageDigest.getInstance(KECCAK_256);
final byte[] encodedhash = digest.digest(originalString.getBytes(StandardCharsets.UTF_8));
return bytesToHex(encodedhash);
}
public static String hashWithBouncyCastle(final String originalString) {
Keccak.Digest256 digest256 = new Keccak.Digest256();
byte[] hashbytes = digest256.digest(originalString.getBytes(StandardCharsets.UTF_8));
return new String(Hex.encode(hashbytes));
}
}

View File

@ -8,15 +8,18 @@ import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import static com.baeldung.hashing.DigestAlgorithms.SHA_256;
import static com.baeldung.hashing.SHACommonUtils.bytesToHex;
public class SHA256Hashing { public class SHA256Hashing {
public static String HashWithJavaMessageDigest(final String originalString) throws NoSuchAlgorithmException { public static String HashWithJavaMessageDigest(final String originalString) throws NoSuchAlgorithmException {
final MessageDigest digest = MessageDigest.getInstance("SHA-256"); final MessageDigest digest = MessageDigest.getInstance(SHA_256);
final byte[] encodedhash = digest.digest(originalString.getBytes(StandardCharsets.UTF_8)); final byte[] encodedhash = digest.digest(originalString.getBytes(StandardCharsets.UTF_8));
return bytesToHex(encodedhash); return bytesToHex(encodedhash);
} }
public static String HashWithGuava(final String originalString) { public static String hashWithGuava(final String originalString) {
final String sha256hex = Hashing.sha256().hashString(originalString, StandardCharsets.UTF_8).toString(); final String sha256hex = Hashing.sha256().hashString(originalString, StandardCharsets.UTF_8).toString();
return sha256hex; return sha256hex;
} }
@ -27,20 +30,10 @@ public class SHA256Hashing {
} }
public static String HashWithBouncyCastle(final String originalString) throws NoSuchAlgorithmException { public static String HashWithBouncyCastle(final String originalString) throws NoSuchAlgorithmException {
final MessageDigest digest = MessageDigest.getInstance("SHA-256"); final MessageDigest digest = MessageDigest.getInstance(SHA_256);
final byte[] hash = digest.digest(originalString.getBytes(StandardCharsets.UTF_8)); final byte[] hash = digest.digest(originalString.getBytes(StandardCharsets.UTF_8));
final String sha256hex = new String(Hex.encode(hash)); final String sha256hex = new String(Hex.encode(hash));
return sha256hex; return sha256hex;
} }
private static String bytesToHex(byte[] hash) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
} }

View File

@ -0,0 +1,45 @@
package com.baeldung.hashing;
import com.google.common.hash.Hashing;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.digests.SHA3Digest;
import org.bouncycastle.jcajce.provider.digest.SHA3;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import static com.baeldung.hashing.DigestAlgorithms.SHA3_256;
import static com.baeldung.hashing.SHACommonUtils.bytesToHex;
public class SHA3Hashing {
/* works with JDK9+ only */
public static String hashWithJavaMessageDigestJDK9(final String originalString) throws NoSuchAlgorithmException {
final MessageDigest digest = MessageDigest.getInstance(SHA3_256);
final byte[] hashbytes = digest.digest(originalString.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hashbytes);
}
public static String hashWithJavaMessageDigest(final String originalString) throws NoSuchAlgorithmException {
Security.addProvider(new BouncyCastleProvider());
final MessageDigest digest = MessageDigest.getInstance(SHA3_256);
final byte[] hashbytes = digest.digest(originalString.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hashbytes);
}
/* works with JDK9+ only */
public static String hashWithApacheCommonsJDK9(final String originalString) {
return new DigestUtils(SHA3_256).digestAsHex(originalString);
}
public static String hashWithBouncyCastle(final String originalString) {
SHA3.Digest256 digest256 = new SHA3.Digest256();
byte[] hashbytes = digest256.digest(originalString.getBytes(StandardCharsets.UTF_8));
return new String(Hex.encode(hashbytes));
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.hashing;
class SHACommonUtils {
public static String bytesToHex(byte[] hash) {
StringBuffer hexString = new StringBuffer();
for (byte h : hash) {
String hex = Integer.toHexString(0xff & h);
if (hex.length() == 1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.hashing;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class Keccak256HashingUnitTest {
private static String originalValue = "abc123";
private static String hashedValue = "719accc61a9cc126830e5906f9d672d06eab6f8597287095a2c55a8b775e7016";
@Test public void testHashWithJavaMessageDigest() throws Exception {
final String currentHashedValue = Keccak256Hashing.hashWithJavaMessageDigest(originalValue);
assertEquals(hashedValue, currentHashedValue);
}
@Test public void testHashWithBouncyCastle() {
final String currentHashedValue = Keccak256Hashing.hashWithBouncyCastle(originalValue);
assertEquals(hashedValue, currentHashedValue);
}
}

View File

@ -12,24 +12,24 @@ public class SHA256HashingUnitTest {
@Test @Test
public void testHashWithJavaMessageDigest() throws Exception { public void testHashWithJavaMessageDigest() throws Exception {
final String currentHashedValue = SHA256Hashing.HashWithJavaMessageDigest(originalValue); final String currentHashedValue = SHA256Hashing.HashWithJavaMessageDigest(originalValue);
assertEquals(currentHashedValue, hashedValue); assertEquals(hashedValue, currentHashedValue);
} }
@Test @Test
public void testHashWithGuava() throws Exception { public void testHashWithGuava() throws Exception {
final String currentHashedValue = SHA256Hashing.HashWithApacheCommons(originalValue); final String currentHashedValue = SHA256Hashing.hashWithGuava(originalValue);
assertEquals(currentHashedValue, hashedValue); assertEquals(hashedValue, currentHashedValue);
} }
@Test @Test
public void testHashWithApacheCommans() throws Exception { public void testHashWithApacheCommans() throws Exception {
final String currentHashedValue = SHA256Hashing.HashWithGuava(originalValue); final String currentHashedValue = SHA256Hashing.HashWithApacheCommons(originalValue);
assertEquals(currentHashedValue, hashedValue); assertEquals(hashedValue, currentHashedValue);
} }
@Test @Test
public void testHashWithBouncyCastle() throws Exception { public void testHashWithBouncyCastle() throws Exception {
final String currentHashedValue = SHA256Hashing.HashWithBouncyCastle(originalValue); final String currentHashedValue = SHA256Hashing.HashWithBouncyCastle(originalValue);
assertEquals(currentHashedValue, hashedValue); assertEquals(hashedValue, currentHashedValue);
} }
} }

View File

@ -0,0 +1,38 @@
package com.baeldung.hashing;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SHA3HashingUnitTest {
private static String originalValue = "abc123";
private static String hashedValue = "f58fa3df820114f56e1544354379820cff464c9c41cb3ca0ad0b0843c9bb67ee";
/* works with JDK9+ only */
//@Test
public void testHashWithJavaMessageDigestJDK9() throws Exception {
final String currentHashedValue = SHA3Hashing.hashWithJavaMessageDigestJDK9(originalValue);
assertEquals(hashedValue, currentHashedValue);
}
@Test
public void testHashWithJavaMessageDigest() throws Exception {
final String currentHashedValue = SHA3Hashing.hashWithJavaMessageDigest(originalValue);
assertEquals(hashedValue, currentHashedValue);
}
/* works with JDK9+ only */
//@Test
public void testHashWithApacheCommonsJDK9() {
final String currentHashedValue = SHA3Hashing.hashWithApacheCommonsJDK9(originalValue);
assertEquals(hashedValue, currentHashedValue);
}
@Test
public void testHashWithBouncyCastle() {
final String currentHashedValue = SHA3Hashing.hashWithBouncyCastle(originalValue);
assertEquals(hashedValue, currentHashedValue);
}
}

View File

@ -46,3 +46,8 @@
- [Graphs in Java](https://www.baeldung.com/java-graphs) - [Graphs in Java](https://www.baeldung.com/java-graphs)
- [Console I/O in Java](http://www.baeldung.com/java-console-input-output) - [Console I/O in Java](http://www.baeldung.com/java-console-input-output)
- [Formatting with printf() in Java](https://www.baeldung.com/java-printstream-printf) - [Formatting with printf() in Java](https://www.baeldung.com/java-printstream-printf)
- [Retrieve Fields from a Java Class Using Reflection](https://www.baeldung.com/java-reflection-class-fields)
- [Introduction to Basic Syntax in Java](https://www.baeldung.com/java-syntax)
- [Using Curl in Java](https://www.baeldung.com/java-curl)
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)

View File

@ -0,0 +1,9 @@
package com.baeldung.jar;
public class JarExample {
public static void main(String[] args) {
System.out.println("Hello Baeldung Reader!");
}
}

View File

@ -0,0 +1 @@
Main-Class: com.baeldung.jar.JarExample

View File

@ -51,3 +51,4 @@
- [Operator Overloading in Kotlin](https://www.baeldung.com/kotlin-operator-overloading) - [Operator Overloading in Kotlin](https://www.baeldung.com/kotlin-operator-overloading)
- [Inline Classes in Kotlin](https://www.baeldung.com/kotlin-inline-classes) - [Inline Classes in Kotlin](https://www.baeldung.com/kotlin-inline-classes)
- [Creating Java static final Equivalents in Kotlin](https://www.baeldung.com/kotlin-java-static-final) - [Creating Java static final Equivalents in Kotlin](https://www.baeldung.com/kotlin-java-static-final)
- [Nested forEach in Kotlin](https://www.baeldung.com/kotlin-nested-foreach)

View File

@ -0,0 +1,24 @@
package com.baeldung.examples.common;
public class Account {
private String accountNumber;
private String type;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public interface AccountService {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public class AccountServiceImpl implements AccountService {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public interface AudioBookService {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public class AudioBookServiceImpl implements AudioBookService {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public interface AuthorService {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public class AuthorServiceImpl implements AuthorService {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public interface BookService {
}

View File

@ -0,0 +1,7 @@
package com.baeldung.examples.common;
public class BookServiceImpl implements BookService {
private AuthorService authorService;
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public interface PersonDao {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.examples.common;
public class PersonDaoImpl implements PersonDao {
}

View File

@ -0,0 +1,4 @@
package com.baeldung.examples.guice;
public class Foo {
}

View File

@ -0,0 +1,9 @@
package com.baeldung.examples.guice;
import com.google.inject.Inject;
public class FooProcessor {
@Inject
private Foo foo;
}

View File

@ -0,0 +1,19 @@
package com.baeldung.examples.guice;
import com.baeldung.examples.common.PersonDao;
import com.google.inject.Inject;
public class GuicePersonService {
@Inject
private PersonDao personDao;
public PersonDao getPersonDao() {
return personDao;
}
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.examples.guice;
import com.baeldung.examples.common.AccountService;
import com.google.inject.Inject;
public class GuiceUserService {
@Inject
private AccountService accountService;
public AccountService getAccountService() {
return accountService;
}
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.examples.guice;
public class Person {
private String firstName;
private String lastName;
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;
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.examples.guice.modules;
import com.baeldung.examples.common.AccountService;
import com.baeldung.examples.common.AccountServiceImpl;
import com.baeldung.examples.common.BookService;
import com.baeldung.examples.common.BookServiceImpl;
import com.baeldung.examples.common.PersonDao;
import com.baeldung.examples.common.PersonDaoImpl;
import com.baeldung.examples.guice.Foo;
import com.baeldung.examples.guice.Person;
import com.google.inject.AbstractModule;
import com.google.inject.Provider;
import com.google.inject.Provides;
public class GuiceModule extends AbstractModule {
@Override
protected void configure() {
try {
bind(AccountService.class).to(AccountServiceImpl.class);
bind(Person.class).toConstructor(Person.class.getConstructor());
// bind(Person.class).toProvider(new Provider<Person>() {
// public Person get() {
// Person p = new Person();
// return p;
// }
// });
bind(Foo.class).toProvider(new Provider<Foo>() {
public Foo get() {
return new Foo();
}
});
bind(PersonDao.class).to(PersonDaoImpl.class);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Provides
public BookService bookServiceGenerator() {
return new BookServiceImpl();
}
}

View File

@ -0,0 +1,61 @@
package com.baeldung.examples;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import com.baeldung.examples.common.BookService;
import com.baeldung.examples.guice.FooProcessor;
import com.baeldung.examples.guice.GuicePersonService;
import com.baeldung.examples.guice.GuiceUserService;
import com.baeldung.examples.guice.Person;
import com.baeldung.examples.guice.modules.GuiceModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class GuiceUnitTest {
@Test
public void givenAccountServiceInjectedInGuiceUserService_WhenGetAccountServiceInvoked_ThenReturnValueIsNotNull() {
Injector injector = Guice.createInjector(new GuiceModule());
GuiceUserService guiceUserService = injector.getInstance(GuiceUserService.class);
assertNotNull(guiceUserService.getAccountService());
}
@Test
public void givenBookServiceIsRegisteredInModule_WhenBookServiceIsInjected_ThenReturnValueIsNotNull() {
Injector injector = Guice.createInjector(new GuiceModule());
BookService bookService = injector.getInstance(BookService.class);
assertNotNull(bookService);
}
@Test
public void givenMultipleBindingsForPerson_WhenPersonIsInjected_ThenTestFailsByProvisionException() {
Injector injector = Guice.createInjector(new GuiceModule());
Person person = injector.getInstance(Person.class);
assertNotNull(person);
}
@Test
public void givenFooInjectedToFooProcessorAsOptionalDependency_WhenFooProcessorIsRetrievedFromContext_ThenCreationExceptionIsNotThrown() {
Injector injector = Guice.createInjector(new GuiceModule());
FooProcessor fooProcessor = injector.getInstance(FooProcessor.class);
assertNotNull(fooProcessor);
}
@Test
public void givenGuicePersonServiceConstructorAnnotatedByInject_WhenGuicePersonServiceIsInjected_ThenInstanceWillBeCreatedFromTheConstructor() {
Injector injector = Guice.createInjector(new GuiceModule());
GuicePersonService personService = injector.getInstance(GuicePersonService.class);
assertNotNull(personService);
}
@Test
public void givenPersonDaoInjectedToGuicePersonServiceBySetterInjection_WhenGuicePersonServiceIsInjected_ThenPersonDaoInitializedByTheSetter() {
Injector injector = Guice.createInjector(new GuiceModule());
GuicePersonService personService = injector.getInstance(GuicePersonService.class);
assertNotNull(personService);
assertNotNull(personService.getPersonDao());
}
}

View File

@ -37,3 +37,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria) - [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria)
- [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values) - [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values)
- [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json) - [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json)
- [Deserialize Immutable Objects with Jackson](https://www.baeldung.com/jackson-deserialize-immutable-objects)

View File

@ -19,3 +19,4 @@
- [How to Check If a Key Exists in a Map](https://www.baeldung.com/java-map-key-exists) - [How to Check If a Key Exists in a Map](https://www.baeldung.com/java-map-key-exists)
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps) - [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
- [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps) - [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps)
- [Map to String Conversion in Java](https://www.baeldung.com/java-map-to-string-conversion)

View File

@ -28,3 +28,4 @@
- [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp) - [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp)
- [A Guide to SimpleDateFormat](https://www.baeldung.com/java-simple-date-format) - [A Guide to SimpleDateFormat](https://www.baeldung.com/java-simple-date-format)
- [ZoneOffset in Java](https://www.baeldung.com/java-zone-offset) - [ZoneOffset in Java](https://www.baeldung.com/java-zone-offset)
- [Differences Between ZonedDateTime and OffsetDateTime](https://www.baeldung.com/java-zoneddatetime-offsetdatetime)

View File

@ -15,3 +15,5 @@
- [Stream Ordering in Java](https://www.baeldung.com/java-stream-ordering) - [Stream Ordering in Java](https://www.baeldung.com/java-stream-ordering)
- [Introduction to Protonpack](https://www.baeldung.com/java-protonpack) - [Introduction to Protonpack](https://www.baeldung.com/java-protonpack)
- [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda) - [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda)
- [Counting Matches on a Stream Filter](https://www.baeldung.com/java-stream-filter-count)
- [Java 8 Streams peek() API](https://www.baeldung.com/java-streams-peek-api)

View File

@ -50,3 +50,6 @@
- [Remove Leading and Trailing Characters from a String](https://www.baeldung.com/java-remove-trailing-characters) - [Remove Leading and Trailing Characters from a String](https://www.baeldung.com/java-remove-trailing-characters)
- [Concatenating Strings In Java](https://www.baeldung.com/java-strings-concatenation) - [Concatenating Strings In Java](https://www.baeldung.com/java-strings-concatenation)
- [Java toString() Method](https://www.baeldung.com/java-tostring) - [Java toString() Method](https://www.baeldung.com/java-tostring)
- [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions)
- [Check if a String is a Pangram in Java](https://www.baeldung.com/java-string-pangram)
- [Check If a String Contains Multiple Keywords](https://www.baeldung.com/string-contains-multiple-words)

View File

@ -0,0 +1,21 @@
package com.baeldung.jooby;
import static io.restassured.RestAssured.get;
import static org.hamcrest.Matchers.equalTo;
import org.jooby.test.JoobyRule;
import org.junit.ClassRule;
import org.junit.Test;
public class AppLiveTest {
@ClassRule
public static JoobyRule app = new JoobyRule(new App());
@Test
public void given_defaultUrl_expect_fixedString() {
get("/").then().assertThat().body(equalTo("Hello World!")).statusCode(200)
.contentType("text/html;charset=UTF-8");
}
}

View File

@ -1,25 +1,12 @@
package com.baeldung.jooby; package com.baeldung.jooby;
import static io.restassured.RestAssured.get;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.jooby.test.JoobyRule;
import org.jooby.test.MockRouter; import org.jooby.test.MockRouter;
import org.junit.ClassRule;
import org.junit.Test; import org.junit.Test;
public class AppUnitTest { public class AppUnitTest {
@ClassRule
public static JoobyRule app = new JoobyRule(new App());
@Test
public void given_defaultUrl_expect_fixedString() {
get("/").then().assertThat().body(equalTo("Hello World!")).statusCode(200)
.contentType("text/html;charset=UTF-8");
}
@Test @Test
public void given_defaultUrl_with_mockrouter_expect_fixedString() throws Throwable { public void given_defaultUrl_with_mockrouter_expect_fixedString() throws Throwable {
String result = new MockRouter(new App()).get("/"); String result = new MockRouter(new App()).get("/");

View File

@ -9,3 +9,4 @@
- [Working with Dates in Kotlin](https://www.baeldung.com/kotlin-dates) - [Working with Dates in Kotlin](https://www.baeldung.com/kotlin-dates)
- [Introduction to Arrow in Kotlin](https://www.baeldung.com/kotlin-arrow) - [Introduction to Arrow in Kotlin](https://www.baeldung.com/kotlin-arrow)
- [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor) - [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor)
- [REST API With Kotlin and Kovert](https://www.baeldung.com/kotlin-kovert)

View File

@ -7,3 +7,4 @@
- [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic) - [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic)
- [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) - [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel)
- [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client) - [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client)
- [Guide to XMPP Smack Client](https://www.baeldung.com/xmpp-smack-chat-client)

View File

@ -64,7 +64,8 @@
- [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once) - [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once)
- [An Introduction to SuanShu](https://www.baeldung.com/suanshu) - [An Introduction to SuanShu](https://www.baeldung.com/suanshu)
- [Implementing a FTP-Client in Java](http://www.baeldung.com/java-ftp-client) - [Implementing a FTP-Client in Java](http://www.baeldung.com/java-ftp-client)
- [Introduction to Functional Java](https://www.baeldung.com/java-functional-library - [Introduction to Functional Java](https://www.baeldung.com/java-functional-library)
- [Intro to Derive4J](https://www.baeldung.com/derive4j)
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.

View File

@ -30,6 +30,11 @@
<version>${springframework.version}</version> <version>${springframework.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -48,6 +53,11 @@
<artifactId>mapstruct-processor</artifactId> <artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version> <version>${org.mapstruct.version}</version>
</path> </path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths> </annotationProcessorPaths>
</configuration> </configuration>
</plugin> </plugin>
@ -55,10 +65,11 @@
</build> </build>
<properties> <properties>
<org.mapstruct.version>1.1.0.Final</org.mapstruct.version> <org.mapstruct.version>1.3.0.Beta2</org.mapstruct.version>
<springframework.version>4.3.4.RELEASE</springframework.version> <springframework.version>4.3.4.RELEASE</springframework.version>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<org.projectlombok.version>1.18.4</org.projectlombok.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,11 @@
package com.baeldung.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CarDTO {
private int id;
private String name;
}

View File

@ -0,0 +1,33 @@
package com.baeldung.dto;
public class PersonDTO {
private String id;
private String name;
public PersonDTO() {
}
public PersonDTO(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.entity;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Car {
private int id;
private String name;
}

View File

@ -0,0 +1,33 @@
package com.baeldung.entity;
public class Person {
private String id;
private String name;
public Person() {
}
public Person(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.mapper;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import com.baeldung.dto.CarDTO;
import com.baeldung.entity.Car;
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
CarDTO carToCarDTO(Car car);
}

View File

@ -0,0 +1,17 @@
package com.baeldung.mapper;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import com.baeldung.dto.PersonDTO;
import com.baeldung.entity.Person;
@Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
@Mapping(target = "id", source = "person.id", defaultExpression = "java(java.util.UUID.randomUUID().toString())")
PersonDTO personToPersonDTO(Person person);
}

View File

@ -0,0 +1,24 @@
package com.baeldung.mapper;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.baeldung.dto.CarDTO;
import com.baeldung.entity.Car;
public class CarMapperUnitTest {
@Test
public void givenCarEntitytoCar_whenMaps_thenCorrect() {
Car entity = new Car();
entity.setId(1);
entity.setName("Toyota");
CarDTO carDto = CarMapper.INSTANCE.carToCarDTO(entity);
assertEquals(carDto.getId(), entity.getId());
assertEquals(carDto.getName(), entity.getName());
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.mapper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import com.baeldung.dto.PersonDTO;
import com.baeldung.entity.Person;
public class PersonMapperUnitTest {
@Test
public void givenPersonEntitytoPersonWithExpression_whenMaps_thenCorrect() {
Person entity = new Person();
entity.setName("Micheal");
PersonDTO personDto = PersonMapper.INSTANCE.personToPersonDTO(entity);
assertNull(entity.getId());
assertNotNull(personDto.getId());
assertEquals(personDto.getName(), entity.getName());
}
}

View File

@ -29,3 +29,4 @@
- [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query) - [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query)
- [Using c3p0 with Hibernate](https://www.baeldung.com/hibernate-c3p0) - [Using c3p0 with Hibernate](https://www.baeldung.com/hibernate-c3p0)
- [Persist a JSON Object Using Hibernate](https://www.baeldung.com/hibernate-persist-json-object) - [Persist a JSON Object Using Hibernate](https://www.baeldung.com/hibernate-persist-json-object)
- [Common Hibernate Exceptions](https://www.baeldung.com/hibernate-exceptions)

View File

@ -9,15 +9,43 @@ import javax.persistence.Id;
public class Student { public class Student {
@Id @Id
@GeneratedValue (strategy = GenerationType.SEQUENCE) @GeneratedValue(strategy = GenerationType.SEQUENCE)
private long studentId; private long studentId;
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public long getStudentId() { public long getStudentId() {
return studentId; return studentId;
} }
public void setStudent_id(long studentId) { public void setStudentId(long studentId) {
this.studentId = studentId; this.studentId = studentId;
} }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
} }

View File

@ -0,0 +1,87 @@
package com.baeldung.hibernate.aggregatefunctions;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.baeldung.hibernate.HibernateUtil;
import com.baeldung.hibernate.pojo.Student;
public class AggregateFunctionsIntegrationTest {
private static Session session;
private static Transaction transaction;
@BeforeClass
public static final void setup() throws HibernateException, IOException {
session = HibernateUtil.getSessionFactory()
.openSession();
transaction = session.beginTransaction();
Student jonas = new Student("Jonas", 22);
session.save(jonas);
Student sally = new Student("Sally", 20);
session.save(sally);
Student simon = new Student("Simon", 25);
session.save(simon);
Student raven = new Student("Raven", 21);
session.save(raven);
Student sam = new Student("Sam", 23);
session.save(sam);
}
@AfterClass
public static final void teardown() {
if (session != null) {
transaction.rollback();
session.close();
}
}
@Test
public void whenMaxAge_ThenReturnValue() {
int maxAge = (int) session.createQuery("SELECT MAX(age) from Student")
.getSingleResult();
assertThat(maxAge).isEqualTo(25);
}
@Test
public void whenMinAge_ThenReturnValue() {
int minAge = (int) session.createQuery("SELECT MIN(age) from Student")
.getSingleResult();
assertThat(minAge).isEqualTo(20);
}
@Test
public void whenAverageAge_ThenReturnValue() {
Double avgAge = (Double) session.createQuery("SELECT AVG(age) from Student")
.getSingleResult();
assertThat(avgAge).isEqualTo(22.2);
}
@Test
public void whenCountAll_ThenReturnValue() {
Long totalStudents = (Long) session.createQuery("SELECT COUNT(*) from Student")
.getSingleResult();
assertThat(totalStudents).isEqualTo(5);
}
@Test
public void whenSumOfAllAges_ThenReturnValue() {
Long sumOfAllAges = (Long) session.createQuery("SELECT SUM(age) from Student")
.getSingleResult();
assertThat(sumOfAllAges).isEqualTo(111);
}
}

View File

@ -4,3 +4,5 @@
- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures)
- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast)
- [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph)
- [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time)
- [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date)

View File

@ -0,0 +1,19 @@
package com.baeldung;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@WebAppConfiguration
public class SpringContextIntegrationTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}

View File

@ -6,4 +6,4 @@
- [Configuring a Tomcat Connection Pool in Spring Boot](https://www.baeldung.com/spring-boot-tomcat-connection-pool) - [Configuring a Tomcat Connection Pool in Spring Boot](https://www.baeldung.com/spring-boot-tomcat-connection-pool)
- [Hibernate Field Naming with Spring Boot](https://www.baeldung.com/hibernate-field-naming-spring-boot) - [Hibernate Field Naming with Spring Boot](https://www.baeldung.com/hibernate-field-naming-spring-boot)
- [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb) - [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb)
- [Configuring a DataSource Programmatically in Spring Boot](https://www.baeldung.com/spring-boot-configure-data-source-programmatic)

View File

@ -19,6 +19,7 @@
- [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting) - [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting)
- [INSERT Statement in JPA](https://www.baeldung.com/jpa-insert) - [INSERT Statement in JPA](https://www.baeldung.com/jpa-insert)
- [Pagination and Sorting using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-pagination-sorting) - [Pagination and Sorting using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-pagination-sorting)
- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
### Eclipse Config ### Eclipse Config
After importing the project into Eclipse, you may see the following error: After importing the project into Eclipse, you may see the following error:

View File

@ -1,17 +1,24 @@
package com.baeldung.hibernate.criteria; package com.baeldung.hibernate.criteria;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.List; import java.util.List;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import org.junit.Test;
import com.baeldung.hibernate.criteria.model.Item; import com.baeldung.hibernate.criteria.model.Item;
import com.baeldung.hibernate.criteria.util.HibernateUtil; import com.baeldung.hibernate.criteria.util.HibernateUtil;
import com.baeldung.hibernate.criteria.view.ApplicationView; import com.baeldung.hibernate.criteria.view.ApplicationView;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Root;
public class HibernateCriteriaIntegrationTest { public class HibernateCriteriaIntegrationTest {
final private ApplicationView av = new ApplicationView(); final private ApplicationView av = new ApplicationView();
@ -179,4 +186,51 @@ public class HibernateCriteriaIntegrationTest {
session.close(); session.close();
assertArrayEquals(expectedPriceBetweenItems, av.betweenCriteria()); assertArrayEquals(expectedPriceBetweenItems, av.betweenCriteria());
} }
@Test
public void givenNewItemPrice_whenCriteriaUpdate_thenReturnAffectedResult() {
int oldPrice = 10, newPrice = 20;
Session session = HibernateUtil.getHibernateSession();
Item item = new Item(12, "Test Item 12", "This is a description");
item.setItemPrice(oldPrice);
session.save(item);
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaUpdate<Item> criteriaUpdate = cb.createCriteriaUpdate(Item.class);
Root<Item> root = criteriaUpdate.from(Item.class);
criteriaUpdate.set("itemPrice", newPrice);
criteriaUpdate.where(cb.equal(root.get("itemPrice"), oldPrice));
Transaction transaction = session.beginTransaction();
session.createQuery(criteriaUpdate).executeUpdate();
transaction.commit();
Item updatedItem = session.createQuery("FROM Item WHERE itemPrice = " + newPrice, Item.class).getSingleResult();
session.refresh(updatedItem);
assertEquals(newPrice, updatedItem.getItemPrice().intValue());
}
@Test
public void givenTargetItemPrice_whenCriteriaDelete_thenDeleteMatched() {
int targetPrice = 1000;
Session session = HibernateUtil.getHibernateSession();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaDelete<Item> criteriaDelete = cb.createCriteriaDelete(Item.class);
Root<Item> root = criteriaDelete.from(Item.class);
criteriaDelete.where(cb.greaterThan(root.get("itemPrice"), targetPrice));
Transaction transaction = session.beginTransaction();
session.createQuery(criteriaDelete).executeUpdate();
transaction.commit();
List<Item> deletedItem = session.createQuery("FROM Item WHERE itemPrice > " + targetPrice, Item.class).list();
assertTrue(deletedItem.isEmpty());
}
} }

View File

@ -0,0 +1,19 @@
package com.baeldung;
import org.baeldung.config.PersistenceJPAConfigL2Cache;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class)
@WebAppConfiguration
public class SpringContextIntegrationTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}

View File

@ -733,6 +733,7 @@
<module>spring-security-mvc-boot</module> <module>spring-security-mvc-boot</module>
<module>spring-security-mvc-custom</module> <module>spring-security-mvc-custom</module>
<module>spring-security-mvc-digest-auth</module> <module>spring-security-mvc-digest-auth</module>
<module>spring-security-mvc-jsonview</module>
<module>spring-security-mvc-ldap</module> <module>spring-security-mvc-ldap</module>
<module>spring-security-mvc-login</module> <module>spring-security-mvc-login</module>
<module>spring-security-mvc-persisted-remember-me</module> <module>spring-security-mvc-persisted-remember-me</module>

View File

@ -2,13 +2,16 @@ package org.baeldung;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.baeldung.flips.ApplicationConfig; import com.baeldung.flips.ApplicationConfig;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApplicationConfig.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ApplicationConfig.class)
@WebAppConfiguration
public class SpringContextIntegrationTest { public class SpringContextIntegrationTest {
@Test @Test

View File

@ -1,3 +1,4 @@
### Relevant Articles: ### Relevant Articles:
- [Spring Security OAuth Login with WebFlux](https://www.baeldung.com/spring-oauth-login-webflux) - [Spring Security OAuth Login with WebFlux](https://www.baeldung.com/spring-oauth-login-webflux)
- [Spring WebClient and OAuth2 Support](https://www.baeldung.com/spring-webclient-oauth2)

View File

@ -62,11 +62,11 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration> <configuration>
<testFailureIgnore>true</testFailureIgnore> <testFailureIgnore>true</testFailureIgnore>
<excludes> <excludes>
<exclude>**/*IntegrationTest.java</exclude> <exclude>**/*IntegrationTest.java</exclude>
<exclude>**/*LiveTest.java</exclude>
</excludes> </excludes>
</configuration> </configuration>
</plugin> </plugin>

View File

@ -0,0 +1,19 @@
package com.baeldung;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.baeldung.autoconfiguration.MySQLAutoconfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MySQLAutoconfiguration.class)
@WebAppConfiguration
public class SpringContextLiveTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}

View File

@ -5,3 +5,4 @@
- [Deploying a Spring Boot Application to Cloud Foundry](https://www.baeldung.com/spring-boot-app-deploy-to-cloud-foundry) - [Deploying a Spring Boot Application to Cloud Foundry](https://www.baeldung.com/spring-boot-app-deploy-to-cloud-foundry)
- [Deploy a Spring Boot Application to Google App Engine](https://www.baeldung.com/spring-boot-google-app-engine) - [Deploy a Spring Boot Application to Google App Engine](https://www.baeldung.com/spring-boot-google-app-engine)
- [Deploy a Spring Boot Application to OpenShift](https://www.baeldung.com/spring-boot-deploy-openshift) - [Deploy a Spring Boot Application to OpenShift](https://www.baeldung.com/spring-boot-deploy-openshift)
- [Deploy a Spring Boot Application to AWS Beanstalk](https://www.baeldung.com/spring-boot-deploy-aws-beanstalk)

View File

@ -10,3 +10,4 @@
- [A Controller, Service and DAO Example with Spring Boot and JSF](https://www.baeldung.com/jsf-spring-boot-controller-service-dao) - [A Controller, Service and DAO Example with Spring Boot and JSF](https://www.baeldung.com/jsf-spring-boot-controller-service-dao)
- [Cache Eviction in Spring Boot](https://www.baeldung.com/spring-boot-evict-cache) - [Cache Eviction in Spring Boot](https://www.baeldung.com/spring-boot-evict-cache)
- [Setting Up Swagger 2 with a Spring REST API](http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) - [Setting Up Swagger 2 with a Spring REST API](http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api)
- [Conditionally Enable Scheduled Jobs in Spring](https://www.baeldung.com/spring-scheduled-enabled-conditionally)

View File

@ -3,3 +3,4 @@ Module for the articles that are part of the Spring REST E-book:
1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration) 1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring) 2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring)
3. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring) 3. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring)
4. [Build a REST API with Spring and Java Config](http://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration)

View File

@ -51,7 +51,6 @@
<dependency> <dependency>
<groupId>net.sourceforge.htmlunit</groupId> <groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId> <artifactId>htmlunit</artifactId>
<version>${htmlunit.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -67,7 +66,6 @@
<properties> <properties>
<start-class>com.baeldung.SpringBootRestApplication</start-class> <start-class>com.baeldung.SpringBootRestApplication</start-class>
<htmlunit.version>2.32</htmlunit.version>
<guava.version>27.0.1-jre</guava.version> <guava.version>27.0.1-jre</guava.version>
</properties> </properties>
</project> </project>

View File

@ -1,16 +1,29 @@
package com.baeldung.persistence; package com.baeldung.persistence;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
public interface IOperations<T extends Serializable> { public interface IOperations<T extends Serializable> {
// read - one
T findOne(final long id);
// read - all // read - all
List<T> findAll();
Page<T> findPaginated(int page, int size); Page<T> findPaginated(int page, int size);
// write // write
T create(final T entity); T create(final T entity);
T update(final T entity);
void delete(final T entity);
void deleteById(final long entityId);
} }

View File

@ -1,6 +1,7 @@
package com.baeldung.persistence.service.common; package com.baeldung.persistence.service.common;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
@ -8,12 +9,28 @@ import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.baeldung.persistence.IOperations; import com.baeldung.persistence.IOperations;
import com.google.common.collect.Lists;
@Transactional @Transactional
public abstract class AbstractService<T extends Serializable> implements IOperations<T> { public abstract class AbstractService<T extends Serializable> implements IOperations<T> {
// read - one
@Override
@Transactional(readOnly = true)
public T findOne(final long id) {
return getDao().findById(id)
.get();
}
// read - all // read - all
@Override
@Transactional(readOnly = true)
public List<T> findAll() {
return Lists.newArrayList(getDao().findAll());
}
@Override @Override
public Page<T> findPaginated(final int page, final int size) { public Page<T> findPaginated(final int page, final int size) {
return getDao().findAll(PageRequest.of(page, size)); return getDao().findAll(PageRequest.of(page, size));
@ -26,6 +43,21 @@ public abstract class AbstractService<T extends Serializable> implements IOperat
return getDao().save(entity); return getDao().save(entity);
} }
@Override
public T update(final T entity) {
return getDao().save(entity);
}
@Override
public void delete(final T entity) {
getDao().delete(entity);
}
@Override
public void deleteById(final long entityId) {
getDao().deleteById(entityId);
}
protected abstract PagingAndSortingRepository<T, Long> getDao(); protected abstract PagingAndSortingRepository<T, Long> getDao();
} }

View File

@ -1,5 +1,7 @@
package com.baeldung.persistence.service.impl; package com.baeldung.persistence.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
@ -11,6 +13,7 @@ import com.baeldung.persistence.dao.IFooDao;
import com.baeldung.persistence.model.Foo; import com.baeldung.persistence.model.Foo;
import com.baeldung.persistence.service.IFooService; import com.baeldung.persistence.service.IFooService;
import com.baeldung.persistence.service.common.AbstractService; import com.baeldung.persistence.service.common.AbstractService;
import com.google.common.collect.Lists;
@Service @Service
@Transactional @Transactional
@ -37,4 +40,12 @@ public class FooService extends AbstractService<Foo> implements IFooService {
return dao.findAll(pageable); return dao.findAll(pageable);
} }
// overridden to be secured
@Override
@Transactional(readOnly = true)
public List<Foo> findAll() {
return Lists.newArrayList(getDao().findAll());
}
} }

View File

@ -9,14 +9,16 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import com.baeldung.persistence.model.Foo; import com.baeldung.persistence.model.Foo;
@ -24,9 +26,11 @@ import com.baeldung.persistence.service.IFooService;
import com.baeldung.web.exception.MyResourceNotFoundException; import com.baeldung.web.exception.MyResourceNotFoundException;
import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent; import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent;
import com.baeldung.web.hateoas.event.ResourceCreatedEvent; import com.baeldung.web.hateoas.event.ResourceCreatedEvent;
import com.baeldung.web.hateoas.event.SingleResourceRetrievedEvent;
import com.baeldung.web.util.RestPreconditions;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
@Controller @RestController
@RequestMapping(value = "/auth/foos") @RequestMapping(value = "/auth/foos")
public class FooController { public class FooController {
@ -42,10 +46,24 @@ public class FooController {
// API // API
// read - one
@GetMapping(value = "/{id}")
public Foo findById(@PathVariable("id") final Long id, final HttpServletResponse response) {
final Foo resourceById = RestPreconditions.checkFound(service.findOne(id));
eventPublisher.publishEvent(new SingleResourceRetrievedEvent(this, response));
return resourceById;
}
// read - all // read - all
@RequestMapping(params = { "page", "size" }, method = RequestMethod.GET) @GetMapping
@ResponseBody public List<Foo> findAll() {
return service.findAll();
}
@GetMapping(params = { "page", "size" })
public List<Foo> findPaginated(@RequestParam("page") final int page, @RequestParam("size") final int size, public List<Foo> findPaginated(@RequestParam("page") final int page, @RequestParam("size") final int size,
final UriComponentsBuilder uriBuilder, final HttpServletResponse response) { final UriComponentsBuilder uriBuilder, final HttpServletResponse response) {
final Page<Foo> resultPage = service.findPaginated(page, size); final Page<Foo> resultPage = service.findPaginated(page, size);
@ -59,7 +77,6 @@ public class FooController {
} }
@GetMapping("/pageable") @GetMapping("/pageable")
@ResponseBody
public List<Foo> findPaginatedWithPageable(Pageable pageable, final UriComponentsBuilder uriBuilder, public List<Foo> findPaginatedWithPageable(Pageable pageable, final UriComponentsBuilder uriBuilder,
final HttpServletResponse response) { final HttpServletResponse response) {
final Page<Foo> resultPage = service.findPaginated(pageable); final Page<Foo> resultPage = service.findPaginated(pageable);
@ -74,9 +91,8 @@ public class FooController {
// write // write
@RequestMapping(method = RequestMethod.POST) @PostMapping
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public Foo create(@RequestBody final Foo resource, final HttpServletResponse response) { public Foo create(@RequestBody final Foo resource, final HttpServletResponse response) {
Preconditions.checkNotNull(resource); Preconditions.checkNotNull(resource);
final Foo foo = service.create(resource); final Foo foo = service.create(resource);
@ -86,4 +102,18 @@ public class FooController {
return foo; return foo;
} }
@PutMapping(value = "/{id}")
@ResponseStatus(HttpStatus.OK)
public void update(@PathVariable("id") final Long id, @RequestBody final Foo resource) {
Preconditions.checkNotNull(resource);
RestPreconditions.checkFound(service.findOne(resource.getId()));
service.update(resource);
}
@DeleteMapping(value = "/{id}")
@ResponseStatus(HttpStatus.OK)
public void delete(@PathVariable("id") final Long id) {
service.deleteById(id);
}
} }

View File

@ -0,0 +1,22 @@
package com.baeldung.web.hateoas.event;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.ApplicationEvent;
public class SingleResourceRetrievedEvent extends ApplicationEvent {
private final HttpServletResponse response;
public SingleResourceRetrievedEvent(final Object source, final HttpServletResponse response) {
super(source);
this.response = response;
}
// API
public HttpServletResponse getResponse() {
return response;
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.web.hateoas.listener;
import javax.servlet.http.HttpServletResponse;
import com.baeldung.web.hateoas.event.SingleResourceRetrievedEvent;
import com.baeldung.web.util.LinkUtil;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.google.common.base.Preconditions;
import com.google.common.net.HttpHeaders;
@Component
class SingleResourceRetrievedDiscoverabilityListener implements ApplicationListener<SingleResourceRetrievedEvent> {
@Override
public void onApplicationEvent(final SingleResourceRetrievedEvent resourceRetrievedEvent) {
Preconditions.checkNotNull(resourceRetrievedEvent);
final HttpServletResponse response = resourceRetrievedEvent.getResponse();
addLinkHeaderOnSingleResourceRetrieval(response);
}
void addLinkHeaderOnSingleResourceRetrieval(final HttpServletResponse response) {
final String requestURL = ServletUriComponentsBuilder.fromCurrentRequestUri().build().toUri().toASCIIString();
final int positionOfLastSlash = requestURL.lastIndexOf("/");
final String uriForResourceCreation = requestURL.substring(0, positionOfLastSlash);
final String linkHeaderValue = LinkUtil.createLinkHeader(uriForResourceCreation, "collection");
response.addHeader(HttpHeaders.LINK, linkHeaderValue);
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.web;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
*
* We'll start the whole context, but not the server. We'll mock the REST calls instead.
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class FooControllerAppIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
public void whenFindPaginatedRequest_thenEmptyResponse() throws Exception {
this.mockMvc.perform(get("/auth/foos").param("page", "0")
.param("size", "2"))
.andExpect(status().isOk())
.andExpect(content().json("[]"));
}
}

View File

@ -0,0 +1,60 @@
package com.baeldung.web;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Collections;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import com.baeldung.persistence.model.Foo;
import com.baeldung.persistence.service.IFooService;
import com.baeldung.web.controller.FooController;
import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent;
/**
*
* We'll start only the web layer.
*
*/
@RunWith(SpringRunner.class)
@WebMvcTest(FooController.class)
public class FooControllerWebLayerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private IFooService service;
@MockBean
private ApplicationEventPublisher publisher;
@Test()
public void givenPresentFoo_whenFindPaginatedRequest_thenPageWithFooRetrieved() throws Exception {
Page<Foo> page = new PageImpl<>(Collections.singletonList(new Foo("fooName")));
when(service.findPaginated(0, 2)).thenReturn(page);
doNothing().when(publisher)
.publishEvent(any(PaginatedResultsRetrievedEvent.class));
this.mockMvc.perform(get("/auth/foos").param("page", "0")
.param("size", "2"))
.andExpect(status().isOk())
.andExpect(jsonPath("$",Matchers.hasSize(1)));
}
}

View File

@ -35,3 +35,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties) - [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties)
- [Display Auto-Configuration Report in Spring Boot](https://www.baeldung.com/spring-boot-auto-configuration-report) - [Display Auto-Configuration Report in Spring Boot](https://www.baeldung.com/spring-boot-auto-configuration-report)
- [Injecting Git Information Into Spring](https://www.baeldung.com/spring-git-information) - [Injecting Git Information Into Spring](https://www.baeldung.com/spring-git-information)
- [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation)

Some files were not shown because too many files have changed in this diff Show More