Merge branch 'master' into geroza/BAEL-14138_update-and-move-Spring-HAETOAS-article
This commit is contained in:
commit
86d4c0b0d9
|
@ -19,6 +19,7 @@
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
*.iws
|
*.iws
|
||||||
|
out/
|
||||||
|
|
||||||
# Mac
|
# Mac
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
@ -27,6 +28,9 @@
|
||||||
log/
|
log/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.gradle/
|
||||||
|
|
||||||
spring-openid/src/main/resources/application.properties
|
spring-openid/src/main/resources/application.properties
|
||||||
.recommenders/
|
.recommenders/
|
||||||
/spring-hibernate4/nbproject/
|
/spring-hibernate4/nbproject/
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Groovy
|
||||||
|
|
||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [String Matching in Groovy](http://www.baeldung.com/)
|
||||||
|
- [Groovy def Keyword]
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>core-groovy-2</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>core-groovy-2</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
|
<artifactId>groovy</artifactId>
|
||||||
|
<version>${groovy.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
|
<artifactId>groovy-all</artifactId>
|
||||||
|
<version>${groovy-all.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
|
<artifactId>groovy-dateutil</artifactId>
|
||||||
|
<version>${groovy.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
|
<artifactId>groovy-sql</artifactId>
|
||||||
|
<version>${groovy-sql.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<version>${hsqldb.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>${spock-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.gmavenplus</groupId>
|
||||||
|
<artifactId>gmavenplus-plugin</artifactId>
|
||||||
|
<version>${gmavenplus-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>addSources</goal>
|
||||||
|
<goal>addTestSources</goal>
|
||||||
|
<goal>compile</goal>
|
||||||
|
<goal>compileTests</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<version>${maven-failsafe-plugin.version}</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>junit5</id>
|
||||||
|
<goals>
|
||||||
|
<goal>integration-test</goal>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Test5.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.20.1</version>
|
||||||
|
<configuration>
|
||||||
|
<useFile>false</useFile>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Test.java</include>
|
||||||
|
<include>**/*Spec.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>central</id>
|
||||||
|
<url>http://jcenter.bintray.com</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<junit.platform.version>1.0.0</junit.platform.version>
|
||||||
|
<groovy.version>2.5.6</groovy.version>
|
||||||
|
<groovy-all.version>2.5.6</groovy-all.version>
|
||||||
|
<groovy-sql.version>2.5.6</groovy-sql.version>
|
||||||
|
<hsqldb.version>2.4.0</hsqldb.version>
|
||||||
|
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
||||||
|
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.baeldung.defkeyword
|
||||||
|
|
||||||
|
import org.codehaus.groovy.runtime.NullObject
|
||||||
|
import org.codehaus.groovy.runtime.typehandling.GroovyCastException
|
||||||
|
|
||||||
|
import groovy.transform.TypeChecked
|
||||||
|
import groovy.transform.TypeCheckingMode
|
||||||
|
|
||||||
|
@TypeChecked
|
||||||
|
class DefUnitTest extends GroovyTestCase {
|
||||||
|
|
||||||
|
def id
|
||||||
|
def firstName = "Samwell"
|
||||||
|
def listOfCountries = ['USA', 'UK', 'FRANCE', 'INDIA']
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
def multiply(x, y) {
|
||||||
|
return x*y
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
void testDefVariableDeclaration() {
|
||||||
|
|
||||||
|
def list
|
||||||
|
assert list.getClass() == org.codehaus.groovy.runtime.NullObject
|
||||||
|
assert list.is(null)
|
||||||
|
|
||||||
|
list = [1,2,4]
|
||||||
|
assert list instanceof ArrayList
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
void testTypeVariables() {
|
||||||
|
int rate = 200
|
||||||
|
try {
|
||||||
|
rate = [12] //GroovyCastException
|
||||||
|
rate = "nill" //GroovyCastException
|
||||||
|
} catch(GroovyCastException) {
|
||||||
|
println "Cannot assign anything other than integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
void testDefVariableMultipleAssignment() {
|
||||||
|
def rate
|
||||||
|
assert rate == null
|
||||||
|
assert rate.getClass() == org.codehaus.groovy.runtime.NullObject
|
||||||
|
|
||||||
|
rate = 12
|
||||||
|
assert rate instanceof Integer
|
||||||
|
|
||||||
|
rate = "Not Available"
|
||||||
|
assert rate instanceof String
|
||||||
|
|
||||||
|
rate = [1, 4]
|
||||||
|
assert rate instanceof List
|
||||||
|
|
||||||
|
assert divide(12, 3) instanceof BigDecimal
|
||||||
|
assert divide(1, 0) instanceof String
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def divide(int x, int y) {
|
||||||
|
if(y==0) {
|
||||||
|
return "Should not divide by 0"
|
||||||
|
} else {
|
||||||
|
return x/y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def greetMsg() {
|
||||||
|
println "Hello! I am Groovy"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testDefVsType() {
|
||||||
|
def int count
|
||||||
|
assert count instanceof Integer
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.strings
|
||||||
|
|
||||||
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
class StringMatchingSpec extends Specification {
|
||||||
|
|
||||||
|
def "pattern operator example"() {
|
||||||
|
given: "a pattern"
|
||||||
|
def p = ~'foo'
|
||||||
|
|
||||||
|
expect:
|
||||||
|
p instanceof Pattern
|
||||||
|
|
||||||
|
and: "you can use slash strings to avoid escaping of blackslash"
|
||||||
|
def digitPattern = ~/\d*/
|
||||||
|
digitPattern.matcher('4711').matches()
|
||||||
|
}
|
||||||
|
|
||||||
|
def "match operator example"() {
|
||||||
|
expect:
|
||||||
|
'foobar' ==~ /.*oba.*/
|
||||||
|
|
||||||
|
and: "matching is strict"
|
||||||
|
!('foobar' ==~ /foo/)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "find operator example"() {
|
||||||
|
when: "using the find operator"
|
||||||
|
def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/
|
||||||
|
|
||||||
|
then: "will find groups"
|
||||||
|
matcher.size() == 2
|
||||||
|
|
||||||
|
and: "can access groups using array"
|
||||||
|
matcher[0][0] == 'foo and bar'
|
||||||
|
matcher[1][2] == 'buz'
|
||||||
|
|
||||||
|
and: "you can use it as a predicate"
|
||||||
|
'foobarbaz' =~ /bar/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package com.baeldung;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit test for simple App.
|
|
||||||
*/
|
|
||||||
public class UnitTest {
|
|
||||||
/**
|
|
||||||
* Stub test
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void givenPreconditions_whenCondition_shouldResult() {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
package com.baeldung.filechannel;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.MappedByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.FileLock;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class FileChannelUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException {
|
||||||
|
|
||||||
|
try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
|
||||||
|
FileChannel channel = reader.getChannel();
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();) {
|
||||||
|
|
||||||
|
int bufferSize = 1024;
|
||||||
|
if (bufferSize > channel.size()) {
|
||||||
|
bufferSize = (int) channel.size();
|
||||||
|
}
|
||||||
|
ByteBuffer buff = ByteBuffer.allocate(bufferSize);
|
||||||
|
|
||||||
|
while (channel.read(buff) > 0) {
|
||||||
|
out.write(buff.array(), 0, buff.position());
|
||||||
|
buff.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
assertEquals("Hello world", fileContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException {
|
||||||
|
|
||||||
|
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
FileInputStream fin = new FileInputStream("src/test/resources/test_read.in");
|
||||||
|
FileChannel channel = fin.getChannel();) {
|
||||||
|
|
||||||
|
int bufferSize = 1024;
|
||||||
|
if (bufferSize > channel.size()) {
|
||||||
|
bufferSize = (int) channel.size();
|
||||||
|
}
|
||||||
|
ByteBuffer buff = ByteBuffer.allocate(bufferSize);
|
||||||
|
|
||||||
|
while (channel.read(buff) > 0) {
|
||||||
|
out.write(buff.array(), 0, buff.position());
|
||||||
|
buff.clear();
|
||||||
|
}
|
||||||
|
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
assertEquals("Hello world", fileContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException {
|
||||||
|
|
||||||
|
try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
|
||||||
|
FileChannel channel = reader.getChannel();
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();) {
|
||||||
|
|
||||||
|
MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5);
|
||||||
|
|
||||||
|
if (buff.hasRemaining()) {
|
||||||
|
byte[] data = new byte[buff.remaining()];
|
||||||
|
buff.get(data);
|
||||||
|
assertEquals("world", new String(data, StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException {
|
||||||
|
String file = "src/test/resources/test_write_using_filechannel.txt";
|
||||||
|
try (RandomAccessFile writer = new RandomAccessFile(file, "rw");
|
||||||
|
FileChannel channel = writer.getChannel();) {
|
||||||
|
ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
channel.write(buff);
|
||||||
|
|
||||||
|
// now we verify whether the file was written correctly
|
||||||
|
RandomAccessFile reader = new RandomAccessFile(file, "r");
|
||||||
|
assertEquals("Hello world", reader.readLine());
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException {
|
||||||
|
try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw");
|
||||||
|
FileChannel channel = reader.getChannel();
|
||||||
|
FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) {
|
||||||
|
|
||||||
|
assertNotNull(fileLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException {
|
||||||
|
|
||||||
|
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
|
||||||
|
FileChannel channel = reader.getChannel();) {
|
||||||
|
|
||||||
|
int bufferSize = 1024;
|
||||||
|
if (bufferSize > channel.size()) {
|
||||||
|
bufferSize = (int) channel.size();
|
||||||
|
}
|
||||||
|
ByteBuffer buff = ByteBuffer.allocate(bufferSize);
|
||||||
|
|
||||||
|
while (channel.read(buff) > 0) {
|
||||||
|
out.write(buff.array(), 0, buff.position());
|
||||||
|
buff.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the original file is 11 bytes long, so that's where the position pointer should be
|
||||||
|
assertEquals(11, channel.position());
|
||||||
|
|
||||||
|
channel.position(4);
|
||||||
|
assertEquals(4, channel.position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetFileSize_thenCorrect() throws IOException {
|
||||||
|
|
||||||
|
try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
|
||||||
|
FileChannel channel = reader.getChannel();) {
|
||||||
|
|
||||||
|
// the original file is 11 bytes long, so that's where the position pointer should be
|
||||||
|
assertEquals(11, channel.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTruncateFile_thenCorrect() throws IOException {
|
||||||
|
String input = "this is a test input";
|
||||||
|
|
||||||
|
FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt");
|
||||||
|
FileChannel channel = fout.getChannel();
|
||||||
|
|
||||||
|
ByteBuffer buff = ByteBuffer.wrap(input.getBytes());
|
||||||
|
channel.write(buff);
|
||||||
|
buff.flip();
|
||||||
|
|
||||||
|
channel = channel.truncate(5);
|
||||||
|
assertEquals(5, channel.size());
|
||||||
|
|
||||||
|
fout.close();
|
||||||
|
channel.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
this
|
|
@ -0,0 +1 @@
|
||||||
|
Hello world
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Entry {
|
||||||
|
private String data;
|
||||||
|
private int rank;
|
||||||
|
|
||||||
|
// non-generic constructor
|
||||||
|
public Entry(String data, int rank) {
|
||||||
|
this.data = data;
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic constructor
|
||||||
|
public <E extends Rankable & Serializable> Entry(E element) {
|
||||||
|
this.data = element.toString();
|
||||||
|
this.rank = element.getRank();
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters and setters
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRank() {
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRank(int rank) {
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class GenericEntry<T> {
|
||||||
|
private T data;
|
||||||
|
private int rank;
|
||||||
|
|
||||||
|
// non-generic constructor
|
||||||
|
public GenericEntry(int rank) {
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic constructor
|
||||||
|
public GenericEntry(T data, int rank) {
|
||||||
|
this.data = data;
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic constructor with different type
|
||||||
|
public <E extends Rankable & Serializable> GenericEntry(E element) {
|
||||||
|
this.data = (T) element;
|
||||||
|
this.rank = element.getRank();
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic constructor with different type and wild card
|
||||||
|
public GenericEntry(Optional<? extends Rankable> optional) {
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
this.data = (T) optional.get();
|
||||||
|
this.rank = optional.get()
|
||||||
|
.getRank();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters and setters
|
||||||
|
public T getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(T data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRank() {
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRank(int rank) {
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
public class MapEntry<K, V> {
|
||||||
|
private K key;
|
||||||
|
private V value;
|
||||||
|
|
||||||
|
public MapEntry() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic constructor with two parameters
|
||||||
|
public MapEntry(K key, V value) {
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters and setters
|
||||||
|
public K getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(K key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(V value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Product implements Rankable, Serializable {
|
||||||
|
private String name;
|
||||||
|
private double price;
|
||||||
|
private int sales;
|
||||||
|
|
||||||
|
public Product(String name, double price) {
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRank() {
|
||||||
|
return sales;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Product [name=" + name + ", price=" + price + ", sales=" + sales + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters and setters
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSales() {
|
||||||
|
return sales;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSales(int sales) {
|
||||||
|
this.sales = sales;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
public interface Rankable {
|
||||||
|
public int getRank();
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.baeldung.generics;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class GenericConstructorUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK() {
|
||||||
|
Entry entry = new Entry("sample", 1);
|
||||||
|
|
||||||
|
assertEquals("sample", entry.getData());
|
||||||
|
assertEquals(1, entry.getRank());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK() {
|
||||||
|
Product product = new Product("milk", 2.5);
|
||||||
|
product.setSales(30);
|
||||||
|
Entry entry = new Entry(product);
|
||||||
|
|
||||||
|
assertEquals(product.toString(), entry.getData());
|
||||||
|
assertEquals(30, entry.getRank());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK() {
|
||||||
|
GenericEntry<String> entry = new GenericEntry<String>(1);
|
||||||
|
|
||||||
|
assertNull(entry.getData());
|
||||||
|
assertEquals(1, entry.getRank());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGenericConstructor_whenCreateGenericEntry_thenOK() {
|
||||||
|
GenericEntry<String> entry = new GenericEntry<String>("sample", 1);
|
||||||
|
|
||||||
|
assertEquals("sample", entry.getData());
|
||||||
|
assertEquals(1, entry.getRank());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK() {
|
||||||
|
Product product = new Product("milk", 2.5);
|
||||||
|
product.setSales(30);
|
||||||
|
GenericEntry<Serializable> entry = new GenericEntry<Serializable>(product);
|
||||||
|
|
||||||
|
assertEquals(product, entry.getData());
|
||||||
|
assertEquals(30, entry.getRank());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK() {
|
||||||
|
Product product = new Product("milk", 2.5);
|
||||||
|
product.setSales(30);
|
||||||
|
Optional<Product> optional = Optional.of(product);
|
||||||
|
GenericEntry<Serializable> entry = new GenericEntry<Serializable>(optional);
|
||||||
|
|
||||||
|
assertEquals(product, entry.getData());
|
||||||
|
assertEquals(30, entry.getRank());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK() {
|
||||||
|
MapEntry<String, Integer> entry = new MapEntry<String, Integer>("sample", 1);
|
||||||
|
|
||||||
|
assertEquals("sample", entry.getKey());
|
||||||
|
assertEquals(1, entry.getValue()
|
||||||
|
.intValue());
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.2.41'
|
ext.kotlin_version = '1.3.30'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -26,8 +26,6 @@ sourceCompatibility = 1.8
|
||||||
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
|
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
|
||||||
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
|
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
|
||||||
|
|
||||||
kotlin { experimental { coroutines "enable" } }
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
@ -39,10 +37,22 @@ sourceSets {
|
||||||
srcDirs 'com/baeldung/ktor'
|
srcDirs 'com/baeldung/ktor'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
testLogging {
|
||||||
|
events "passed", "skipped", "failed"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "ch.qos.logback:logback-classic:1.2.1"
|
implementation "ch.qos.logback:logback-classic:1.2.1"
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
|
||||||
}
|
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
testImplementation 'org.assertj:assertj-core:3.12.2'
|
||||||
|
testImplementation 'org.mockito:mockito-core:2.27.0'
|
||||||
|
testImplementation "org.jetbrains.kotlin:kotlin-test:${kotlin_version}"
|
||||||
|
testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:${kotlin_version}"
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
|
|
||||||
|
|
|
@ -1,5 +1,21 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
## Gradle start up script for UN*X
|
## Gradle start up script for UN*X
|
||||||
|
@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS=""
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
|
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS=
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
|
@ -20,9 +20,21 @@
|
||||||
<version>${kotlin.version}</version>
|
<version>${kotlin.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.platform</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-platform-runner</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<version>${junit.platform.version}</version>
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy</artifactId>
|
||||||
|
<version>${byte-buddy.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -37,6 +49,12 @@
|
||||||
<version>${kotlin.version}</version>
|
<version>${kotlin.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-test-junit5</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -69,10 +87,11 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<kotlin.version>1.2.71</kotlin.version>
|
<kotlin.version>1.3.30</kotlin.version>
|
||||||
<junit.platform.version>1.1.1</junit.platform.version>
|
<junit.jupiter.version>5.4.2</junit.jupiter.version>
|
||||||
<junit.vintage.version>5.2.0</junit.vintage.version>
|
<mockito.version>2.27.0</mockito.version>
|
||||||
|
<byte-buddy.version>1.9.12</byte-buddy.version>
|
||||||
<assertj.version>3.10.0</assertj.version>
|
<assertj.version>3.10.0</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.baeldung.console
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.mockito.Mockito.`when`
|
||||||
|
import org.mockito.Mockito.mock
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.Console
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.io.PrintStream
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleIOUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenText_whenPrint_thenPrintText() {
|
||||||
|
val expectedTest = "Hello from Kotlin"
|
||||||
|
val out = ByteArrayOutputStream()
|
||||||
|
System.setOut(PrintStream(out))
|
||||||
|
|
||||||
|
print(expectedTest)
|
||||||
|
out.flush()
|
||||||
|
val printedText = String(out.toByteArray())
|
||||||
|
|
||||||
|
assertThat(printedText).isEqualTo(expectedTest)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenInput_whenRead_thenReadText() {
|
||||||
|
val expectedTest = "Hello from Kotlin"
|
||||||
|
val input = ByteArrayInputStream(expectedTest.toByteArray())
|
||||||
|
System.setIn(input)
|
||||||
|
|
||||||
|
val readText = readLine()
|
||||||
|
|
||||||
|
assertThat(readText).isEqualTo(expectedTest)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenInput_whenReadWithScanner_thenReadText() {
|
||||||
|
val expectedTest = "Hello from Kotlin"
|
||||||
|
val scanner = Scanner(ByteArrayInputStream(expectedTest.toByteArray()))
|
||||||
|
|
||||||
|
val readText = scanner.nextLine()
|
||||||
|
|
||||||
|
assertThat(readText).isEqualTo(expectedTest)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenInput_whenReadWithBufferedReader_thenReadText() {
|
||||||
|
val expectedTest = "Hello from Kotlin"
|
||||||
|
val reader = BufferedReader(InputStreamReader(ByteArrayInputStream(expectedTest.toByteArray())))
|
||||||
|
|
||||||
|
val readText = reader.readLine()
|
||||||
|
|
||||||
|
assertThat(readText).isEqualTo(expectedTest)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenInput_whenReadWithConsole_thenReadText() {
|
||||||
|
val expectedTest = "Hello from Kotlin"
|
||||||
|
val console = mock(Console::class.java)
|
||||||
|
`when`(console.readLine()).thenReturn(expectedTest)
|
||||||
|
|
||||||
|
val readText = console.readLine()
|
||||||
|
|
||||||
|
assertThat(readText).isEqualTo(expectedTest)
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
fun resetIO() {
|
||||||
|
System.setOut(System.out)
|
||||||
|
System.setIn(System.`in`)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
mock-maker-inline
|
|
@ -0,0 +1,11 @@
|
||||||
|
/bin/
|
||||||
|
|
||||||
|
#ignore gradle
|
||||||
|
.gradle/
|
||||||
|
|
||||||
|
|
||||||
|
#ignore build and generated files
|
||||||
|
build/
|
||||||
|
node/
|
||||||
|
target/
|
||||||
|
out/
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [InputStream to String in Kotlin](https://www.baeldung.com/kotlin-inputstream-to-string)
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>core-kotlin-io</artifactId>
|
||||||
|
<name>core-kotlin-io</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-kotlin</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-kotlin</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-test</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<kotlin.version>1.2.71</kotlin.version>
|
||||||
|
<junit.platform.version>1.1.1</junit.platform.version>
|
||||||
|
<junit.vintage.version>5.2.0</junit.vintage.version>
|
||||||
|
<assertj.version>3.10.0</assertj.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -8,7 +8,8 @@ import kotlin.test.assertEquals
|
||||||
|
|
||||||
class InputStreamToStringTest {
|
class InputStreamToStringTest {
|
||||||
private val fileName = "src/test/resources/inputstream2string.txt"
|
private val fileName = "src/test/resources/inputstream2string.txt"
|
||||||
private val fileFullContent = "Computer programming can be a hassle\r\n" +
|
private val endOfLine = System.lineSeparator()
|
||||||
|
private val fileFullContent = "Computer programming can be a hassle$endOfLine" +
|
||||||
"It's like trying to take a defended castle"
|
"It's like trying to take a defended castle"
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -46,7 +47,7 @@ class InputStreamToStringTest {
|
||||||
} finally {
|
} finally {
|
||||||
reader.close()
|
reader.close()
|
||||||
}
|
}
|
||||||
assertEquals(fileFullContent.replace("\r\n", ""), content.toString())
|
assertEquals(fileFullContent.replace(endOfLine, ""), content.toString())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
|
@ -0,0 +1,37 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>guava-collections-set</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>guava-collections-set</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>guava-collections-set</finalName>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- util -->
|
||||||
|
<guava.version>27.1-jre</guava.version>
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,92 @@
|
||||||
|
package org.baeldung.guava;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultiset;
|
||||||
|
import com.google.common.collect.Multiset;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
public class GuavaMultiSetUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenAddingValues_shouldReturnCorrectCount() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
bookStore.add("Potter");
|
||||||
|
bookStore.add("Potter");
|
||||||
|
bookStore.add("Potter");
|
||||||
|
|
||||||
|
assertThat(bookStore.contains("Potter")).isTrue();
|
||||||
|
assertThat(bookStore.count("Potter")).isEqualTo(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenRemovingValues_shouldReturnCorrectCount() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
bookStore.add("Potter");
|
||||||
|
bookStore.add("Potter");
|
||||||
|
|
||||||
|
bookStore.remove("Potter");
|
||||||
|
assertThat(bookStore.contains("Potter")).isTrue();
|
||||||
|
assertThat(bookStore.count("Potter")).isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenSetCount_shouldReturnCorrectCount() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
bookStore.setCount("Potter", 50);
|
||||||
|
assertThat(bookStore.count("Potter")).isEqualTo(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenSettingNegativeCount_shouldThrowException() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
assertThatThrownBy(() -> bookStore.setCount("Potter", -1))
|
||||||
|
.isInstanceOf(IllegalArgumentException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenSettingCountWithEmptySet_shouldBeSuccessful() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
assertThat(bookStore.setCount("Potter", 0, 2)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenSettingCountWithCorrectValue_shouldBeSuccessful() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
bookStore.add("Potter");
|
||||||
|
bookStore.add("Potter");
|
||||||
|
|
||||||
|
assertThat(bookStore.setCount("Potter", 2, 52)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiSet_whenSettingCountWithIncorrectValue_shouldFail() {
|
||||||
|
Multiset<String> bookStore = HashMultiset.create();
|
||||||
|
bookStore.add("Potter");
|
||||||
|
bookStore.add("Potter");
|
||||||
|
|
||||||
|
assertThat(bookStore.setCount("Potter", 5, 52)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMap_compareMultiSetOperations() {
|
||||||
|
Map<String, Integer> bookStore = new HashMap<>();
|
||||||
|
bookStore.put("Potter", 3);
|
||||||
|
|
||||||
|
assertThat(bookStore.containsKey("Potter")).isTrue();
|
||||||
|
assertThat(bookStore.get("Potter")).isEqualTo(3);
|
||||||
|
|
||||||
|
bookStore.put("Potter", 2);
|
||||||
|
assertThat(bookStore.get("Potter")).isEqualTo(2);
|
||||||
|
|
||||||
|
bookStore.put("Potter", null);
|
||||||
|
assertThat(bookStore.containsKey("Potter")).isTrue();
|
||||||
|
|
||||||
|
bookStore.put("Potter", -1);
|
||||||
|
assertThat(bookStore.containsKey("Potter")).isTrue();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
|
@ -0,0 +1,11 @@
|
||||||
|
=========
|
||||||
|
## HttpClient 4.x Cookbooks and Examples
|
||||||
|
|
||||||
|
###The Course
|
||||||
|
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [HttpClient 4 – Get the Status Code](http://www.baeldung.com/httpclient-status-code)
|
||||||
|
- [HttpClient with SSL](http://www.baeldung.com/httpclient-ssl)
|
|
@ -0,0 +1,315 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>httpclient-simple</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
<name>httpclient-simple</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-spring-5</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-spring-5</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- Spring Security -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-web</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-config</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-jdbc</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-beans</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-aop</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-expression</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-oxm</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- marshalling -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpcore</artifactId>
|
||||||
|
<version>${httpcore.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- http client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>fluent-hc</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpmime</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>${commons-codec.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpasyncclient</artifactId>
|
||||||
|
<version>${httpasyncclient.version}</version> <!-- 4.0.2 --> <!-- 4.1-beta1 -->
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
|
<artifactId>wiremock</artifactId>
|
||||||
|
<version>${wiremock.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- web -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>${javax.servlet.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>jstl</artifactId>
|
||||||
|
<version>${jstl.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>httpclient-simple</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>${maven-war-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.cargo</groupId>
|
||||||
|
<artifactId>cargo-maven2-plugin</artifactId>
|
||||||
|
<version>${cargo-maven2-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<wait>true</wait>
|
||||||
|
<container>
|
||||||
|
<containerId>jetty8x</containerId>
|
||||||
|
<type>embedded</type>
|
||||||
|
<systemProperties>
|
||||||
|
<!-- <provPersistenceTarget>cargo</provPersistenceTarget> -->
|
||||||
|
</systemProperties>
|
||||||
|
</container>
|
||||||
|
<configuration>
|
||||||
|
<properties>
|
||||||
|
<cargo.servlet.port>8082</cargo.servlet.port>
|
||||||
|
</properties>
|
||||||
|
</configuration>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>live</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.cargo</groupId>
|
||||||
|
<artifactId>cargo-maven2-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>start-server</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>start</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>stop-server</id>
|
||||||
|
<phase>post-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>stop</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>none</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*LiveTest.java</include>
|
||||||
|
</includes>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<webTarget>cargo</webTarget>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- various -->
|
||||||
|
<jstl.version>1.2</jstl.version>
|
||||||
|
<javax.servlet.version>3.1.0</javax.servlet.version>
|
||||||
|
<!-- util -->
|
||||||
|
<guava.version>19.0</guava.version>
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<commons-codec.version>1.10</commons-codec.version>
|
||||||
|
<httpasyncclient.version>4.1.4</httpasyncclient.version>
|
||||||
|
<!-- testing -->
|
||||||
|
<wiremock.version>2.5.1</wiremock.version>
|
||||||
|
<httpcore.version>4.4.11</httpcore.version>
|
||||||
|
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
|
||||||
|
<!-- maven plugins -->
|
||||||
|
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||||
|
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.baeldung.basic;
|
||||||
|
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException {
|
||||||
|
response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
final PrintWriter writer = response.getWriter();
|
||||||
|
writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED + " - " + authException.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
setRealmName("Baeldung");
|
||||||
|
super.afterPropertiesSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.baeldung.client;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.apache.http.client.AuthCache;
|
||||||
|
import org.apache.http.client.protocol.HttpClientContext;
|
||||||
|
import org.apache.http.impl.auth.BasicScheme;
|
||||||
|
import org.apache.http.impl.client.BasicAuthCache;
|
||||||
|
import org.apache.http.protocol.BasicHttpContext;
|
||||||
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||||
|
|
||||||
|
public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory {
|
||||||
|
|
||||||
|
HttpHost host;
|
||||||
|
|
||||||
|
public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) {
|
||||||
|
super();
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
|
||||||
|
return createHttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpContext createHttpContext() {
|
||||||
|
|
||||||
|
AuthCache authCache = new BasicAuthCache();
|
||||||
|
|
||||||
|
BasicScheme basicAuth = new BasicScheme();
|
||||||
|
authCache.put(host, basicAuth);
|
||||||
|
|
||||||
|
BasicHttpContext localcontext = new BasicHttpContext();
|
||||||
|
localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
|
||||||
|
return localcontext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.baeldung.client;
|
||||||
|
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
|
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean {
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
public RestTemplateFactory() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestTemplate getObject() {
|
||||||
|
return restTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<RestTemplate> getObjectType() {
|
||||||
|
return RestTemplate.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
HttpHost host = new HttpHost("localhost", 8082, "http");
|
||||||
|
final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryBasicAuth(host);
|
||||||
|
restTemplate = new RestTemplate(requestFactory);
|
||||||
|
restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor("user1", "user1Pass"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.baeldung.client.spring;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan("org.baeldung.client")
|
||||||
|
public class ClientConfig {
|
||||||
|
|
||||||
|
public ClientConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// beans
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.baeldung.filter;
|
||||||
|
|
||||||
|
import org.springframework.web.filter.GenericFilterBean;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class CustomFilter extends GenericFilterBean {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.baeldung.filter;
|
||||||
|
|
||||||
|
import org.baeldung.security.RestAuthenticationEntryPoint;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Autowired private RestAuthenticationEntryPoint authenticationEntryPoint;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth
|
||||||
|
.inMemoryAuthentication()
|
||||||
|
.withUser("user1")
|
||||||
|
.password(passwordEncoder().encode("user1Pass"))
|
||||||
|
.authorities("ROLE_USER");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/securityNone")
|
||||||
|
.permitAll()
|
||||||
|
.anyRequest()
|
||||||
|
.authenticated()
|
||||||
|
.and()
|
||||||
|
.httpBasic()
|
||||||
|
.authenticationEntryPoint(authenticationEntryPoint);
|
||||||
|
|
||||||
|
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.baeldung.security;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||||
|
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||||
|
import org.springframework.security.web.savedrequest.RequestCache;
|
||||||
|
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
|
||||||
|
|
||||||
|
private RequestCache requestCache = new HttpSessionRequestCache();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication) throws ServletException, IOException {
|
||||||
|
final SavedRequest savedRequest = requestCache.getRequest(request, response);
|
||||||
|
|
||||||
|
if (savedRequest == null) {
|
||||||
|
super.onAuthenticationSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final String targetUrlParameter = getTargetUrlParameter();
|
||||||
|
if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
|
||||||
|
requestCache.removeRequest(request, response);
|
||||||
|
super.onAuthenticationSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearAuthenticationAttributes(request);
|
||||||
|
|
||||||
|
// Use the DefaultSavedRequest URL
|
||||||
|
// final String targetUrl = savedRequest.getRedirectUrl();
|
||||||
|
// logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
|
||||||
|
// getRedirectStrategy().sendRedirect(request, response, targetUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestCache(final RequestCache requestCache) {
|
||||||
|
this.requestCache = requestCache;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.baeldung.security;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Entry Point will not redirect to any sort of Login - it will return the 401
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException {
|
||||||
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
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")
|
||||||
|
public class SecSecurityConfig {
|
||||||
|
|
||||||
|
public SecSecurityConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.baeldung.spring;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
@ComponentScan("org.baeldung.web")
|
||||||
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
public WebConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// beans
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
|
||||||
|
converters.add(new MappingJackson2HttpMessageConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.baeldung.web.controller;
|
||||||
|
|
||||||
|
import org.baeldung.web.dto.Bar;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(value = "/bars")
|
||||||
|
public class BarController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
|
public BarController() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
public Bar findOne(@PathVariable("id") final Long id) {
|
||||||
|
return new Bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.baeldung.web.controller;
|
||||||
|
|
||||||
|
import org.baeldung.web.dto.Foo;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(value = "/foos")
|
||||||
|
public class FooController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
|
public FooController() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
@PreAuthorize("hasRole('ROLE_USER')")
|
||||||
|
public Foo findOne(@PathVariable("id") final Long id) {
|
||||||
|
return new Foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.baeldung.web.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
public class Bar implements Serializable {
|
||||||
|
|
||||||
|
public Bar() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.baeldung.web.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
public class Foo implements Serializable {
|
||||||
|
|
||||||
|
public Foo() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="org.springframework" level="WARN" />
|
||||||
|
<logger name="org.springframework.transaction" level="WARN" />
|
||||||
|
|
||||||
|
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||||
|
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://www.springframework.org/schema/security
|
||||||
|
http://www.springframework.org/schema/security/spring-security.xsd
|
||||||
|
http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans.xsd"
|
||||||
|
>
|
||||||
|
|
||||||
|
<http create-session="stateless" use-expressions="true">
|
||||||
|
|
||||||
|
<http-basic entry-point-ref="myBasicAuthenticationEntryPoint"/>
|
||||||
|
|
||||||
|
</http>
|
||||||
|
|
||||||
|
<authentication-manager>
|
||||||
|
<authentication-provider>
|
||||||
|
<user-service>
|
||||||
|
<user name="user1" password="{noop}user1Pass" authorities="ROLE_USER"/>
|
||||||
|
</user-service>
|
||||||
|
</authentication-provider>
|
||||||
|
</authentication-manager>
|
||||||
|
|
||||||
|
<global-method-security pre-post-annotations="enabled"/>
|
||||||
|
|
||||||
|
<beans:bean id="myBasicAuthenticationEntryPoint" class="org.baeldung.basic.MyBasicAuthenticationEntryPoint" />
|
||||||
|
|
||||||
|
</beans:beans>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"
|
||||||
|
>
|
||||||
|
|
||||||
|
<display-name>Spring Security Custom Application</display-name>
|
||||||
|
|
||||||
|
<!-- Spring root -->
|
||||||
|
<context-param>
|
||||||
|
<param-name>contextClass</param-name>
|
||||||
|
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>contextConfigLocation</param-name>
|
||||||
|
<param-value>org.baeldung.spring</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
|
<listener>
|
||||||
|
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||||
|
</listener>
|
||||||
|
|
||||||
|
<!-- Spring child -->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>api</servlet-name>
|
||||||
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>api</servlet-name>
|
||||||
|
<url-pattern>/api/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<!-- Spring Security -->
|
||||||
|
<filter>
|
||||||
|
<filter-name>springSecurityFilterChain</filter-name>
|
||||||
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>springSecurityFilterChain</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -33,13 +33,13 @@ public class ClientLiveTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void whenSecuredRestApiIsConsumed_then200OK() {
|
public final void whenSecuredRestApiIsConsumed_then200OK() {
|
||||||
final ResponseEntity<Foo> responseEntity = secureRestTemplate.exchange("http://localhost:8082/spring-security-rest-basic-auth/api/foos/1", HttpMethod.GET, null, Foo.class);
|
final ResponseEntity<Foo> responseEntity = secureRestTemplate.exchange("http://localhost:8082/httpclient-simple/api/foos/1", HttpMethod.GET, null, Foo.class);
|
||||||
assertThat(responseEntity.getStatusCode().value(), is(200));
|
assertThat(responseEntity.getStatusCode().value(), is(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = ResourceAccessException.class)
|
@Test(expected = ResourceAccessException.class)
|
||||||
public final void whenHttpsUrlIsConsumed_thenException() {
|
public final void whenHttpsUrlIsConsumed_thenException() {
|
||||||
final String urlOverHttps = "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1";
|
final String urlOverHttps = "https://localhost:8443/httpclient-simple/api/bars/1";
|
||||||
final ResponseEntity<String> response = new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class);
|
final ResponseEntity<String> response = new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class);
|
||||||
assertThat(response.getStatusCode().value(), equalTo(200));
|
assertThat(response.getStatusCode().value(), equalTo(200));
|
||||||
}
|
}
|
|
@ -8,19 +8,24 @@ import java.io.IOException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.ClientProtocolException;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.config.Registry;
|
||||||
|
import org.apache.http.config.RegistryBuilder;
|
||||||
import org.apache.http.conn.scheme.Scheme;
|
import org.apache.http.conn.scheme.Scheme;
|
||||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||||
import org.apache.http.conn.ssl.TrustStrategy;
|
import org.apache.http.conn.ssl.TrustStrategy;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
||||||
|
import org.apache.http.ssl.SSLContexts;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
@ -34,14 +39,14 @@ import org.springframework.web.client.RestTemplate;
|
||||||
* */
|
* */
|
||||||
public class RestClientLiveManualTest {
|
public class RestClientLiveManualTest {
|
||||||
|
|
||||||
final String urlOverHttps = "http://localhost:8082/spring-security-rest-basic-auth/api/bars/1";
|
final String urlOverHttps = "http://localhost:8082/httpclient-simple/api/bars/1";
|
||||||
|
|
||||||
// tests
|
// tests
|
||||||
|
|
||||||
// old httpClient will throw UnsupportedOperationException
|
// old httpClient will throw UnsupportedOperationException
|
||||||
@Ignore
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() throws GeneralSecurityException {
|
public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException_1() throws GeneralSecurityException {
|
||||||
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
||||||
final CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient();
|
final CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient();
|
||||||
|
|
||||||
|
@ -57,6 +62,29 @@ public class RestClientLiveManualTest {
|
||||||
final ResponseEntity<String> response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class);
|
final ResponseEntity<String> response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class);
|
||||||
assertThat(response.getStatusCode().value(), equalTo(200));
|
assertThat(response.getStatusCode().value(), equalTo(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new httpClient : 4.4 and above
|
||||||
|
@Test
|
||||||
|
public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException_2() throws GeneralSecurityException {
|
||||||
|
|
||||||
|
final TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
|
||||||
|
final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
||||||
|
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||||
|
final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
|
||||||
|
.register("https", sslsf)
|
||||||
|
.register("http", new PlainConnectionSocketFactory())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(socketFactoryRegistry);
|
||||||
|
final CloseableHttpClient httpClient = HttpClients.custom()
|
||||||
|
.setSSLSocketFactory(sslsf)
|
||||||
|
.setConnectionManager(connectionManager)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||||
|
final ResponseEntity<String> response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class);
|
||||||
|
assertThat(response.getStatusCode().value(), equalTo(200));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenAcceptingAllCertificatesUsing4_4_whenHttpsUrlIsConsumed_thenCorrect() throws ClientProtocolException, IOException {
|
public final void givenAcceptingAllCertificatesUsing4_4_whenHttpsUrlIsConsumed_thenCorrect() throws ClientProtocolException, IOException {
|
|
@ -1,32 +1,31 @@
|
||||||
package org.baeldung.httpclient;
|
package org.baeldung.httpclient;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.conn.ClientConnectionManager;
|
|
||||||
import org.apache.http.conn.scheme.Scheme;
|
|
||||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
|
||||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
|
||||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
|
||||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
|
||||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
|
||||||
import org.apache.http.conn.ssl.TrustStrategy;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.impl.conn.PoolingClientConnectionManager;
|
|
||||||
import org.apache.http.ssl.SSLContextBuilder;
|
|
||||||
import org.apache.http.ssl.SSLContexts;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.SSLHandshakeException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLHandshakeException;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.config.Registry;
|
||||||
|
import org.apache.http.config.RegistryBuilder;
|
||||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||||
|
import org.apache.http.conn.ssl.TrustStrategy;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.apache.http.ssl.SSLContextBuilder;
|
||||||
|
import org.apache.http.ssl.SSLContexts;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test requires a localhost server over HTTPS <br>
|
* This test requires a localhost server over HTTPS <br>
|
||||||
* It should only be manually run, not part of the automated build
|
* It should only be manually run, not part of the automated build
|
||||||
|
@ -50,16 +49,22 @@ public class HttpsClientSslLiveTest {
|
||||||
.getStatusCode(), equalTo(200));
|
.getStatusCode(), equalTo(200));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenHttpClientPre4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException {
|
public final void givenHttpClientPre4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException {
|
||||||
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
|
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
|
||||||
final SSLSocketFactory sf = new SSLSocketFactory(acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
|
||||||
final SchemeRegistry registry = new SchemeRegistry();
|
final SSLContext sslContext = SSLContexts.custom()
|
||||||
registry.register(new Scheme("https", 443, sf));
|
.loadTrustMaterial(null, acceptingTrustStrategy)
|
||||||
final ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);
|
.build();
|
||||||
|
|
||||||
final CloseableHttpClient httpClient = new DefaultHttpClient(ccm);
|
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||||
|
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslsf).build();
|
||||||
|
PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
||||||
|
|
||||||
|
final CloseableHttpClient httpClient = HttpClients.custom()
|
||||||
|
.setSSLSocketFactory(sslsf)
|
||||||
|
.setConnectionManager(clientConnectionManager)
|
||||||
|
.build();
|
||||||
|
|
||||||
final HttpGet getMethod = new HttpGet(HOST_WITH_SSL);
|
final HttpGet getMethod = new HttpGet(HOST_WITH_SSL);
|
||||||
final HttpResponse response = httpClient.execute(getMethod);
|
final HttpResponse response = httpClient.execute(getMethod);
|
||||||
|
@ -76,10 +81,9 @@ public class HttpsClientSslLiveTest {
|
||||||
.loadTrustMaterial(null, acceptingTrustStrategy)
|
.loadTrustMaterial(null, acceptingTrustStrategy)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||||
|
|
||||||
final CloseableHttpClient httpClient = HttpClients.custom()
|
final CloseableHttpClient httpClient = HttpClients.custom()
|
||||||
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
|
|
||||||
.setSSLSocketFactory(sslsf)
|
.setSSLSocketFactory(sslsf)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.baeldung.httpclient;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public final class ResponseUtil {
|
||||||
|
private ResponseUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeResponse(CloseableHttpResponse response) throws IOException {
|
||||||
|
if (response == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final HttpEntity entity = response.getEntity();
|
||||||
|
if (entity != null) {
|
||||||
|
entity.getContent().close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
|
@ -8,7 +8,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [HttpClient 4 – Send Custom Cookie](http://www.baeldung.com/httpclient-4-cookies)
|
- [HttpClient 4 – Send Custom Cookie](http://www.baeldung.com/httpclient-4-cookies)
|
||||||
- [HttpClient 4 – Get the Status Code](http://www.baeldung.com/httpclient-status-code)
|
|
||||||
- [HttpClient 4 – Cancel Request](http://www.baeldung.com/httpclient-cancel-request)
|
- [HttpClient 4 – Cancel Request](http://www.baeldung.com/httpclient-cancel-request)
|
||||||
- [HttpClient 4 Cookbook](http://www.baeldung.com/httpclient4)
|
- [HttpClient 4 Cookbook](http://www.baeldung.com/httpclient4)
|
||||||
- [Unshorten URLs with HttpClient](http://www.baeldung.com/unshorten-url-httpclient)
|
- [Unshorten URLs with HttpClient](http://www.baeldung.com/unshorten-url-httpclient)
|
||||||
|
|
|
@ -122,11 +122,10 @@
|
||||||
<guava.version>19.0</guava.version>
|
<guava.version>19.0</guava.version>
|
||||||
<commons-lang3.version>3.5</commons-lang3.version>
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
<commons-codec.version>1.10</commons-codec.version>
|
<commons-codec.version>1.10</commons-codec.version>
|
||||||
<httpasyncclient.version>4.1.2</httpasyncclient.version>
|
<httpasyncclient.version>4.1.4</httpasyncclient.version>
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<wiremock.version>2.5.1</wiremock.version>
|
<wiremock.version>2.5.1</wiremock.version>
|
||||||
<httpcore.version>4.4.5</httpcore.version>
|
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
|
||||||
<httpclient.version>4.5.3</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
|
|
||||||
<!-- maven plugins -->
|
<!-- maven plugins -->
|
||||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -4,7 +4,6 @@ import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
@ -18,8 +17,7 @@ import org.apache.http.client.CredentialsProvider;
|
||||||
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.protocol.HttpClientContext;
|
import org.apache.http.client.protocol.HttpClientContext;
|
||||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
import org.apache.http.conn.ssl.SSLContexts;
|
|
||||||
import org.apache.http.conn.ssl.TrustStrategy;
|
import org.apache.http.conn.ssl.TrustStrategy;
|
||||||
import org.apache.http.impl.client.BasicCookieStore;
|
import org.apache.http.impl.client.BasicCookieStore;
|
||||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||||
|
@ -31,6 +29,7 @@ import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||||
import org.apache.http.nio.reactor.ConnectingIOReactor;
|
import org.apache.http.nio.reactor.ConnectingIOReactor;
|
||||||
import org.apache.http.protocol.BasicHttpContext;
|
import org.apache.http.protocol.BasicHttpContext;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.apache.http.ssl.SSLContexts;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class HttpAsyncClientLiveTest {
|
public class HttpAsyncClientLiveTest {
|
||||||
|
@ -104,7 +103,7 @@ public class HttpAsyncClientLiveTest {
|
||||||
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
|
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
|
||||||
final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).setSSLContext(sslContext).build();
|
final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build();
|
||||||
|
|
||||||
client.start();
|
client.start();
|
||||||
final HttpGet request = new HttpGet(HOST_WITH_SSL);
|
final HttpGet request = new HttpGet(HOST_WITH_SSL);
|
||||||
|
|
|
@ -327,7 +327,8 @@ public class HttpClientConnectionManagementLiveTest {
|
||||||
// 8.1
|
// 8.1
|
||||||
public final void whenHttpClientChecksStaleConns_thenNoExceptions() {
|
public final void whenHttpClientChecksStaleConns_thenNoExceptions() {
|
||||||
poolingConnManager = new PoolingHttpClientConnectionManager();
|
poolingConnManager = new PoolingHttpClientConnectionManager();
|
||||||
client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build()).setConnectionManager(poolingConnManager).build();
|
poolingConnManager.setValidateAfterInactivity(1000);
|
||||||
|
client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().build()).setConnectionManager(poolingConnManager).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -22,6 +22,20 @@
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- YAML -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||||
|
<version>2.9.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Allow use of LocalDate -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.9.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- test scoped -->
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.baeldung.jackson.entities;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Order {
|
||||||
|
private String orderNo;
|
||||||
|
private LocalDate date;
|
||||||
|
private String customerName;
|
||||||
|
private List<OrderLine> orderLines;
|
||||||
|
|
||||||
|
public Order() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Order(String orderNo, LocalDate date, String customerName, List<OrderLine> orderLines) {
|
||||||
|
super();
|
||||||
|
this.orderNo = orderNo;
|
||||||
|
this.date = date;
|
||||||
|
this.customerName = customerName;
|
||||||
|
this.orderLines = orderLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderNo() {
|
||||||
|
return orderNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderNo(String orderNo) {
|
||||||
|
this.orderNo = orderNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCustomerName() {
|
||||||
|
return customerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomerName(String customerName) {
|
||||||
|
this.customerName = customerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<OrderLine> getOrderLines() {
|
||||||
|
if (orderLines == null) {
|
||||||
|
orderLines = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return orderLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderLines(List<OrderLine> orderLines) {
|
||||||
|
if (orderLines == null) {
|
||||||
|
orderLines = new ArrayList<>();
|
||||||
|
}
|
||||||
|
this.orderLines = orderLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Order [orderNo=" + orderNo + ", date=" + date + ", customerName=" + customerName + ", orderLines=" + orderLines + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.jackson.entities;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public class OrderLine {
|
||||||
|
private String item;
|
||||||
|
private int quantity;
|
||||||
|
private BigDecimal unitPrice;
|
||||||
|
|
||||||
|
public OrderLine() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderLine(String item, int quantity, BigDecimal unitPrice) {
|
||||||
|
super();
|
||||||
|
this.item = item;
|
||||||
|
this.quantity = quantity;
|
||||||
|
this.unitPrice = unitPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(String item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQuantity() {
|
||||||
|
return quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuantity(int quantity) {
|
||||||
|
this.quantity = quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getUnitPrice() {
|
||||||
|
return unitPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnitPrice(BigDecimal unitPrice) {
|
||||||
|
this.unitPrice = unitPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
orderNo: A001
|
||||||
|
date: 2019-04-17
|
||||||
|
customerName: Customer, Joe
|
||||||
|
orderLines:
|
||||||
|
- item: No. 9 Sprockets
|
||||||
|
quantity: 12
|
||||||
|
unitPrice: 1.23
|
||||||
|
- item: Widget (10mm)
|
||||||
|
quantity: 4
|
||||||
|
unitPrice: 3.45
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.baeldung.jackson.yaml;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.jackson.entities.Order;
|
||||||
|
import com.baeldung.jackson.entities.OrderLine;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
|
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
|
||||||
|
|
||||||
|
public class YamlUnitTest {
|
||||||
|
private ObjectMapper mapper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
|
||||||
|
mapper.findAndRegisterModules();
|
||||||
|
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenYamlInput_ObjectCreated() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
Order order = mapper.readValue(new File("src/main/resources/orderInput.yaml"), Order.class);
|
||||||
|
assertEquals("A001", order.getOrderNo());
|
||||||
|
assertEquals(LocalDate.parse("2019-04-17", DateTimeFormatter.ISO_DATE), order.getDate());
|
||||||
|
assertEquals("Customer, Joe", order.getCustomerName());
|
||||||
|
assertEquals(2, order.getOrderLines()
|
||||||
|
.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenYamlObject_FileWritten() throws JsonGenerationException, JsonMappingException, IOException {
|
||||||
|
List<OrderLine> lines = new ArrayList<>();
|
||||||
|
lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP)));
|
||||||
|
lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP)));
|
||||||
|
Order order = new Order(
|
||||||
|
"B-9910",
|
||||||
|
LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE),
|
||||||
|
"Customer, Jane",
|
||||||
|
lines);
|
||||||
|
mapper.writeValue(new File("src/main/resources/orderOutput.yaml"), order);
|
||||||
|
|
||||||
|
File outputYaml = new File("src/main/resources/orderOutput.yaml");
|
||||||
|
assertTrue(outputYaml.exists());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
|
@ -0,0 +1,13 @@
|
||||||
|
=========
|
||||||
|
### Jackson Articles that are also part of the e-book
|
||||||
|
|
||||||
|
###The Course
|
||||||
|
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization)
|
||||||
|
- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties)
|
||||||
|
- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations)
|
||||||
|
- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial)
|
||||||
|
- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields)
|
||||||
|
- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property)
|
|
@ -0,0 +1,131 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>jackson-simple</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
<name>jackson-simple</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons-io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!--jackson for xml -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${commons-collections4.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- marshalling -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-joda</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
<artifactId>jackson-module-jsonSchema</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jdk8</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>joda-time</groupId>
|
||||||
|
<artifactId>joda-time</artifactId>
|
||||||
|
<version>${joda-time.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>${gson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>json-schema-validator</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.rest-assured</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>jackson-simple</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- util -->
|
||||||
|
<commons-lang3.version>3.8</commons-lang3.version>
|
||||||
|
<joda-time.version>2.10</joda-time.version>
|
||||||
|
<gson.version>2.8.5</gson.version>
|
||||||
|
<commons-collections4.version>4.2</commons-collections4.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<rest-assured.version>3.1.1</rest-assured.version>
|
||||||
|
<assertj.version>3.11.0</assertj.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="org.springframework" level="WARN" />
|
||||||
|
<logger name="org.springframework.transaction" level="WARN" />
|
||||||
|
|
||||||
|
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||||
|
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
|
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
|
public class ItemWithIdentity {
|
||||||
|
public int id;
|
||||||
|
public String itemName;
|
||||||
|
public UserWithIdentity owner;
|
||||||
|
|
||||||
|
public ItemWithIdentity() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemWithIdentity(final int id, final String itemName, final UserWithIdentity owner) {
|
||||||
|
this.id = id;
|
||||||
|
this.itemName = itemName;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
|
public class ItemWithIgnore {
|
||||||
|
public int id;
|
||||||
|
public String itemName;
|
||||||
|
public UserWithIgnore owner;
|
||||||
|
|
||||||
|
public ItemWithIgnore() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemWithIgnore(final int id, final String itemName, final UserWithIgnore owner) {
|
||||||
|
this.id = id;
|
||||||
|
this.itemName = itemName;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
|
|
||||||
|
public class ItemWithRef {
|
||||||
|
public int id;
|
||||||
|
public String itemName;
|
||||||
|
|
||||||
|
@JsonManagedReference
|
||||||
|
public UserWithRef owner;
|
||||||
|
|
||||||
|
public ItemWithRef() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemWithRef(final int id, final String itemName, final UserWithRef owner) {
|
||||||
|
this.id = id;
|
||||||
|
this.itemName = itemName;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
|
|
||||||
|
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
|
||||||
|
public class UserWithIdentity {
|
||||||
|
public int id;
|
||||||
|
public String name;
|
||||||
|
public List<ItemWithIdentity> userItems;
|
||||||
|
|
||||||
|
public UserWithIdentity() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserWithIdentity(final int id, final String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
userItems = new ArrayList<ItemWithIdentity>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(final ItemWithIdentity item) {
|
||||||
|
userItems.add(item);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
public class UserWithIgnore {
|
||||||
|
public int id;
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public List<ItemWithIgnore> userItems;
|
||||||
|
|
||||||
|
public UserWithIgnore() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserWithIgnore(final int id, final String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
userItems = new ArrayList<ItemWithIgnore>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(final ItemWithIgnore item) {
|
||||||
|
userItems.add(item);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
|
||||||
|
public class UserWithRef {
|
||||||
|
public int id;
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
@JsonBackReference
|
||||||
|
public List<ItemWithRef> userItems;
|
||||||
|
|
||||||
|
public UserWithRef() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserWithRef(final int id, final String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
userItems = new ArrayList<ItemWithRef>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(final ItemWithRef item) {
|
||||||
|
userItems.add(item);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.jackson.date;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||||
|
|
||||||
|
public class CustomDateDeserializer extends StdDeserializer<Date> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5451717385630622729L;
|
||||||
|
private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
|
||||||
|
|
||||||
|
public CustomDateDeserializer() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomDateDeserializer(final Class<?> vc) {
|
||||||
|
super(vc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
|
||||||
|
final String date = jsonparser.getText();
|
||||||
|
try {
|
||||||
|
return formatter.parse(date);
|
||||||
|
} catch (final ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.jackson.date;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||||
|
|
||||||
|
public class CustomDateSerializer extends StdSerializer<Date> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -2894356342227378312L;
|
||||||
|
private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
|
||||||
|
|
||||||
|
public CustomDateSerializer() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomDateSerializer(final Class<Date> t) {
|
||||||
|
super(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
|
||||||
|
gen.writeString(formatter.format(value));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.jackson.date;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
|
||||||
|
public class EventWithFormat {
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
|
||||||
|
public Date eventDate;
|
||||||
|
|
||||||
|
public EventWithFormat() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventWithFormat(final String name, final Date eventDate) {
|
||||||
|
this.name = name;
|
||||||
|
this.eventDate = eventDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEventDate() {
|
||||||
|
return eventDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.jackson.date;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
|
public class EventWithSerializer {
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
@JsonDeserialize(using = CustomDateDeserializer.class)
|
||||||
|
@JsonSerialize(using = CustomDateSerializer.class)
|
||||||
|
public Date eventDate;
|
||||||
|
|
||||||
|
public EventWithSerializer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventWithSerializer(final String name, final Date eventDate) {
|
||||||
|
this.name = name;
|
||||||
|
this.eventDate = eventDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEventDate() {
|
||||||
|
return eventDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.jackson.deserialization;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.baeldung.jackson.dtos.ItemWithSerializer;
|
||||||
|
import com.baeldung.jackson.dtos.User;
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||||
|
import com.fasterxml.jackson.databind.node.IntNode;
|
||||||
|
|
||||||
|
public class ItemDeserializerOnClass extends StdDeserializer<ItemWithSerializer> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5579141241817332594L;
|
||||||
|
|
||||||
|
public ItemDeserializerOnClass() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemDeserializerOnClass(final Class<?> vc) {
|
||||||
|
super(vc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {"id":1,"itemNr":"theItem","owner":2}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ItemWithSerializer deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||||
|
final JsonNode node = jp.getCodec()
|
||||||
|
.readTree(jp);
|
||||||
|
final int id = (Integer) ((IntNode) node.get("id")).numberValue();
|
||||||
|
final String itemName = node.get("itemName")
|
||||||
|
.asText();
|
||||||
|
final int userId = (Integer) ((IntNode) node.get("owner")).numberValue();
|
||||||
|
|
||||||
|
return new ItemWithSerializer(id, itemName, new User(userId, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue