diff --git a/core-java/src/main/java/com/baeldung/generics/Generics.java b/core-java/src/main/java/com/baeldung/generics/Generics.java new file mode 100644 index 0000000000..69c7baddd3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/generics/Generics.java @@ -0,0 +1,23 @@ +package com.baeldung.generics; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Generics { + + // definition of a generic method + public static List fromArrayToList(T[] a) { + List list = new ArrayList<>(); + Arrays.stream(a).forEach(list::add); + return list; + } + + // example of a generic method that has Number as an upper bound for T + public static List fromArrayToListWithUpperBound(T[] a) { + List list = new ArrayList<>(); + Arrays.stream(a).forEach(list::add); + return list; + } + +} diff --git a/core-java/src/main/java/com/baeldung/java/nio2/visitor/FileSearchExample.java b/core-java/src/main/java/com/baeldung/java/nio2/visitor/FileSearchExample.java new file mode 100644 index 0000000000..15910abf9b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/nio2/visitor/FileSearchExample.java @@ -0,0 +1,60 @@ +package com.baeldung.java.nio2.visitor; + +import static java.nio.file.FileVisitResult.CONTINUE; +import static java.nio.file.FileVisitResult.TERMINATE; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributes; + +public class FileSearchExample implements FileVisitor { + private static String FILE_NAME; + private static Path START_DIR; + + public FileSearchExample(String fileName, Path startingDir) { + FILE_NAME = fileName; + START_DIR = startingDir; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + return CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String fileName = file.getFileName().toString(); + if (FILE_NAME.equals(fileName)) { + System.out.println("File found: " + file.toString()); + return TERMINATE; + } + return CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { + System.out.println("Failed to access file: " + file.toString()); + return CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + boolean finishedSearch = Files.isSameFile(dir, START_DIR); + if (finishedSearch) { + System.out.println("File:" + FILE_NAME + " not found"); + return TERMINATE; + } + return CONTINUE; + } + + public static void main(String[] args) throws IOException { + Path startingDir = Paths.get("C:/Users/new/Desktop"); + FileSearchExample crawler = new FileSearchExample("hibernate.txt", startingDir); + Files.walkFileTree(startingDir, crawler); + } + +} diff --git a/core-java/src/main/java/com/baeldung/java/nio2/visitor/FileVisitorImpl.java b/core-java/src/main/java/com/baeldung/java/nio2/visitor/FileVisitorImpl.java new file mode 100644 index 0000000000..360d6d0689 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/nio2/visitor/FileVisitorImpl.java @@ -0,0 +1,30 @@ +package com.baeldung.java.nio2.visitor; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +public class FileVisitorImpl implements FileVisitor { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + return null; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + return null; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return null; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + return null; + } +} diff --git a/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java b/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java new file mode 100644 index 0000000000..ffc58a1c50 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java @@ -0,0 +1,25 @@ +package com.baeldung.java.nio2.watcher; + +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; + +public class DirectoryWatcherExample { + public static void main(String[] args) throws IOException, InterruptedException { + WatchService watchService = FileSystems.getDefault().newWatchService(); + Path path = Paths.get(System.getProperty("user.home")); + path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY); + WatchKey key; + while ((key = watchService.take()) != null) { + for (WatchEvent event : key.pollEvents()) { + System.out.println("Event kind:" + event.kind() + ". File affected: " + event.context() + "."); + } + key.reset(); + } + } +} diff --git a/core-java/src/test/java/com/baeldung/generics/GenericsTest.java b/core-java/src/test/java/com/baeldung/generics/GenericsTest.java new file mode 100644 index 0000000000..9eb459ccb5 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/generics/GenericsTest.java @@ -0,0 +1,41 @@ +package com.baeldung.generics; + +import org.junit.Test; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; + +public class GenericsTest { + + // testing the generic method with Integer + @Test + public void givenArrayOfIntegers_thanListOfIntegersReturnedOK() { + Integer[] intArray = {1, 2, 3, 4, 5}; + List list = Generics.fromArrayToList(intArray); + + assertThat(list, hasItems(intArray)); + } + + // testing the generic method with String + @Test + public void givenArrayOfStrings_thanListOfStringsReturnedOK() { + String[] stringArray = {"hello1", "hello2", "hello3", "hello4", "hello5"}; + List list = Generics.fromArrayToList(stringArray); + + assertThat(list, hasItems(stringArray)); + } + + // testing the generic method with Number as upper bound with Integer + // if we test fromArrayToListWithUpperBound with any type that doesn't + // extend Number it will fail to compile + @Test + public void givenArrayOfIntegersAndNumberUpperBound_thanListOfIntegersReturnedOK() { + Integer[] intArray = {1, 2, 3, 4, 5}; + List list = Generics.fromArrayToListWithUpperBound(intArray); + + assertThat(list, hasItems(intArray)); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoClient.java b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoClient.java new file mode 100644 index 0000000000..ea35130f49 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoClient.java @@ -0,0 +1,82 @@ +package com.baeldung.java.nio2.async; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousSocketChannel; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class AsyncEchoClient { + private AsynchronousSocketChannel client; + private Future future; + private static AsyncEchoClient instance; + + private AsyncEchoClient() { + try { + client = AsynchronousSocketChannel.open(); + InetSocketAddress hostAddress = new InetSocketAddress("localhost", 4999); + future = client.connect(hostAddress); + start(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static AsyncEchoClient getInstance() { + if (instance == null) + instance = new AsyncEchoClient(); + return instance; + } + + private void start() { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } + + public String sendMessage(String message) { + byte[] byteMsg = new String(message).getBytes(); + ByteBuffer buffer = ByteBuffer.wrap(byteMsg); + Future writeResult = client.write(buffer); + + while (!writeResult.isDone()) { + // do nothing + } + buffer.flip(); + Future readResult = client.read(buffer); + while (!readResult.isDone()) { + + } + String echo = new String(buffer.array()).trim(); + buffer.clear(); + return echo; + } + + public void stop() { + try { + client.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) throws IOException { + AsyncEchoClient client = AsyncEchoClient.getInstance(); + client.start(); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String line = null; + System.out.println("Message to server:"); + while ((line = br.readLine()) != null) { + String response = client.sendMessage(line); + System.out.println("response from server: " + response); + System.out.println("Message to server:"); + } + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer.java b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer.java new file mode 100644 index 0000000000..0e58cb5f10 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer.java @@ -0,0 +1,79 @@ +package com.baeldung.java.nio2.async; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousServerSocketChannel; +import java.nio.channels.AsynchronousSocketChannel; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class AsyncEchoServer { + private AsynchronousServerSocketChannel serverChannel; + private Future acceptResult; + private AsynchronousSocketChannel clientChannel; + + public AsyncEchoServer() { + try { + serverChannel = AsynchronousServerSocketChannel.open(); + InetSocketAddress hostAddress = new InetSocketAddress("localhost", 4999); + serverChannel.bind(hostAddress); + acceptResult = serverChannel.accept(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void runServer() { + try { + clientChannel = acceptResult.get(); + if ((clientChannel != null) && (clientChannel.isOpen())) { + while (true) { + + ByteBuffer buffer = ByteBuffer.allocate(32); + Future readResult = clientChannel.read(buffer); + + while (!readResult.isDone()) { + // do nothing + } + + buffer.flip(); + String message = new String(buffer.array()).trim(); + if (message.equals("bye")) { + break; // while loop + } + buffer = ByteBuffer.wrap(new String(message).getBytes()); + Future writeResult = clientChannel.write(buffer); + while (!writeResult.isDone()) { + // do nothing + } + buffer.clear(); + + } // while() + + clientChannel.close(); + serverChannel.close(); + + } + } catch (InterruptedException | ExecutionException | IOException e) { + e.printStackTrace(); + } + + } + + public static void main(String[] args) { + AsyncEchoServer server = new AsyncEchoServer(); + server.runServer(); + } + public static Process start() throws IOException, InterruptedException { + String javaHome = System.getProperty("java.home"); + String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; + String classpath = System.getProperty("java.class.path"); + String className = AsyncEchoServer.class.getCanonicalName(); + + ProcessBuilder builder = new ProcessBuilder(javaBin, "-cp", classpath, className); + + return builder.start(); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer2.java b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer2.java new file mode 100644 index 0000000000..03ce233ce9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer2.java @@ -0,0 +1,100 @@ +package com.baeldung.java.nio2.async; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousServerSocketChannel; +import java.nio.channels.AsynchronousSocketChannel; +import java.nio.channels.CompletionHandler; +import java.util.HashMap; +import java.util.Map; + +public class AsyncEchoServer2 { + private AsynchronousServerSocketChannel serverChannel; + private AsynchronousSocketChannel clientChannel; + + public AsyncEchoServer2() { + try { + serverChannel = AsynchronousServerSocketChannel.open(); + InetSocketAddress hostAddress = new InetSocketAddress("localhost", 4999); + serverChannel.bind(hostAddress); + while (true) { + + serverChannel.accept(null, new CompletionHandler() { + + @Override + public void completed(AsynchronousSocketChannel result, Object attachment) { + if (serverChannel.isOpen()) + serverChannel.accept(null, this); + clientChannel = result; + if ((clientChannel != null) && (clientChannel.isOpen())) { + ReadWriteHandler handler = new ReadWriteHandler(); + ByteBuffer buffer = ByteBuffer.allocate(32); + Map readInfo = new HashMap<>(); + readInfo.put("action", "read"); + readInfo.put("buffer", buffer); + clientChannel.read(buffer, readInfo, handler); + } + } + + @Override + public void failed(Throwable exc, Object attachment) { + // process error + } + }); + try { + System.in.read(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + class ReadWriteHandler implements CompletionHandler> { + + @Override + public void completed(Integer result, Map attachment) { + Map actionInfo = attachment; + String action = (String) actionInfo.get("action"); + if ("read".equals(action)) { + ByteBuffer buffer = (ByteBuffer) actionInfo.get("buffer"); + buffer.flip(); + actionInfo.put("action", "write"); + clientChannel.write(buffer, actionInfo, this); + buffer.clear(); + } else if ("write".equals(action)) { + ByteBuffer buffer = ByteBuffer.allocate(32); + actionInfo.put("action", "read"); + actionInfo.put("buffer", buffer); + clientChannel.read(buffer, actionInfo, this); + } + + } + + @Override + public void failed(Throwable exc, Map attachment) { + + } + + } + + + public static void main(String[] args) { + new AsyncEchoServer2(); + } + + public static Process start() throws IOException, InterruptedException { + String javaHome = System.getProperty("java.home"); + String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; + String classpath = System.getProperty("java.class.path"); + String className = AsyncEchoServer2.class.getCanonicalName(); + + ProcessBuilder builder = new ProcessBuilder(javaBin, "-cp", classpath, className); + + return builder.start(); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoTest.java b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoTest.java new file mode 100644 index 0000000000..7ac388fb09 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncEchoTest.java @@ -0,0 +1,36 @@ +package com.baeldung.java.nio2.async; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class AsyncEchoTest { + + Process server; + AsyncEchoClient client; + + @Before + public void setup() throws IOException, InterruptedException { + server = AsyncEchoServer2.start(); + client = AsyncEchoClient.getInstance(); + } + + @Test + public void givenServerClient_whenServerEchosMessage_thenCorrect() { + String resp1 = client.sendMessage("hello"); + String resp2 = client.sendMessage("world"); + assertEquals("hello", resp1); + assertEquals("world", resp2); + } + + @After + public void teardown() throws IOException { + server.destroy(); + client.stop(); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncFileTest.java b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncFileTest.java new file mode 100644 index 0000000000..db30d32210 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/async/AsyncFileTest.java @@ -0,0 +1,130 @@ +package com.baeldung.java.nio2.async; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousFileChannel; +import java.nio.channels.CompletionHandler; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.UUID; +import java.util.concurrent.Future; + +import org.junit.Test; + +public class AsyncFileTest { + @Test + public void givenPath_whenReadsContentWithFuture_thenCorrect() throws IOException { + Path path = Paths.get(URI.create(new AsyncFileTest().getClass().getResource("/file.txt").toString())); + AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); + + ByteBuffer buffer = ByteBuffer.allocate(1024); + + Future operation = fileChannel.read(buffer, 0); + + while (!operation.isDone()) + ; + + String fileContent = new String(buffer.array()).trim(); + buffer.clear(); + + assertEquals(fileContent, "baeldung.com"); + } + + @Test + public void givenPath_whenReadsContentWithCompletionHandler_thenCorrect() throws IOException { + Path path = Paths.get(URI.create(new AsyncFileTest().getClass().getResource("/file.txt").toString())); + AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); + + ByteBuffer buffer = ByteBuffer.allocate(1024); + + fileChannel.read(buffer, 0, buffer, new CompletionHandler() { + + @Override + public void completed(Integer result, ByteBuffer attachment) { + // result is number of bytes read + // attachment is the buffer + + } + + @Override + public void failed(Throwable exc, ByteBuffer attachment) { + + } + }); + } + + @Test + public void givenPathAndContent_whenWritesToFileWithFuture_thenCorrect() throws IOException { + String fileName = UUID.randomUUID().toString(); + Path path = Paths.get(fileName); + AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE,StandardOpenOption.DELETE_ON_CLOSE); + + ByteBuffer buffer = ByteBuffer.allocate(1024); + long position = 0; + + buffer.put("hello world".getBytes()); + buffer.flip(); + + Future operation = fileChannel.write(buffer, position); + buffer.clear(); + + while (!operation.isDone()) { + + } + + String content = readContent(path); + assertEquals("hello world", content); + } + + @Test + public void givenPathAndContent_whenWritesToFileWithHandler_thenCorrect() throws IOException { + String fileName = UUID.randomUUID().toString(); + Path path = Paths.get(fileName); + AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE,StandardOpenOption.DELETE_ON_CLOSE); + + + ByteBuffer buffer = ByteBuffer.allocate(1024); + buffer.put("hello world".getBytes()); + buffer.flip(); + + fileChannel.write(buffer, 0, buffer, new CompletionHandler() { + + @Override + public void completed(Integer result, ByteBuffer attachment) { + // result is number of bytes written + // attachment is the buffer + + } + + @Override + public void failed(Throwable exc, ByteBuffer attachment) { + + } + }); + } + + public static String readContent(Path file) { + AsynchronousFileChannel fileChannel = null; + try { + fileChannel = AsynchronousFileChannel.open(file, StandardOpenOption.READ); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + ByteBuffer buffer = ByteBuffer.allocate(1024); + + Future operation = fileChannel.read(buffer, 0); + + while (!operation.isDone()) + ; + + String fileContent = new String(buffer.array()).trim(); + buffer.clear(); + return fileContent; + } +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsTest.java b/core-java/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsTest.java new file mode 100644 index 0000000000..dcc24c6415 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsTest.java @@ -0,0 +1,68 @@ +package com.baeldung.java.nio2.attributes; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; + +import org.junit.Before; +import org.junit.Test; + +public class BasicAttribsTest { + private static final String HOME = System.getProperty("user.home"); + BasicFileAttributes basicAttribs; + + @Before + public void setup() throws IOException { + Path home = Paths.get(HOME); + BasicFileAttributeView basicView = Files.getFileAttributeView(home, BasicFileAttributeView.class); + basicAttribs = basicView.readAttributes(); + } + + @Test + public void givenFileTimes_whenComparesThem_ThenCorrect() { + FileTime created = basicAttribs.creationTime(); + FileTime modified = basicAttribs.lastModifiedTime(); + FileTime accessed = basicAttribs.lastAccessTime(); + + assertTrue(0 > created.compareTo(accessed)); + assertTrue(0 < modified.compareTo(created)); + assertTrue(0 == created.compareTo(created)); + } + + @Test + public void givenPath_whenGetsFileSize_thenCorrect() { + long size = basicAttribs.size(); + assertTrue(size > 0); + } + + @Test + public void givenPath_whenChecksIfDirectory_thenCorrect() { + boolean isDir = basicAttribs.isDirectory(); + assertTrue(isDir); + } + + @Test + public void givenPath_whenChecksIfFile_thenCorrect() { + boolean isFile = basicAttribs.isRegularFile(); + assertFalse(isFile); + } + + @Test + public void givenPath_whenChecksIfSymLink_thenCorrect() { + boolean isSymLink = basicAttribs.isSymbolicLink(); + assertFalse(isSymLink); + } + + @Test + public void givenPath_whenChecksIfOther_thenCorrect() { + boolean isOther = basicAttribs.isOther(); + assertFalse(isOther); + } +} diff --git a/core-java/src/test/java/org/baeldung/java/collections/CollectionsConcatenateUnitTest.java b/core-java/src/test/java/org/baeldung/java/collections/CollectionsConcatenateUnitTest.java new file mode 100644 index 0000000000..3ee08767bd --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/collections/CollectionsConcatenateUnitTest.java @@ -0,0 +1,116 @@ +package org.baeldung.java.collections; + +import static java.util.Arrays.asList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +public class CollectionsConcatenateUnitTest { + + @Test + public void givenUsingJava8_whenConcatenatingUsingConcat_thenCorrect() { + Collection collectionA = asList("S", "T"); + Collection collectionB = asList("U", "V"); + Collection collectionC = asList("W", "X"); + + Stream combinedStream = Stream.concat(Stream.concat(collectionA.stream(), collectionB.stream()), collectionC.stream()); + Collection collectionCombined = combinedStream.collect(Collectors.toList()); + + Assert.assertEquals(asList("S", "T", "U", "V", "W", "X"), collectionCombined); + } + + @Test + public void givenUsingJava8_whenConcatenatingUsingflatMap_thenCorrect() { + Collection collectionA = asList("S", "T"); + Collection collectionB = asList("U", "V"); + + Stream combinedStream = Stream.of(collectionA, collectionB).flatMap(Collection::stream); + Collection collectionCombined = combinedStream.collect(Collectors.toList()); + + Assert.assertEquals(asList("S", "T", "U", "V"), collectionCombined); + } + + @Test + public void givenUsingGuava_whenConcatenatingUsingIterables_thenCorrect() { + Collection collectionA = asList("S", "T"); + Collection collectionB = asList("U", "V"); + + Iterable combinedIterables = Iterables.unmodifiableIterable(Iterables.concat(collectionA, collectionB)); + Collection collectionCombined = Lists.newArrayList(combinedIterables); + + Assert.assertEquals(asList("S", "T", "U", "V"), collectionCombined); + } + + @Test + public void givenUsingJava7_whenConcatenatingUsingIterables_thenCorrect() { + Collection collectionA = asList("S", "T"); + Collection collectionB = asList("U", "V"); + + Iterable combinedIterables = concat(collectionA, collectionB); + Collection collectionCombined = makeListFromIterable(combinedIterables); + Assert.assertEquals(Arrays.asList("S", "T", "U", "V"), collectionCombined); + } + + public static Iterable concat(Iterable list1, Iterable list2) { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { + protected Iterator listIterator = list1.iterator(); + protected Boolean checkedHasNext; + protected E nextValue; + private boolean startTheSecond; + + public void theNext() { + if (listIterator.hasNext()) { + checkedHasNext = true; + nextValue = listIterator.next(); + } else if (startTheSecond) + checkedHasNext = false; + else { + startTheSecond = true; + listIterator = list2.iterator(); + theNext(); + } + } + + public boolean hasNext() { + if (checkedHasNext == null) + theNext(); + return checkedHasNext; + } + + public E next() { + if (!hasNext()) + throw new NoSuchElementException(); + checkedHasNext = null; + return nextValue; + } + + public void remove() { + listIterator.remove(); + } + }; + } + }; + } + + public static List makeListFromIterable(Iterable iter) { + List list = new ArrayList(); + for (E item : iter) { + list.add(item); + } + return list; + } +} diff --git a/spring-core/pom.xml b/spring-core/pom.xml index 84a492bbe4..bf8c8f3ebc 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -47,6 +47,11 @@ 4.12 test + + com.google.guava + guava + 20.0 + diff --git a/spring-core/src/main/java/com/baeldung/constructordi/Config.java b/spring-core/src/main/java/com/baeldung/constructordi/Config.java new file mode 100644 index 0000000000..07568018f3 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/constructordi/Config.java @@ -0,0 +1,23 @@ +package com.baeldung.constructordi; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.constructordi.domain.Engine; +import com.baeldung.constructordi.domain.Transmission; + +@Configuration +@ComponentScan("com.baeldung.constructordi") +public class Config { + + @Bean + public Engine engine() { + return new Engine("v8", 5); + } + + @Bean + public Transmission transmission() { + return new Transmission("sliding"); + } +} diff --git a/spring-core/src/main/java/com/baeldung/constructordi/SpringRunner.java b/spring-core/src/main/java/com/baeldung/constructordi/SpringRunner.java new file mode 100644 index 0000000000..623739f036 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/constructordi/SpringRunner.java @@ -0,0 +1,31 @@ +package com.baeldung.constructordi; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import com.baeldung.constructordi.domain.Car; + +public class SpringRunner { + public static void main(String[] args) { + Car toyota = getCarFromXml(); + + System.out.println(toyota); + + toyota = getCarFromJavaConfig(); + + System.out.println(toyota); + } + + private static Car getCarFromJavaConfig() { + ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); + + return context.getBean(Car.class); + } + + private static Car getCarFromXml() { + ApplicationContext context = new ClassPathXmlApplicationContext("baeldung.xml"); + + return context.getBean(Car.class); + } +} diff --git a/spring-core/src/main/java/com/baeldung/constructordi/domain/Car.java b/spring-core/src/main/java/com/baeldung/constructordi/domain/Car.java new file mode 100644 index 0000000000..9f68ba5cd9 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/constructordi/domain/Car.java @@ -0,0 +1,21 @@ +package com.baeldung.constructordi.domain; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class Car { + private Engine engine; + private Transmission transmission; + + @Autowired + public Car(Engine engine, Transmission transmission) { + this.engine = engine; + this.transmission = transmission; + } + + @Override + public String toString() { + return String.format("Engine: %s Transmission: %s", engine, transmission); + } +} diff --git a/spring-core/src/main/java/com/baeldung/constructordi/domain/Engine.java b/spring-core/src/main/java/com/baeldung/constructordi/domain/Engine.java new file mode 100644 index 0000000000..f2987988eb --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/constructordi/domain/Engine.java @@ -0,0 +1,16 @@ +package com.baeldung.constructordi.domain; + +public class Engine { + private String type; + private int volume; + + public Engine(String type, int volume) { + this.type = type; + this.volume = volume; + } + + @Override + public String toString() { + return String.format("%s %d", type, volume); + } +} diff --git a/spring-core/src/main/java/com/baeldung/constructordi/domain/Transmission.java b/spring-core/src/main/java/com/baeldung/constructordi/domain/Transmission.java new file mode 100644 index 0000000000..85271e1f2a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/constructordi/domain/Transmission.java @@ -0,0 +1,14 @@ +package com.baeldung.constructordi.domain; + +public class Transmission { + private String type; + + public Transmission(String type) { + this.type = type; + } + + @Override + public String toString() { + return String.format("%s", type); + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/FactoryBeanAppConfig.java b/spring-core/src/main/java/com/baeldung/factorybean/FactoryBeanAppConfig.java new file mode 100644 index 0000000000..40e181b7a7 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/FactoryBeanAppConfig.java @@ -0,0 +1,26 @@ +package com.baeldung.factorybean; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FactoryBeanAppConfig { + + @Bean + public ToolFactory tool() { + ToolFactory factory = new ToolFactory(); + factory.setFactoryId(7070); + factory.setToolId(2); + factory.setToolName("wrench"); + factory.setToolPrice(3.7); + return factory; + } + + @Bean + public Worker worker() throws Exception { + Worker worker = new Worker(); + worker.setNumber("1002"); + worker.setTool(tool().getObject()); + return worker; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/InitializationToolFactory.java b/spring-core/src/main/java/com/baeldung/factorybean/InitializationToolFactory.java new file mode 100644 index 0000000000..15e2b01f49 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/InitializationToolFactory.java @@ -0,0 +1,68 @@ +package com.baeldung.factorybean; + +import static com.google.common.base.Preconditions.checkArgument; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.StringUtils; + +public class InitializationToolFactory implements FactoryBean, InitializingBean { + + private int factoryId; + private int toolId; + private String toolName; + private double toolPrice; + + @Override + public void afterPropertiesSet() throws Exception { + checkArgument(!StringUtils.isEmpty(toolName), "tool name cannot be empty"); + checkArgument(toolPrice >= 0, "tool price should not be less than 0"); + } + + @Override + public Tool getObject() throws Exception { + return new Tool(toolId, toolName, toolPrice); + } + + @Override + public Class getObjectType() { + return Tool.class; + } + + @Override + public boolean isSingleton() { + return false; + } + + public int getFactoryId() { + return factoryId; + } + + public void setFactoryId(int factoryId) { + this.factoryId = factoryId; + } + + public int getToolId() { + return toolId; + } + + public void setToolId(int toolId) { + this.toolId = toolId; + } + + public String getToolName() { + return toolName; + } + + public void setToolName(String toolName) { + this.toolName = toolName; + } + + public double getToolPrice() { + return toolPrice; + } + + public void setToolPrice(double toolPrice) { + this.toolPrice = toolPrice; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/NonSingleToolFactory.java b/spring-core/src/main/java/com/baeldung/factorybean/NonSingleToolFactory.java new file mode 100644 index 0000000000..158318649c --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/NonSingleToolFactory.java @@ -0,0 +1,57 @@ +package com.baeldung.factorybean; + +import org.springframework.beans.factory.config.AbstractFactoryBean; + +public class NonSingleToolFactory extends AbstractFactoryBean { + + private int factoryId; + private int toolId; + private String toolName; + private double toolPrice; + + public NonSingleToolFactory() { + setSingleton(false); + } + + @Override + public Class getObjectType() { + return Tool.class; + } + + @Override + protected Tool createInstance() throws Exception { + return new Tool(toolId, toolName, toolPrice); + } + + public int getFactoryId() { + return factoryId; + } + + public void setFactoryId(int factoryId) { + this.factoryId = factoryId; + } + + public int getToolId() { + return toolId; + } + + public void setToolId(int toolId) { + this.toolId = toolId; + } + + public String getToolName() { + return toolName; + } + + public void setToolName(String toolName) { + this.toolName = toolName; + } + + public double getToolPrice() { + return toolPrice; + } + + public void setToolPrice(double toolPrice) { + this.toolPrice = toolPrice; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/PostConstructToolFactory.java b/spring-core/src/main/java/com/baeldung/factorybean/PostConstructToolFactory.java new file mode 100644 index 0000000000..696545a70a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/PostConstructToolFactory.java @@ -0,0 +1,69 @@ +package com.baeldung.factorybean; + +import static com.google.common.base.Preconditions.checkArgument; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.util.StringUtils; + +public class PostConstructToolFactory implements FactoryBean { + + private int factoryId; + private int toolId; + private String toolName; + private double toolPrice; + + @Override + public Tool getObject() throws Exception { + return new Tool(toolId, toolName, toolPrice); + } + + @Override + public Class getObjectType() { + return Tool.class; + } + + @Override + public boolean isSingleton() { + return false; + } + + @PostConstruct + public void checkParams() { + checkArgument(!StringUtils.isEmpty(toolName), "tool name cannot be empty"); + checkArgument(toolPrice >= 0, "tool price should not be less than 0"); + } + + public int getFactoryId() { + return factoryId; + } + + public void setFactoryId(int factoryId) { + this.factoryId = factoryId; + } + + public int getToolId() { + return toolId; + } + + public void setToolId(int toolId) { + this.toolId = toolId; + } + + public String getToolName() { + return toolName; + } + + public void setToolName(String toolName) { + this.toolName = toolName; + } + + public double getToolPrice() { + return toolPrice; + } + + public void setToolPrice(double toolPrice) { + this.toolPrice = toolPrice; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/SingleToolFactory.java b/spring-core/src/main/java/com/baeldung/factorybean/SingleToolFactory.java new file mode 100644 index 0000000000..37fd978a3c --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/SingleToolFactory.java @@ -0,0 +1,54 @@ +package com.baeldung.factorybean; + +import org.springframework.beans.factory.config.AbstractFactoryBean; + +//no need to set singleton property because default value is true +public class SingleToolFactory extends AbstractFactoryBean { + + private int factoryId; + private int toolId; + private String toolName; + private double toolPrice; + + @Override + public Class getObjectType() { + return Tool.class; + } + + @Override + protected Tool createInstance() throws Exception { + return new Tool(toolId, toolName, toolPrice); + } + + public int getFactoryId() { + return factoryId; + } + + public void setFactoryId(int factoryId) { + this.factoryId = factoryId; + } + + public int getToolId() { + return toolId; + } + + public void setToolId(int toolId) { + this.toolId = toolId; + } + + public String getToolName() { + return toolName; + } + + public void setToolName(String toolName) { + this.toolName = toolName; + } + + public double getToolPrice() { + return toolPrice; + } + + public void setToolPrice(double toolPrice) { + this.toolPrice = toolPrice; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/Tool.java b/spring-core/src/main/java/com/baeldung/factorybean/Tool.java new file mode 100644 index 0000000000..2a69cbaf2a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/Tool.java @@ -0,0 +1,38 @@ +package com.baeldung.factorybean; + +public class Tool { + + private int id; + private String name; + private double price; + + public Tool(int id, String name, double price) { + this.id = id; + this.name = name; + this.price = price; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/ToolFactory.java b/spring-core/src/main/java/com/baeldung/factorybean/ToolFactory.java new file mode 100644 index 0000000000..5e6385c679 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/ToolFactory.java @@ -0,0 +1,58 @@ +package com.baeldung.factorybean; + +import org.springframework.beans.factory.FactoryBean; + +public class ToolFactory implements FactoryBean { + + private int factoryId; + private int toolId; + private String toolName; + private double toolPrice; + + @Override + public Tool getObject() throws Exception { + return new Tool(toolId, toolName, toolPrice); + } + + @Override + public Class getObjectType() { + return Tool.class; + } + + @Override + public boolean isSingleton() { + return false; + } + + public int getFactoryId() { + return factoryId; + } + + public void setFactoryId(int factoryId) { + this.factoryId = factoryId; + } + + public int getToolId() { + return toolId; + } + + public void setToolId(int toolId) { + this.toolId = toolId; + } + + public String getToolName() { + return toolName; + } + + public void setToolName(String toolName) { + this.toolName = toolName; + } + + public double getToolPrice() { + return toolPrice; + } + + public void setToolPrice(double toolPrice) { + this.toolPrice = toolPrice; + } +} diff --git a/spring-core/src/main/java/com/baeldung/factorybean/Worker.java b/spring-core/src/main/java/com/baeldung/factorybean/Worker.java new file mode 100644 index 0000000000..0d1dc5d7d6 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/factorybean/Worker.java @@ -0,0 +1,30 @@ +package com.baeldung.factorybean; + +public class Worker { + + private String number; + private Tool tool; + + public Worker() {} + + public Worker(String number, Tool tool) { + this.number = number; + this.tool = tool; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public Tool getTool() { + return tool; + } + + public void setTool(Tool tool) { + this.tool = tool; + } +} diff --git a/spring-core/src/main/resources/baeldung.xml b/spring-core/src/main/resources/baeldung.xml new file mode 100644 index 0000000000..d84492f1d4 --- /dev/null +++ b/spring-core/src/main/resources/baeldung.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/spring-core/src/main/resources/factorybean-abstract-spring-ctx.xml b/spring-core/src/main/resources/factorybean-abstract-spring-ctx.xml new file mode 100644 index 0000000000..33b3051cae --- /dev/null +++ b/spring-core/src/main/resources/factorybean-abstract-spring-ctx.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/main/resources/factorybean-init-spring-ctx.xml b/spring-core/src/main/resources/factorybean-init-spring-ctx.xml new file mode 100644 index 0000000000..1ff492e5df --- /dev/null +++ b/spring-core/src/main/resources/factorybean-init-spring-ctx.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/main/resources/factorybean-postconstruct-spring-ctx.xml b/spring-core/src/main/resources/factorybean-postconstruct-spring-ctx.xml new file mode 100644 index 0000000000..f34325160f --- /dev/null +++ b/spring-core/src/main/resources/factorybean-postconstruct-spring-ctx.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/main/resources/factorybean-spring-ctx.xml b/spring-core/src/main/resources/factorybean-spring-ctx.xml new file mode 100644 index 0000000000..2987b67d94 --- /dev/null +++ b/spring-core/src/main/resources/factorybean-spring-ctx.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/factorybean/AbstractFactoryBeanTest.java b/spring-core/src/test/java/com/baeldung/factorybean/AbstractFactoryBeanTest.java new file mode 100644 index 0000000000..a7ba6d9a68 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/factorybean/AbstractFactoryBeanTest.java @@ -0,0 +1,36 @@ +package com.baeldung.factorybean; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class AbstractFactoryBeanTest { + + @Test + public void testSingleToolFactory() { + ApplicationContext context = new ClassPathXmlApplicationContext("classpath:factorybean-abstract-spring-ctx.xml"); + + Worker worker1 = (Worker) context.getBean("worker1"); + Worker worker2 = (Worker) context.getBean("worker2"); + + assertThat(worker1.getNumber(), equalTo("50001")); + assertThat(worker2.getNumber(), equalTo("50002")); + assertTrue(worker1.getTool() == worker2.getTool()); + } + + @Test + public void testNonSingleToolFactory() { + ApplicationContext context = new ClassPathXmlApplicationContext("classpath:factorybean-abstract-spring-ctx.xml"); + + Worker worker3 = (Worker) context.getBean("worker3"); + Worker worker4 = (Worker) context.getBean("worker4"); + + assertThat(worker3.getNumber(), equalTo("50003")); + assertThat(worker4.getNumber(), equalTo("50004")); + assertTrue(worker3.getTool() != worker4.getTool()); + } +} diff --git a/spring-core/src/test/java/com/baeldung/factorybean/FactoryBeanInitializeTest.java b/spring-core/src/test/java/com/baeldung/factorybean/FactoryBeanInitializeTest.java new file mode 100644 index 0000000000..87947b148a --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/factorybean/FactoryBeanInitializeTest.java @@ -0,0 +1,18 @@ +package com.baeldung.factorybean; + +import org.junit.Test; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class FactoryBeanInitializeTest { + + @Test(expected = BeanCreationException.class) + public void testInitializationToolFactory() { + new ClassPathXmlApplicationContext("classpath:factorybean-init-spring-ctx.xml"); + } + + @Test(expected = BeanCreationException.class) + public void testPostConstructToolFactory() { + new ClassPathXmlApplicationContext("classpath:factorybean-postconstruct-spring-ctx.xml"); + } +} diff --git a/spring-core/src/test/java/com/baeldung/factorybean/FactoryBeanTest.java b/spring-core/src/test/java/com/baeldung/factorybean/FactoryBeanTest.java new file mode 100644 index 0000000000..f35503794a --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/factorybean/FactoryBeanTest.java @@ -0,0 +1,40 @@ +package com.baeldung.factorybean; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; + +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class FactoryBeanTest { + + @Test + public void testConstructWorkerByXml() { + ApplicationContext context = new ClassPathXmlApplicationContext("classpath:factorybean-spring-ctx.xml"); + + Worker worker = (Worker) context.getBean("worker"); + assertThat(worker.getNumber(), equalTo("1001")); + assertThat(worker.getTool().getId(), equalTo(1)); + assertThat(worker.getTool().getName(), equalTo("screwdriver")); + assertThat(worker.getTool().getPrice(), equalTo(1.5)); + + ToolFactory toolFactory = (ToolFactory) context.getBean("&tool"); + assertThat(toolFactory.getFactoryId(), equalTo(9090)); + } + + @Test + public void testConstructWorkerByJava() { + ApplicationContext context = new AnnotationConfigApplicationContext(FactoryBeanAppConfig.class); + + Worker worker = (Worker) context.getBean("worker"); + assertThat(worker.getNumber(), equalTo("1002")); + assertThat(worker.getTool().getId(), equalTo(2)); + assertThat(worker.getTool().getName(), equalTo("wrench")); + assertThat(worker.getTool().getPrice(), equalTo(3.7)); + + ToolFactory toolFactory = (ToolFactory) context.getBean("&tool"); + assertThat(toolFactory.getFactoryId(), equalTo(7070)); + } +} diff --git a/spring-mvc-xml/README.md b/spring-mvc-xml/README.md index 783bbb2ef4..e96a8d0392 100644 --- a/spring-mvc-xml/README.md +++ b/spring-mvc-xml/README.md @@ -12,3 +12,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Servlet Session Timeout](http://www.baeldung.com/servlet-session-timeout) - [Basic Forms with Spring MVC](http://www.baeldung.com/spring-mvc-form-tutorial) - [Returning Image/Media Data with Spring MVC](http://www.baeldung.com/spring-mvc-image-media-data) +- [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind) diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java index 0a292ab1e9..af3ce8cfb3 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java @@ -13,7 +13,7 @@ public class RawDBDemoGeoIPLocationService{ private DatabaseReader dbReader; public RawDBDemoGeoIPLocationService() throws IOException { - File database = new File("C:\\Users\\Parth Joshi\\Desktop\\GeoLite2-City.mmdb\\GeoLite2-City.mmdb"); + File database = new File("your-path-to-db-file"); dbReader = new DatabaseReader.Builder(database).build(); } diff --git a/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp b/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp index 431f6162bc..c2a60d5197 100644 --- a/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp +++ b/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp @@ -77,8 +77,8 @@
- - \ No newline at end of file diff --git a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java index 72d528095e..2edaa125b7 100644 --- a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java +++ b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java @@ -15,10 +15,10 @@ public class GeoIpIntegrationTest { @Test public void givenIP_whenFetchingCity_thenReturnsCityData() throws IOException, GeoIp2Exception { - File database = new File("C:\\Users\\Parth Joshi\\Desktop\\GeoLite2-City.mmdb\\GeoLite2-City.mmdb"); + File database = new File("your-path-to-db-file"); DatabaseReader dbReader = new DatabaseReader.Builder(database).build(); - InetAddress ipAddress = InetAddress.getByName("202.47.112.9"); + InetAddress ipAddress = InetAddress.getByName("your-public-ip"); CityResponse response = dbReader.city(ipAddress); String countryName = response.getCountry().getName(); diff --git a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java index 2c88408017..d5765b9756 100644 --- a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpFileUploadingLiveTest.java @@ -8,6 +8,7 @@ import java.io.File; import java.io.IOException; import org.baeldung.okhttp.ProgressRequestWrapper; +import org.junit.Before; import org.junit.Test; import okhttp3.Call; @@ -22,11 +23,16 @@ public class OkHttpFileUploadingLiveTest { private static final String BASE_URL = "http://localhost:8080/spring-rest"; + OkHttpClient client; + + @Before + public void init() { + client = new OkHttpClient(); + } + @Test public void whenUploadFile_thenCorrect() throws IOException { - OkHttpClient client = new OkHttpClient(); - RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", "file.txt", @@ -47,22 +53,17 @@ public class OkHttpFileUploadingLiveTest { @Test public void whenGetUploadFileProgress_thenCorrect() throws IOException { - OkHttpClient client = new OkHttpClient(); - RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", "file.txt", RequestBody.create(MediaType.parse("application/octet-stream"), new File("src/test/resources/test.txt"))) .build(); + ProgressRequestWrapper countingBody = new ProgressRequestWrapper(requestBody, (long bytesWritten, long contentLength) -> { - ProgressRequestWrapper.ProgressListener listener = (bytesWritten, contentLength) -> { - - float percentage = 100f * bytesWritten / contentLength; + float percentage = 100f * bytesWritten / contentLength; assertFalse(Float.compare(percentage, 100) > 0); - }; - - ProgressRequestWrapper countingBody = new ProgressRequestWrapper(requestBody, listener); + }); Request request = new Request.Builder() .url(BASE_URL + "/users/upload") diff --git a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java index 3f773bf35e..034833da0d 100644 --- a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpGetLiveTest.java @@ -1,26 +1,36 @@ package org.baeldung.okhttp; -import okhttp3.*; -import org.junit.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; import java.io.IOException; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; public class OkHttpGetLiveTest { private static final String BASE_URL = "http://localhost:8080/spring-rest"; + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + @Test public void whenGetRequest_thenCorrect() throws IOException { - - OkHttpClient client = new OkHttpClient(); - - Request request = new Request.Builder() - .url(BASE_URL + "/date") - .build(); + Request request = new Request.Builder().url(BASE_URL + "/date").build(); Call call = client.newCall(request); Response response = call.execute(); @@ -30,17 +40,12 @@ public class OkHttpGetLiveTest { @Test public void whenGetRequestWithQueryParameter_thenCorrect() throws IOException { - - OkHttpClient client = new OkHttpClient(); - HttpUrl.Builder urlBuilder = HttpUrl.parse(BASE_URL + "/ex/bars").newBuilder(); urlBuilder.addQueryParameter("id", "1"); String url = urlBuilder.build().toString(); - Request request = new Request.Builder() - .url(url) - .build(); + Request request = new Request.Builder().url(url).build(); Call call = client.newCall(request); Response response = call.execute(); @@ -50,12 +55,7 @@ public class OkHttpGetLiveTest { @Test public void whenAsynchronousGetRequest_thenCorrect() throws InterruptedException { - - OkHttpClient client = new OkHttpClient(); - - Request request = new Request.Builder() - .url(BASE_URL + "/date") - .build(); + Request request = new Request.Builder().url(BASE_URL + "/date").build(); Call call = client.newCall(request); @@ -65,7 +65,7 @@ public class OkHttpGetLiveTest { } public void onFailure(Call call, IOException e) { - fail(); + fail(); } }); diff --git a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java index 8eddfcb135..8888f7d4a7 100644 --- a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpHeaderLiveTest.java @@ -2,6 +2,7 @@ package org.baeldung.okhttp; import java.io.IOException; +import org.junit.Before; import org.junit.Test; import okhttp3.Call; @@ -13,11 +14,16 @@ public class OkHttpHeaderLiveTest { private static final String SAMPLE_URL = "http://www.github.com"; + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + @Test public void whenSetHeader_thenCorrect() throws IOException { - - OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder() .url(SAMPLE_URL) .addHeader("Content-Type", "application/json") @@ -31,7 +37,7 @@ public class OkHttpHeaderLiveTest { @Test public void whenSetDefaultHeader_thenCorrect() throws IOException { - OkHttpClient client = new OkHttpClient.Builder() + OkHttpClient clientWithInterceptor = new OkHttpClient.Builder() .addInterceptor(new DefaultContentTypeInterceptor("application/json")) .build(); @@ -39,10 +45,8 @@ public class OkHttpHeaderLiveTest { .url(SAMPLE_URL) .build(); - Call call = client.newCall(request); + Call call = clientWithInterceptor.newCall(request); Response response = call.execute(); response.close(); } - - } diff --git a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java index 9c38c8da51..34e1554908 100644 --- a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpMiscLiveTest.java @@ -4,22 +4,37 @@ import okhttp3.*; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.io.File; import java.io.IOException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import okhttp3.Cache; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; public class OkHttpMiscLiveTest { private static final String BASE_URL = "http://localhost:8080/spring-rest"; private static Logger logger = LoggerFactory.getLogger(OkHttpMiscLiveTest.class); + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + @Test public void whenSetRequestTimeout_thenFail() throws IOException { - - OkHttpClient client = new OkHttpClient.Builder() + OkHttpClient clientWithTimeout = new OkHttpClient.Builder() .readTimeout(1, TimeUnit.SECONDS) .build(); @@ -27,18 +42,15 @@ public class OkHttpMiscLiveTest { .url(BASE_URL + "/delay/2") // This URL is served with a 2 second delay. .build(); - Call call = client.newCall(request); + Call call = clientWithTimeout.newCall(request); Response response = call.execute(); response.close(); } @Test(expected = IOException.class) public void whenCancelRequest_thenCorrect() throws IOException { - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); - OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder() .url(BASE_URL + "/delay/2") // This URL is served with a 2 second delay. .build(); @@ -69,7 +81,7 @@ public class OkHttpMiscLiveTest { File cacheDirectory = new File("src/test/resources/cache"); Cache cache = new Cache(cacheDirectory, cacheSize); - OkHttpClient client = new OkHttpClient.Builder() + OkHttpClient clientCached = new OkHttpClient.Builder() .cache(cache) .build(); @@ -77,10 +89,10 @@ public class OkHttpMiscLiveTest { .url("http://publicobject.com/helloworld.txt") .build(); - Response response1 = client.newCall(request).execute(); + Response response1 = clientCached.newCall(request).execute(); logResponse(response1); - Response response2 = client.newCall(request).execute(); + Response response2 = clientCached.newCall(request).execute(); logResponse(response2); } diff --git a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java index 18bd4cdcb3..dce3bb174f 100644 --- a/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java +++ b/spring-rest/src/test/java/org/baeldung/okhttp/OkHttpPostingLiveTest.java @@ -6,6 +6,7 @@ import static org.junit.Assert.assertThat; import java.io.File; import java.io.IOException; +import org.junit.Before; import org.junit.Test; import okhttp3.Call; @@ -23,11 +24,16 @@ public class OkHttpPostingLiveTest { private static final String BASE_URL = "http://localhost:8080/spring-rest"; private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php"; + OkHttpClient client; + + @Before + public void init() { + + client = new OkHttpClient(); + } + @Test public void whenSendPostRequest_thenCorrect() throws IOException { - - OkHttpClient client = new OkHttpClient(); - RequestBody formBody = new FormBody.Builder() .add("username", "test") .add("password", "test") @@ -46,11 +52,8 @@ public class OkHttpPostingLiveTest { @Test public void whenSendPostRequestWithAuthorization_thenCorrect() throws IOException { - String postBody = "test post"; - OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder() .url(URL_SECURED_BY_BASIC_AUTHENTICATION) .addHeader("Authorization", Credentials.basic("test", "test")) @@ -65,9 +68,6 @@ public class OkHttpPostingLiveTest { @Test public void whenPostJson_thenCorrect() throws IOException { - - OkHttpClient client = new OkHttpClient(); - String json = "{\"id\":1,\"name\":\"John\"}"; RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json); @@ -85,9 +85,6 @@ public class OkHttpPostingLiveTest { @Test public void whenSendMultipartRequest_thenCorrect() throws IOException { - - OkHttpClient client = new OkHttpClient(); - RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("username", "test") diff --git a/spring-rest/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java b/spring-rest/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java new file mode 100644 index 0000000000..4b6a9ba312 --- /dev/null +++ b/spring-rest/src/test/java/org/baeldung/uribuilder/SpringUriBuilderTest.java @@ -0,0 +1,53 @@ +package org.baeldung.uribuilder; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.junit.Test; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +public class SpringUriBuilderTest { + + @Test + public void constructUri() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.baeldung.com") + .path("/junit-5").build(); + + assertEquals("http://www.baeldung.com/junit-5", uriComponents.toUriString()); + } + + @Test + public void constructUriEncoded() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.baeldung.com") + .path("/junit 5").build().encode(); + + assertEquals("http://www.baeldung.com/junit%205", uriComponents.toUriString()); + } + + @Test + public void constructUriFromTemplate() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.baeldung.com") + .path("/{article-name}").buildAndExpand("junit-5"); + + assertEquals("http://www.baeldung.com/junit-5", uriComponents.toUriString()); + } + + @Test + public void constructUriWithQueryParameter() { + UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("www.google.com") + .path("/").query("q={keyword}").buildAndExpand("baeldung"); + + assertEquals("http://www.google.com/?q=baeldung", uriComponents.toUriString()); + } + + @Test + public void expandWithRegexVar() { + String template = "/myurl/{name:[a-z]{1,5}}/show"; + UriComponents uriComponents = UriComponentsBuilder.fromUriString(template).build(); + uriComponents = uriComponents.expand(Collections.singletonMap("name", "test")); + + assertEquals("/myurl/test/show", uriComponents.getPath()); + } +} diff --git a/spring-security-basic-auth/src/main/java/org/baeldung/security/filter/configuration/CustomWebSecurityConfigurerAdapter.java b/spring-security-basic-auth/src/main/java/org/baeldung/security/filter/configuration/CustomWebSecurityConfigurerAdapter.java index 468c99cb2a..1901489305 100644 --- a/spring-security-basic-auth/src/main/java/org/baeldung/security/filter/configuration/CustomWebSecurityConfigurerAdapter.java +++ b/spring-security-basic-auth/src/main/java/org/baeldung/security/filter/configuration/CustomWebSecurityConfigurerAdapter.java @@ -1,17 +1,40 @@ package org.baeldung.security.filter.configuration; +import org.baeldung.security.basic.MyBasicAuthenticationEntryPoint; import org.baeldung.security.filter.CustomFilter; +import org.springframework.beans.factory.annotation.Autowired; 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.web.authentication.www.BasicAuthenticationFilter; @Configuration +@EnableWebSecurity public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + @Autowired + private MyBasicAuthenticationEntryPoint authenticationEntryPoint; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) + throws Exception { + auth + .inMemoryAuthentication() + .withUser("user1").password("user1Pass") + .authorities("ROLE_USER"); + } @Override protected void configure(HttpSecurity http) throws Exception { - http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); - } + http.authorizeRequests() + .antMatchers("/securityNone").permitAll() + .anyRequest().authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint); + http.addFilterAfter(new CustomFilter(), + BasicAuthenticationFilter.class); + } } diff --git a/spring-security-basic-auth/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/spring-security-basic-auth/src/main/java/org/baeldung/spring/SecSecurityConfig.java index 4ce80dab9f..5aa14c1051 100644 --- a/spring-security-basic-auth/src/main/java/org/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-basic-auth/src/main/java/org/baeldung/spring/SecSecurityConfig.java @@ -2,11 +2,10 @@ package org.baeldung.spring; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; @Configuration -@ImportResource({ "classpath:webSecurityConfig.xml" }) @ComponentScan("org.baeldung.security") +//@ImportResource({ "classpath:webSecurityConfig.xml" }) public class SecSecurityConfig { public SecSecurityConfig() { diff --git a/spring-security-client/README.MD b/spring-security-client/README.MD index 5ac974203b..0b0af7ffe1 100644 --- a/spring-security-client/README.MD +++ b/spring-security-client/README.MD @@ -1,2 +1,11 @@ -###The Course +========= +## Spring Security Authentication/Authorization Example Project + +##The Course The "REST With Spring" Classes: http://github.learnspringsecurity.com + +### Relevant Articles: +- [Spring Security Manual Authentication](http://www.baeldung.com/spring-security-authentication) + +### Build the Project +mvn clean install diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java index 9ade60e54c..259433f6ae 100644 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java @@ -8,9 +8,11 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.context.annotation.Profile; @Configuration @EnableWebMvc +@Profile("!manual") public class MvcConfig extends WebMvcConfigurerAdapter { public MvcConfig() { diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfigManual.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfigManual.java new file mode 100644 index 0000000000..d80527c30a --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfigManual.java @@ -0,0 +1,22 @@ +package org.baeldung.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@Configuration +@EnableWebMvc +@Profile("manual") +public class MvcConfigManual extends WebMvcConfigurerAdapter { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/home").setViewName("home"); + registry.addViewController("/").setViewName("home"); + registry.addViewController("/hello").setViewName("hello"); + registry.addViewController("/login").setViewName("login"); + } + +} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/RegistrationController.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/RegistrationController.java new file mode 100644 index 0000000000..025001ac44 --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/RegistrationController.java @@ -0,0 +1,92 @@ +package org.baeldung.config; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.context.annotation.Profile; + +/** + * Manually authenticate a user using Spring Security / Spring Web MVC' (upon successful account registration) + * (http://stackoverflow.com/questions/4664893/how-to-manually-set-an-authenticated-user-in-spring-security-springmvc) + * + * @author jim clayson + */ +@Controller +@Profile("manual") +public class RegistrationController { + private static final Logger logger = LoggerFactory.getLogger(RegistrationController.class); + + @Autowired + AuthenticationManager authenticationManager; + + /** + * For demo purposes this need only be a GET request method + * + * @param request + * @param response + * @return The view. Page confirming either successful registration (and/or + * successful authentication) or failed registration. + */ + @RequestMapping(value = "/register", method = RequestMethod.GET) + public String registerAndAuthenticate(HttpServletRequest request, HttpServletResponse response) { + logger.debug("registerAndAuthenticate: attempt to register, application should manually authenticate."); + + // Mocked values. Potentially could come from an HTML registration form, + // in which case this mapping would match on an HTTP POST, rather than a GET + String username = "user"; + String password = "password"; + + String view = "registrationSuccess"; + + if (requestQualifiesForManualAuthentication()) { + try { + authenticate(username, password, request, response); + logger.debug("registerAndAuthenticate: authentication completed."); + } catch (BadCredentialsException bce) { + logger.debug("Authentication failure: bad credentials"); + bce.printStackTrace(); + view = "systemError"; // assume a low-level error, since the registration + // form would have been successfully validated + } + } + + return view; + } + + private boolean requestQualifiesForManualAuthentication() { + // Some processing to determine that the user requires a Spring Security-recognized, + // application-directed login e.g. successful account registration. + return true; + } + + private void authenticate(String username, String password, HttpServletRequest request, HttpServletResponse response) throws BadCredentialsException { + logger.debug("attempting to authenticated, manually ... "); + + // create and populate the token + AbstractAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password); + authToken.setDetails(new WebAuthenticationDetails(request)); + + // This call returns an authentication object, which holds principle and user credentials + Authentication authentication = this.authenticationManager.authenticate(authToken); + + // The security context holds the authentication object, and is stored + // in thread local scope. + SecurityContextHolder.getContext().setAuthentication(authentication); + + logger.debug("User should now be authenticated."); + } + +} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java index bd6c56d38a..153cc67661 100644 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java @@ -6,9 +6,11 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.context.annotation.Profile; @Configuration @EnableWebSecurity +@Profile("!manual") public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/WebSecurityConfigManual.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/WebSecurityConfigManual.java new file mode 100644 index 0000000000..180a53deba --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/WebSecurityConfigManual.java @@ -0,0 +1,35 @@ +package org.baeldung.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +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 +@Profile("manual") +public class WebSecurityConfigManual extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeRequests() + .antMatchers("/", "/home", "/register").permitAll() + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login").permitAll() + .and() + .logout().permitAll(); + // @formatter:on + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); + } +} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/hello.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/hello.html new file mode 100644 index 0000000000..b37731b0ed --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/hello.html @@ -0,0 +1,15 @@ + + + + Hello World! + + +

Hello [[${#httpServletRequest.remoteUser}]]!

+
+ +
+

Click here to go to the home page.

+ + + \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/home.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/home.html new file mode 100644 index 0000000000..6dbdf491c6 --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/home.html @@ -0,0 +1,15 @@ + + + + Spring Security Example + + +

Welcome!

+ +

Click here to see a greeting.

+

Click here to send a dummy registration request, where the application logs you in.

+ + \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/login.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/login.html new file mode 100644 index 0000000000..3f28efac69 --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/login.html @@ -0,0 +1,21 @@ + + + + Spring Security Example + + +
+ Invalid username and password. +
+
+ You have been logged out. +
+
+
+
+
+
+

Click here to go to the home page.

+ + \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationError.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationError.html new file mode 100644 index 0000000000..756cc2390d --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationError.html @@ -0,0 +1 @@ +Registration could not be completed at this time. Please try again later or contact support! \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationSuccess.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationSuccess.html new file mode 100644 index 0000000000..b1c4336f2f --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationSuccess.html @@ -0,0 +1,15 @@ + + + + Registration Success! + + +

Registration succeeded. You have been logged in by the system. Welcome [[${#httpServletRequest.remoteUser}]]!

+
+ +
+

Click here to go to the home page.

+ + + \ No newline at end of file