Merge branch 'master' into java8DateTime
This commit is contained in:
commit
0a3f723e45
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
public class Address {
|
||||||
|
|
||||||
|
private String street;
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStreet(String street) {
|
||||||
|
this.street = street;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
public class CustomException extends RuntimeException {
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Detail {
|
||||||
|
|
||||||
|
private static final List<String> PARTS = Arrays.asList("turbine", "pump");
|
||||||
|
|
||||||
|
public List<String> getParts() {
|
||||||
|
return PARTS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class OptionalAddress {
|
||||||
|
|
||||||
|
private String street;
|
||||||
|
|
||||||
|
public Optional<String> getStreet() {
|
||||||
|
return Optional.ofNullable(street);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStreet(String street) {
|
||||||
|
this.street = street;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class OptionalUser {
|
||||||
|
|
||||||
|
private OptionalAddress address;
|
||||||
|
|
||||||
|
public Optional<OptionalAddress> getAddress() {
|
||||||
|
return Optional.of(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(OptionalAddress address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Address address;
|
||||||
|
|
||||||
|
public Address getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(Address address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRealUser(User user) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrThrow() {
|
||||||
|
String value = null;
|
||||||
|
Optional<String> valueOpt = Optional.ofNullable(value);
|
||||||
|
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLegalName(String name) {
|
||||||
|
return name.length() > 3 && name.length() < 16;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
public interface Vehicle {
|
||||||
|
|
||||||
|
void moveTo(long altitude, long longitude);
|
||||||
|
|
||||||
|
static String producer() {
|
||||||
|
return "N&F Vehicles";
|
||||||
|
}
|
||||||
|
|
||||||
|
default long[] startPosition() {
|
||||||
|
return new long[]{23, 15};
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getOverview() {
|
||||||
|
return "ATV made by " + producer();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.java_8_features;
|
||||||
|
|
||||||
|
public class VehicleImpl implements Vehicle {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveTo(long altitude, long longitude) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.java8;
|
||||||
|
|
||||||
|
import com.baeldung.java_8_features.Vehicle;
|
||||||
|
import com.baeldung.java_8_features.VehicleImpl;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class Java8DefaultStaticIntefaceMethodsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void callStaticInterfaceMethdosMethods_whenExpectedResults_thenCorrect() {
|
||||||
|
Vehicle vehicle = new VehicleImpl();
|
||||||
|
String overview = vehicle.getOverview();
|
||||||
|
long[] startPosition = vehicle.startPosition();
|
||||||
|
|
||||||
|
assertEquals(overview, "ATV made by N&F Vehicles");
|
||||||
|
assertEquals(startPosition[0], 23);
|
||||||
|
assertEquals(startPosition[1], 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void callDefaultInterfaceMethods_whenExpectedResults_thenCorrect() {
|
||||||
|
String producer = Vehicle.producer();
|
||||||
|
assertEquals(producer, "N&F Vehicles");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.baeldung.java8;
|
||||||
|
|
||||||
|
import com.baeldung.java_8_features.User;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class Java8MethodReferenceTest {
|
||||||
|
|
||||||
|
private List<String> list;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
list = new ArrayList<>();
|
||||||
|
list.add("One");
|
||||||
|
list.add("OneAndOnly");
|
||||||
|
list.add("Derek");
|
||||||
|
list.add("Change");
|
||||||
|
list.add("factory");
|
||||||
|
list.add("justBefore");
|
||||||
|
list.add("Italy");
|
||||||
|
list.add("Italy");
|
||||||
|
list.add("Thursday");
|
||||||
|
list.add("");
|
||||||
|
list.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStaticMethodReferences_whenWork_thenCorrect() {
|
||||||
|
|
||||||
|
List<User> users = new ArrayList<>();
|
||||||
|
users.add(new User());
|
||||||
|
users.add(new User());
|
||||||
|
boolean isReal = users.stream().anyMatch(u -> User.isRealUser(u));
|
||||||
|
boolean isRealRef = users.stream().anyMatch(User::isRealUser);
|
||||||
|
assertTrue(isReal);
|
||||||
|
assertTrue(isRealRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkInstanceMethodReferences_whenWork_thenCorrect() {
|
||||||
|
User user = new User();
|
||||||
|
boolean isLegalName = list.stream().anyMatch(user::isLegalName);
|
||||||
|
assertTrue(isLegalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkParticularTypeReferences_whenWork_thenCorrect() {
|
||||||
|
long count = list.stream().filter(String::isEmpty).count();
|
||||||
|
assertEquals(count, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkConstructorReferences_whenWork_thenCorrect() {
|
||||||
|
Stream<User> stream = list.stream().map(User::new);
|
||||||
|
List<User> userList = stream.collect(Collectors.toList());
|
||||||
|
assertEquals(userList.size(), list.size());
|
||||||
|
assertTrue(userList.get(0) instanceof User);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.baeldung.java8;
|
||||||
|
|
||||||
|
import com.baeldung.java_8_features.*;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class Java8OptionalTest {
|
||||||
|
|
||||||
|
private List<String> list;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
list = new ArrayList<>();
|
||||||
|
list.add("One");
|
||||||
|
list.add("OneAndOnly");
|
||||||
|
list.add("Derek");
|
||||||
|
list.add("Change");
|
||||||
|
list.add("factory");
|
||||||
|
list.add("justBefore");
|
||||||
|
list.add("Italy");
|
||||||
|
list.add("Italy");
|
||||||
|
list.add("Thursday");
|
||||||
|
list.add("");
|
||||||
|
list.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkOptional_whenAsExpected_thenCorrect() {
|
||||||
|
|
||||||
|
Optional<String> optionalEmpty = Optional.empty();
|
||||||
|
assertFalse(optionalEmpty.isPresent());
|
||||||
|
|
||||||
|
String str = "value";
|
||||||
|
Optional<String> optional = Optional.of(str);
|
||||||
|
assertEquals(optional.get(), "value");
|
||||||
|
|
||||||
|
Optional<String> optionalNullable = Optional.ofNullable(str);
|
||||||
|
Optional<String> optionalNull = Optional.ofNullable(null);
|
||||||
|
assertEquals(optionalNullable.get(), "value");
|
||||||
|
assertFalse(optionalNull.isPresent());
|
||||||
|
|
||||||
|
List<String> listOpt = Optional.of(list).orElse(new ArrayList<>());
|
||||||
|
List<String> listNull = null;
|
||||||
|
List<String> listOptNull = Optional.ofNullable(listNull).orElse(new ArrayList<>());
|
||||||
|
assertTrue(listOpt == list);
|
||||||
|
assertTrue(listOptNull.isEmpty());
|
||||||
|
|
||||||
|
Optional<User> user = Optional.ofNullable(getUser());
|
||||||
|
String result = user.map(User::getAddress)
|
||||||
|
.map(Address::getStreet)
|
||||||
|
.orElse("not specified");
|
||||||
|
assertEquals(result, "1st Avenue");
|
||||||
|
|
||||||
|
Optional<OptionalUser> optionalUser = Optional.ofNullable(getOptionalUser());
|
||||||
|
String resultOpt = optionalUser.flatMap(OptionalUser::getAddress)
|
||||||
|
.flatMap(OptionalAddress::getStreet)
|
||||||
|
.orElse("not specified");
|
||||||
|
assertEquals(resultOpt, "1st Avenue");
|
||||||
|
|
||||||
|
Optional<User> userNull = Optional.ofNullable(getUserNull());
|
||||||
|
String resultNull = userNull.map(User::getAddress)
|
||||||
|
.map(Address::getStreet)
|
||||||
|
.orElse("not specified");
|
||||||
|
assertEquals(resultNull, "not specified");
|
||||||
|
|
||||||
|
Optional<OptionalUser> optionalUserNull = Optional.ofNullable(getOptionalUserNull());
|
||||||
|
String resultOptNull = optionalUserNull.flatMap(OptionalUser::getAddress)
|
||||||
|
.flatMap(OptionalAddress::getStreet)
|
||||||
|
.orElse("not specified");
|
||||||
|
assertEquals(resultOptNull, "not specified");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CustomException.class)
|
||||||
|
public void callMethod_whenCustomException_thenCorrect() {
|
||||||
|
User user = new User();
|
||||||
|
String result = user.getOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private User getUser() {
|
||||||
|
User user = new User();
|
||||||
|
Address address = new Address();
|
||||||
|
address.setStreet("1st Avenue");
|
||||||
|
user.setAddress(address);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OptionalUser getOptionalUser() {
|
||||||
|
OptionalUser user = new OptionalUser();
|
||||||
|
OptionalAddress address = new OptionalAddress();
|
||||||
|
address.setStreet("1st Avenue");
|
||||||
|
user.setAddress(address);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OptionalUser getOptionalUserNull() {
|
||||||
|
OptionalUser user = new OptionalUser();
|
||||||
|
OptionalAddress address = new OptionalAddress();
|
||||||
|
address.setStreet(null);
|
||||||
|
user.setAddress(address);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private User getUserNull() {
|
||||||
|
User user = new User();
|
||||||
|
Address address = new Address();
|
||||||
|
address.setStreet(null);
|
||||||
|
user.setAddress(address);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package com.baeldung.java8;
|
||||||
|
|
||||||
|
import com.baeldung.java_8_features.Detail;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class Java8StreamsTest {
|
||||||
|
|
||||||
|
private List<String> list;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
list = new ArrayList<>();
|
||||||
|
list.add("One");
|
||||||
|
list.add("OneAndOnly");
|
||||||
|
list.add("Derek");
|
||||||
|
list.add("Change");
|
||||||
|
list.add("factory");
|
||||||
|
list.add("justBefore");
|
||||||
|
list.add("Italy");
|
||||||
|
list.add("Italy");
|
||||||
|
list.add("Thursday");
|
||||||
|
list.add("");
|
||||||
|
list.add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStreamCount_whenCreating_givenDifferentSources() {
|
||||||
|
String[] arr = new String[]{"a", "b", "c"};
|
||||||
|
Stream<String> streamArr = Arrays.stream(arr);
|
||||||
|
assertEquals(streamArr.count(), 3);
|
||||||
|
|
||||||
|
Stream<String> streamOf = Stream.of("a", "b", "c");
|
||||||
|
assertEquals(streamOf.count(), 3);
|
||||||
|
|
||||||
|
long count = list.stream().distinct().count();
|
||||||
|
assertEquals(count, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStreamCount_whenOperationFilter_thanCorrect() {
|
||||||
|
Stream<String> streamFilter = list.stream().filter(element -> element.isEmpty());
|
||||||
|
assertEquals(streamFilter.count(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStreamCount_whenOperationMap_thanCorrect() {
|
||||||
|
List<String> uris = new ArrayList<>();
|
||||||
|
uris.add("C:\\My.txt");
|
||||||
|
Stream<Path> streamMap = uris.stream().map(uri -> Paths.get(uri));
|
||||||
|
assertEquals(streamMap.count(), 1);
|
||||||
|
|
||||||
|
List<Detail> details = new ArrayList<>();
|
||||||
|
details.add(new Detail());
|
||||||
|
details.add(new Detail());
|
||||||
|
Stream<String> streamFlatMap = details.stream()
|
||||||
|
.flatMap(detail -> detail.getParts().stream());
|
||||||
|
assertEquals(streamFlatMap.count(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStreamCount_whenOperationMatch_thenCorrect() {
|
||||||
|
boolean isValid = list.stream().anyMatch(element -> element.contains("h"));
|
||||||
|
boolean isValidOne = list.stream().allMatch(element -> element.contains("h"));
|
||||||
|
boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h"));
|
||||||
|
assertTrue(isValid);
|
||||||
|
assertFalse(isValidOne);
|
||||||
|
assertFalse(isValidTwo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStreamReducedValue_whenOperationReduce_thenCorrect() {
|
||||||
|
List<Integer> integers = new ArrayList<>();
|
||||||
|
integers.add(1);
|
||||||
|
integers.add(1);
|
||||||
|
integers.add(1);
|
||||||
|
Integer reduced = integers.stream().reduce(23, (a, b) -> a + b);
|
||||||
|
assertTrue(reduced == 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkStreamContains_whenOperationCollect_thenCorrect() {
|
||||||
|
List<String> resultList = list.stream()
|
||||||
|
.map(element -> element.toUpperCase())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
assertEquals(resultList.size(), list.size());
|
||||||
|
assertTrue(resultList.contains(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkParallelStream_whenDoWork() {
|
||||||
|
list.parallelStream().forEach(element -> doWork(element));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doWork(String string) {
|
||||||
|
assertTrue(true); //just imitate an amount of work
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,12 @@
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.4</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--jackson for xml-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
<version>2.7.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.baeldung.jackson.xml;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||||
|
|
||||||
|
public class TestXMLSerializeDeserialize {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException {
|
||||||
|
XmlMapper xmlMapper = new XmlMapper();
|
||||||
|
String xml = xmlMapper.writeValueAsString(new SimpleBean());
|
||||||
|
assertNotNull(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException {
|
||||||
|
XmlMapper xmlMapper = new XmlMapper();
|
||||||
|
xmlMapper.writeValue(new File("target/simple_bean.xml"), new SimpleBean());
|
||||||
|
File file = new File("target/simple_bean.xml");
|
||||||
|
assertNotNull(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenJavaGotFromXmlStr_thenCorrect() throws IOException {
|
||||||
|
XmlMapper xmlMapper = new XmlMapper();
|
||||||
|
SimpleBean value = xmlMapper.readValue(
|
||||||
|
"<SimpleBean><x>1</x><y>2</y></SimpleBean>", SimpleBean.class);
|
||||||
|
assertTrue(value.getX() == 1 && value.getY() == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenJavaGotFromXmlFile_thenCorrect() throws IOException {
|
||||||
|
File file = new File("src/test/resources/simple_bean.xml");
|
||||||
|
XmlMapper xmlMapper = new XmlMapper();
|
||||||
|
String xml = inputStreamToString(new FileInputStream(file));
|
||||||
|
SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class);
|
||||||
|
assertTrue(value.getX() == 1 && value.getY() == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String inputStreamToString(InputStream is) throws IOException {
|
||||||
|
BufferedReader br;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
String line;
|
||||||
|
br = new BufferedReader(new InputStreamReader(is));
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleBean {
|
||||||
|
private int x = 1;
|
||||||
|
private int y = 2;
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<SimpleBean>
|
||||||
|
<x>1</x>
|
||||||
|
<y>2</y>
|
||||||
|
</SimpleBean>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?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>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>junit5</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>junit5</name>
|
||||||
|
<description>Intro to JUnit 5</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<!-- Due to a bug in surefire-junit5-5.0.0-ALPHA we use the latest snapshot instead -->
|
||||||
|
<junit.gen5.version>5.0.0-SNAPSHOT</junit.gen5.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>snapshots-repo</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<!-- Do NOT cache JUnit 5 snapshot JARs. -->
|
||||||
|
<updatePolicy>always</updatePolicy>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>snapshots-repo</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<!-- Do NOT cache JUnit 5 snapshot JARs. -->
|
||||||
|
<updatePolicy>always</updatePolicy>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.19</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit</groupId>
|
||||||
|
<artifactId>surefire-junit5</artifactId>
|
||||||
|
<version>${junit.gen5.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit</groupId>
|
||||||
|
<artifactId>junit5-api</artifactId>
|
||||||
|
<version>${junit.gen5.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.gen5.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.gen5.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.gen5.api.Assumptions.*;
|
||||||
|
|
||||||
|
public class AssumptionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void trueAssumption() {
|
||||||
|
assumeTrue(5 > 1);
|
||||||
|
assertEquals(5 + 2, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void falseAssumption() {
|
||||||
|
assumeFalse(5 < 1);
|
||||||
|
assertEquals(5 + 2, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void assumptionThat() {
|
||||||
|
String someString = "Just a string";
|
||||||
|
assumingThat(
|
||||||
|
someString.equals("Just a string"),
|
||||||
|
() -> assertEquals(2 + 2, 4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.gen5.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.gen5.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.gen5.api.Assertions.expectThrows;
|
||||||
|
|
||||||
|
public class ExceptionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldThrowException() {
|
||||||
|
Throwable exception = expectThrows(UnsupportedOperationException.class,
|
||||||
|
() -> {
|
||||||
|
throw new UnsupportedOperationException("Not supported");
|
||||||
|
});
|
||||||
|
assertEquals(exception.getMessage(), "Not supported");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.gen5.api.Disabled;
|
||||||
|
import org.junit.gen5.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.gen5.api.Assertions.*;
|
||||||
|
|
||||||
|
class FirstTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void lambdaExpressions() {
|
||||||
|
List<Integer> numbers = Arrays.asList(1, 2, 3);
|
||||||
|
assertTrue(numbers
|
||||||
|
.stream()
|
||||||
|
.mapToInt(i -> i)
|
||||||
|
.sum() > 5, "Sum should be greater than 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void groupAssertions() {
|
||||||
|
int[] numbers = {0, 1, 2, 3, 4};
|
||||||
|
assertAll("numbers",
|
||||||
|
() -> assertEquals(numbers[0], 1),
|
||||||
|
() -> assertEquals(numbers[3], 3),
|
||||||
|
() -> assertEquals(numbers[4], 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled
|
||||||
|
void disabledTest() {
|
||||||
|
assertTrue(false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.gen5.api.*;
|
||||||
|
|
||||||
|
import java.util.EmptyStackException;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
public class NestedTest {
|
||||||
|
Stack<Object> stack;
|
||||||
|
boolean isRun = false;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("is instantiated with new Stack()")
|
||||||
|
void isInstantiatedWithNew() {
|
||||||
|
new Stack<Object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("when new")
|
||||||
|
class WhenNew {
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void init() {
|
||||||
|
stack = new Stack<Object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("is empty")
|
||||||
|
void isEmpty() {
|
||||||
|
Assertions.assertTrue(stack.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("throws EmptyStackException when popped")
|
||||||
|
void throwsExceptionWhenPopped() {
|
||||||
|
Assertions.expectThrows(EmptyStackException.class, () -> stack.pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("throws EmptyStackException when peeked")
|
||||||
|
void throwsExceptionWhenPeeked() {
|
||||||
|
Assertions.expectThrows(EmptyStackException.class, () -> stack.peek());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("after pushing an element")
|
||||||
|
class AfterPushing {
|
||||||
|
|
||||||
|
String anElement = "an element";
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void init() {
|
||||||
|
stack.push(anElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("it is no longer empty")
|
||||||
|
void isEmpty() {
|
||||||
|
Assertions.assertFalse(stack.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("returns the element when popped and is empty")
|
||||||
|
void returnElementWhenPopped() {
|
||||||
|
Assertions.assertEquals(anElement, stack.pop());
|
||||||
|
Assertions.assertTrue(stack.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("returns the element when peeked but remains not empty")
|
||||||
|
void returnElementWhenPeeked() {
|
||||||
|
Assertions.assertEquals(anElement, stack.peek());
|
||||||
|
Assertions.assertFalse(stack.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.gen5.api.Tag;
|
||||||
|
import org.junit.gen5.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.gen5.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
@Tag("Test case")
|
||||||
|
public class TaggedTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Tag("Method")
|
||||||
|
void testMethod() {
|
||||||
|
assertEquals(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<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>spring-autowire</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-autowire</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<org.springframework.version>4.2.5.RELEASE</org.springframework.version>
|
||||||
|
<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>spring-autowire</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
|
||||||
|
FooService fooService = ctx.getBean(FooService.class);
|
||||||
|
fooService.doStuff();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan("com.baeldung.autowire.sample")
|
||||||
|
public class AppConfig {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
public class Bar {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@FormatterType("Bar")
|
||||||
|
@Component
|
||||||
|
public class BarFormatter implements Formatter {
|
||||||
|
|
||||||
|
public String format() {
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
public class Foo {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
public class FooDAO {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@FormatterType("Foo")
|
||||||
|
@Component
|
||||||
|
public class FooFormatter implements Formatter {
|
||||||
|
|
||||||
|
public String format() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class FooService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@FormatterType("Foo")
|
||||||
|
private Formatter formatter;
|
||||||
|
|
||||||
|
public String doStuff(){
|
||||||
|
return formatter.format();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
public interface Formatter {
|
||||||
|
|
||||||
|
String format();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD,ElementType.TYPE, ElementType.PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface FormatterType {
|
||||||
|
|
||||||
|
String value();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.autowire.sample;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes=AppConfig.class, loader=AnnotationConfigContextLoader.class)
|
||||||
|
public class FooServiceTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FooService fooService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFooFormatterType_thenReturnFoo(){
|
||||||
|
Assert.assertEquals("foo", fooService.doStuff());
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import org.springframework.web.context.support.ServletContextResource;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@ -41,17 +42,13 @@ public class ImageController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
|
@RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
|
||||||
public ResponseEntity<byte[]> getImageAsResponseEntity() {
|
public ResponseEntity<byte[]> getImageAsResponseEntity() throws IOException {
|
||||||
ResponseEntity<byte[]> responseEntity;
|
ResponseEntity<byte[]> responseEntity;
|
||||||
final HttpHeaders headers = new HttpHeaders();
|
final HttpHeaders headers = new HttpHeaders();
|
||||||
try {
|
|
||||||
final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
|
final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
|
||||||
byte[] media = IOUtils.toByteArray(in);
|
byte[] media = IOUtils.toByteArray(in);
|
||||||
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
|
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
|
||||||
responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
|
responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
|
||||||
} catch (IOException ioe) {
|
|
||||||
responseEntity = new ResponseEntity<>(null, headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
|
||||||
}
|
|
||||||
return responseEntity;
|
return responseEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -44,6 +45,11 @@
|
||||||
<version>1.0.1.RELEASE</version>
|
<version>1.0.1.RELEASE</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
|
<artifactId>json-path</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -52,6 +58,38 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Documentation.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.asciidoctor</groupId>
|
||||||
|
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||||
|
<version>1.5.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>generate-docs</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>process-asciidoc</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<backend>html</backend>
|
||||||
|
<doctype>book</doctype>
|
||||||
|
<attributes>
|
||||||
|
<snippets>${snippetsDirectory}</snippets>
|
||||||
|
</attributes>
|
||||||
|
<sourceDirectory>src/docs/asciidocs</sourceDirectory>
|
||||||
|
<outputDirectory>target/generated-docs</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
= RESTful Notes API Guide
|
||||||
|
Baeldung;
|
||||||
|
:doctype: book
|
||||||
|
:icons: font
|
||||||
|
:source-highlighter: highlightjs
|
||||||
|
:toc: left
|
||||||
|
:toclevels: 4
|
||||||
|
:sectlinks:
|
||||||
|
|
||||||
|
[[overview]]
|
||||||
|
= Overview
|
||||||
|
|
||||||
|
[[overview-http-verbs]]
|
||||||
|
== HTTP verbs
|
||||||
|
|
||||||
|
RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
|
||||||
|
use of HTTP verbs.
|
||||||
|
|
||||||
|
|===
|
||||||
|
| Verb | Usage
|
||||||
|
|
||||||
|
| `GET`
|
||||||
|
| Used to retrieve a resource
|
||||||
|
|
||||||
|
| `POST`
|
||||||
|
| Used to create a new resource
|
||||||
|
|
||||||
|
| `PATCH`
|
||||||
|
| Used to update an existing resource, including partial updates
|
||||||
|
|
||||||
|
| `DELETE`
|
||||||
|
| Used to delete an existing resource
|
||||||
|
|===
|
||||||
|
|
||||||
|
RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
|
||||||
|
use of HTTP status codes.
|
||||||
|
|
||||||
|
|===
|
||||||
|
| Status code | Usage
|
||||||
|
|
||||||
|
| `200 OK`
|
||||||
|
| The request completed successfully
|
||||||
|
|
||||||
|
| `201 Created`
|
||||||
|
| A new resource has been created successfully. The resource's URI is available from the response's
|
||||||
|
`Location` header
|
||||||
|
|
||||||
|
| `204 No Content`
|
||||||
|
| An update to an existing resource has been applied successfully
|
||||||
|
|
||||||
|
| `400 Bad Request`
|
||||||
|
| The request was malformed. The response body will include an error providing further information
|
||||||
|
|
||||||
|
| `404 Not Found`
|
||||||
|
| The requested resource did not exist
|
||||||
|
|===
|
||||||
|
|
||||||
|
[[overview-headers]]
|
||||||
|
== Headers
|
||||||
|
|
||||||
|
Every response has the following header(s):
|
||||||
|
|
||||||
|
include::{snippets}/headers-example/response-headers.adoc[]
|
||||||
|
|
||||||
|
[[overview-hypermedia]]
|
||||||
|
== Hypermedia
|
||||||
|
|
||||||
|
RESTful Notes uses hypermedia and resources include links to other resources in their
|
||||||
|
responses. Responses are in http://stateless.co/hal_specification.html[Hypertext Application
|
||||||
|
from resource to resource.
|
||||||
|
Language (HAL)] format. Links can be found beneath the `_links` key. Users of the API should
|
||||||
|
not create URIs themselves, instead they should use the above-described links to navigate
|
||||||
|
|
||||||
|
[[resources]]
|
||||||
|
= Resources
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[resources-index]]
|
||||||
|
== Index
|
||||||
|
|
||||||
|
The index provides the entry point into the service.
|
||||||
|
|
||||||
|
[[resources-index-access]]
|
||||||
|
=== Accessing the index
|
||||||
|
|
||||||
|
A `GET` request is used to access the index
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/index-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== Example response
|
||||||
|
|
||||||
|
include::{snippets}/index-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== Example request
|
||||||
|
|
||||||
|
include::{snippets}/index-example/http-request.adoc[]
|
||||||
|
|
||||||
|
==== CURL request
|
||||||
|
|
||||||
|
include::{snippets}/index-example/curl-request.adoc[]
|
||||||
|
|
||||||
|
[[resources-index-links]]
|
||||||
|
==== Links
|
||||||
|
|
||||||
|
include::{snippets}/index-example/links.adoc[]
|
||||||
|
|
||||||
|
|
||||||
|
[[resources-CRUD]]
|
||||||
|
== CRUD REST Service
|
||||||
|
|
||||||
|
The CRUD provides the entry point into the service.
|
||||||
|
|
||||||
|
[[resources-crud-access]]
|
||||||
|
=== Accessing the crud GET
|
||||||
|
|
||||||
|
A `GET` request is used to access the CRUD read
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/crud-get-example/http-request.adoc[]
|
||||||
|
|
||||||
|
==== Example response
|
||||||
|
|
||||||
|
include::{snippets}/crud-get-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== CURL request
|
||||||
|
|
||||||
|
include::{snippets}/crud-get-example/curl-request.adoc[]
|
||||||
|
|
||||||
|
[[resources-crud-access]]
|
||||||
|
=== Accessing the crud POST
|
||||||
|
|
||||||
|
A `POST` request is used to access the CRUD create
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/crud-create-example/http-request.adoc[]
|
||||||
|
|
||||||
|
==== Example response
|
||||||
|
|
||||||
|
include::{snippets}/crud-create-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== CURL request
|
||||||
|
|
||||||
|
include::{snippets}/crud-create-example/curl-request.adoc[]
|
||||||
|
|
||||||
|
[[resources-crud-access]]
|
||||||
|
=== Accessing the crud DELETE
|
||||||
|
|
||||||
|
A `DELETE` request is used to access the CRUD create
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/crud-delete-example/http-request.adoc[]
|
||||||
|
|
||||||
|
==== Example response
|
||||||
|
|
||||||
|
include::{snippets}/crud-delete-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== CURL request
|
||||||
|
|
||||||
|
include::{snippets}/crud-delete-example/curl-request.adoc[]
|
||||||
|
|
||||||
|
[[resources-crud-access]]
|
||||||
|
=== Accessing the crud PATCH
|
||||||
|
|
||||||
|
A `PATCH` request is used to access the CRUD create
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/crud-patch-example/http-request.adoc[]
|
||||||
|
|
||||||
|
==== Example response
|
||||||
|
|
||||||
|
include::{snippets}/crud-patch-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== CURL request
|
||||||
|
|
||||||
|
include::{snippets}/crud-patch-example/curl-request.adoc[]
|
||||||
|
|
||||||
|
[[resources-crud-access]]
|
||||||
|
=== Accessing the crud PUT
|
||||||
|
|
||||||
|
A `PUT` request is used to access the CRUD create
|
||||||
|
|
||||||
|
==== Response structure
|
||||||
|
|
||||||
|
include::{snippets}/crud-put-example/http-request.adoc[]
|
||||||
|
|
||||||
|
==== Example response
|
||||||
|
|
||||||
|
include::{snippets}/crud-put-example/http-response.adoc[]
|
||||||
|
|
||||||
|
==== CURL request
|
||||||
|
|
||||||
|
include::{snippets}/crud-put-example/curl-request.adoc[]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.example;
|
||||||
|
|
||||||
|
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/crud")
|
||||||
|
public class CRUDController {
|
||||||
|
|
||||||
|
@RequestMapping(method=RequestMethod.GET)
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
public List<CrudInput> read(@RequestBody CrudInput crudInput) {
|
||||||
|
List<CrudInput> returnList=new ArrayList<CrudInput>();
|
||||||
|
returnList.add(crudInput);
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
|
@RequestMapping(method=RequestMethod.POST)
|
||||||
|
public HttpHeaders save(@RequestBody CrudInput crudInput) {
|
||||||
|
HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri());
|
||||||
|
return httpHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
HttpHeaders delete(@RequestBody CrudInput crudInput) {
|
||||||
|
HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
return httpHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
|
||||||
|
@ResponseStatus(HttpStatus.ACCEPTED)
|
||||||
|
void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
|
||||||
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
|
void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.example;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.validator.constraints.NotBlank;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public class CrudInput {
|
||||||
|
|
||||||
|
//@NotBlank
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
private final String body;
|
||||||
|
|
||||||
|
private final List<URI> tagUris;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public CrudInput(@JsonProperty("title") String title,
|
||||||
|
@JsonProperty("body") String body, @JsonProperty("tags") List<URI> tagUris) {
|
||||||
|
this.title = title;
|
||||||
|
this.body = body;
|
||||||
|
this.tagUris = tagUris == null ? Collections.<URI>emptyList() : tagUris;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("tags")
|
||||||
|
public List<URI> getTagUris() {
|
||||||
|
return this.tagUris;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,22 +1,21 @@
|
||||||
package com.example;
|
package com.example;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
||||||
|
|
||||||
import org.springframework.hateoas.ResourceSupport;
|
import org.springframework.hateoas.ResourceSupport;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api")
|
@RequestMapping("/")
|
||||||
public class IndexController {
|
public class IndexController {
|
||||||
|
|
||||||
@RequestMapping(method=RequestMethod.GET)
|
@RequestMapping(method=RequestMethod.GET)
|
||||||
public ResourceSupport index() {
|
public ResourceSupport index() {
|
||||||
ResourceSupport index = new ResourceSupport();
|
ResourceSupport index = new ResourceSupport();
|
||||||
index.add(linkTo(MyRestController.class).withRel("notes"));
|
index.add(linkTo(CRUDController.class).withRel("crud"));
|
||||||
index.add(linkTo(MyRestController.class).withRel("tags"));
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package com.example;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/rest/api")
|
|
||||||
public class MyRestController {
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET)
|
|
||||||
public String index() {
|
|
||||||
return "Hello";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,28 +1,39 @@
|
||||||
package com.example;
|
package com.example;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
|
import org.springframework.hateoas.MediaTypes;
|
||||||
import org.springframework.restdocs.RestDocumentation;
|
import org.springframework.restdocs.RestDocumentation;
|
||||||
|
import org.springframework.restdocs.constraints.ConstraintDescriptions;
|
||||||
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
|
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
|
||||||
|
import org.springframework.restdocs.payload.FieldDescriptor;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
|
||||||
|
import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
|
||||||
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
|
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
|
||||||
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
|
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
|
||||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
||||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
|
||||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
import static org.springframework.restdocs.snippet.Attributes.key;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
import static org.springframework.util.StringUtils.collectionToDelimitedString;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringApplicationConfiguration(classes = SpringRestDocsApplication.class)
|
@SpringApplicationConfiguration(classes = SpringRestDocsApplication.class)
|
||||||
|
@ -35,6 +46,9 @@ public class ApiDocumentation {
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext context;
|
private WebApplicationContext context;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
private RestDocumentationResultHandler document;
|
private RestDocumentationResultHandler document;
|
||||||
|
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
@ -42,25 +56,179 @@ public class ApiDocumentation {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
this.document = document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()));
|
this.document = document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()));
|
||||||
|
|
||||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
|
||||||
.apply(documentationConfiguration(this.restDocumentation))
|
.apply(documentationConfiguration(this.restDocumentation))
|
||||||
.alwaysDo(this.document).build();
|
.alwaysDo(this.document)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headersExample() throws Exception {
|
||||||
|
this.document.snippets(responseHeaders(headerWithName("Content-Type")
|
||||||
|
.description("The Content-Type of the payload, e.g. `application/hal+json`")));
|
||||||
|
this.mockMvc.perform(get("/"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void indexExample() throws Exception {
|
public void indexExample() throws Exception {
|
||||||
this.document.snippets(
|
this.document.snippets(
|
||||||
links(
|
links(linkWithRel("crud").description("The <<resources-tags,Tags resource>>")),
|
||||||
linkWithRel("notes").description("The <<Simple description about the REST Service >>"),
|
responseFields(fieldWithPath("_links").description("<<resources-index-links,Links>> to other resources"))
|
||||||
linkWithRel("tags").description("The <<resources-tags,Tags resource>>")
|
);
|
||||||
),
|
this.mockMvc.perform(get("/"))
|
||||||
responseFields(fieldWithPath("_links").description("<<resources-index-links,Links>> to other resources")));
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
this.mockMvc.perform(get("/api")).andExpect(status().isOk());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudGetExample() throws Exception {
|
||||||
|
|
||||||
|
Map<String, String> tag = new HashMap<>();
|
||||||
|
tag.put("name", "GET");
|
||||||
|
|
||||||
|
String tagLocation = this.mockMvc.perform(get("/crud")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(tag)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse()
|
||||||
|
.getHeader("Location");
|
||||||
|
|
||||||
|
Map<String, Object> crud = new HashMap<>();
|
||||||
|
crud.put("title", "Sample Model");
|
||||||
|
crud.put("body", "http://www.baeldung.com/");
|
||||||
|
crud.put("tags", singletonList(tagLocation));
|
||||||
|
|
||||||
|
this.mockMvc.perform(get("/crud")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(crud)))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudCreateExample() throws Exception {
|
||||||
|
Map<String, String> tag = new HashMap<>();
|
||||||
|
tag.put("name", "CREATE");
|
||||||
|
|
||||||
|
String tagLocation = this.mockMvc.perform(post("/crud")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(tag)))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse()
|
||||||
|
.getHeader("Location");
|
||||||
|
|
||||||
|
Map<String, Object> crud = new HashMap<>();
|
||||||
|
crud.put("title", "Sample Model");
|
||||||
|
crud.put("body", "http://www.baeldung.com/");
|
||||||
|
crud.put("tags", singletonList(tagLocation));
|
||||||
|
|
||||||
|
ConstrainedFields fields = new ConstrainedFields(CrudInput.class);
|
||||||
|
this.document.snippets(requestFields(
|
||||||
|
fields.withPath("title").description("The title of the note"),
|
||||||
|
fields.withPath("body").description("The body of the note"),
|
||||||
|
fields.withPath("tags").description("An array of tag resource URIs")));
|
||||||
|
this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isCreated());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudDeleteExample() throws Exception {
|
||||||
|
|
||||||
|
Map<String, String> tag = new HashMap<>();
|
||||||
|
tag.put("name", "DELETE");
|
||||||
|
|
||||||
|
String tagLocation = this.mockMvc.perform(delete("/crud/10")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(tag)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse()
|
||||||
|
.getHeader("Location");
|
||||||
|
|
||||||
|
Map<String, Object> crud = new HashMap<>();
|
||||||
|
crud.put("title", "Sample Model");
|
||||||
|
crud.put("body", "http://www.baeldung.com/");
|
||||||
|
crud.put("tags", singletonList(tagLocation));
|
||||||
|
|
||||||
|
this.mockMvc.perform(delete("/crud/10")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(crud)))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudPatchExample() throws Exception {
|
||||||
|
|
||||||
|
Map<String, String> tag = new HashMap<>();
|
||||||
|
tag.put("name", "PATCH");
|
||||||
|
|
||||||
|
String tagLocation = this.mockMvc.perform(patch("/crud/10")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(tag)))
|
||||||
|
.andExpect(status().isNoContent())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse()
|
||||||
|
.getHeader("Location");
|
||||||
|
|
||||||
|
Map<String, Object> crud = new HashMap<>();
|
||||||
|
crud.put("title", "Sample Model");
|
||||||
|
crud.put("body", "http://www.baeldung.com/");
|
||||||
|
crud.put("tags", singletonList(tagLocation));
|
||||||
|
|
||||||
|
this.mockMvc.perform(patch("/crud/10")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(crud)))
|
||||||
|
.andExpect(status().isNoContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void crudPutExample() throws Exception {
|
||||||
|
Map<String, String> tag = new HashMap<>();
|
||||||
|
tag.put("name", "PUT");
|
||||||
|
|
||||||
|
String tagLocation = this.mockMvc.perform(put("/crud/10")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(tag)))
|
||||||
|
.andExpect(status().isAccepted())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse()
|
||||||
|
.getHeader("Location");
|
||||||
|
|
||||||
|
Map<String, Object> crud = new HashMap<>();
|
||||||
|
crud.put("title", "Sample Model");
|
||||||
|
crud.put("body", "http://www.baeldung.com/");
|
||||||
|
crud.put("tags", singletonList(tagLocation));
|
||||||
|
|
||||||
|
this.mockMvc.perform(put("/crud/10")
|
||||||
|
.contentType(MediaTypes.HAL_JSON)
|
||||||
|
.content(this.objectMapper.writeValueAsString(crud)))
|
||||||
|
.andExpect(status().isAccepted());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() {
|
public void contextLoads() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ConstrainedFields {
|
||||||
|
|
||||||
|
private final ConstraintDescriptions constraintDescriptions;
|
||||||
|
|
||||||
|
ConstrainedFields(Class<?> input) {
|
||||||
|
this.constraintDescriptions = new ConstraintDescriptions(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FieldDescriptor withPath(String path) {
|
||||||
|
return fieldWithPath(path)
|
||||||
|
.attributes(key("constraints")
|
||||||
|
.value(collectionToDelimitedString(this.constraintDescriptions.descriptionsForProperty(path), ". ")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
package com.example;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.jayway.jsonpath.JsonPath;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
|
import org.springframework.hateoas.MediaTypes;
|
||||||
|
import org.springframework.restdocs.RestDocumentation;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||||
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
||||||
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
|
||||||
|
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@SpringApplicationConfiguration(classes = SpringRestDocsApplication.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
public class GettingStartedDocumentation {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext context;
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
|
||||||
|
.apply(documentationConfiguration(this.restDocumentation))
|
||||||
|
.alwaysDo(document("{method-name}/{step}/",
|
||||||
|
preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void index() throws Exception {
|
||||||
|
this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("_links.crud", is(notNullValue())))
|
||||||
|
.andExpect(jsonPath("_links.crud", is(notNullValue())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// String createNote() throws Exception {
|
||||||
|
// Map<String, String> note = new HashMap<String, String>();
|
||||||
|
// note.put("title", "Note creation with cURL");
|
||||||
|
// note.put("body", "An example of how to create a note using curl");
|
||||||
|
// String noteLocation = this.mockMvc.perform(post("/crud")
|
||||||
|
// .contentType(MediaTypes.HAL_JSON)
|
||||||
|
// .content(objectMapper.writeValueAsString(note)))
|
||||||
|
// .andExpect(status().isCreated())
|
||||||
|
// .andExpect(header().string("Location", notNullValue()))
|
||||||
|
// .andReturn()
|
||||||
|
// .getResponse()
|
||||||
|
// .getHeader("Location");
|
||||||
|
// return noteLocation;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MvcResult getNote(String noteLocation) throws Exception {
|
||||||
|
// return this.mockMvc.perform(get(noteLocation))
|
||||||
|
// .andExpect(status().isOk())
|
||||||
|
// .andExpect(jsonPath("title", is(notNullValue())))
|
||||||
|
// .andExpect(jsonPath("body", is(notNullValue())))
|
||||||
|
// .andExpect(jsonPath("_links.crud", is(notNullValue())))
|
||||||
|
// .andReturn();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// String createTag() throws Exception, JsonProcessingException {
|
||||||
|
// Map<String, String> tag = new HashMap<String, String>();
|
||||||
|
// tag.put("name", "getting-started");
|
||||||
|
// String tagLocation = this.mockMvc.perform(post("/crud")
|
||||||
|
// .contentType(MediaTypes.HAL_JSON)
|
||||||
|
// .content(objectMapper.writeValueAsString(tag)))
|
||||||
|
// .andExpect(status().isCreated())
|
||||||
|
// .andExpect(header().string("Location", notNullValue()))
|
||||||
|
// .andReturn()
|
||||||
|
// .getResponse()
|
||||||
|
// .getHeader("Location");
|
||||||
|
// return tagLocation;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void getTag(String tagLocation) throws Exception {
|
||||||
|
// this.mockMvc.perform(get(tagLocation)).andExpect(status().isOk())
|
||||||
|
// .andExpect(jsonPath("name", is(notNullValue())))
|
||||||
|
// .andExpect(jsonPath("_links.tagged-notes", is(notNullValue())));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// String createTaggedNote(String tag) throws Exception {
|
||||||
|
// Map<String, Object> note = new HashMap<String, Object>();
|
||||||
|
// note.put("title", "Tagged note creation with cURL");
|
||||||
|
// note.put("body", "An example of how to create a tagged note using cURL");
|
||||||
|
// note.put("tags", Arrays.asList(tag));
|
||||||
|
//
|
||||||
|
// String noteLocation = this.mockMvc.perform(post("/notes")
|
||||||
|
// .contentType(MediaTypes.HAL_JSON)
|
||||||
|
// .content(objectMapper.writeValueAsString(note)))
|
||||||
|
// .andExpect(status().isCreated())
|
||||||
|
// .andExpect(header().string("Location", notNullValue()))
|
||||||
|
// .andReturn()
|
||||||
|
// .getResponse()
|
||||||
|
// .getHeader("Location");
|
||||||
|
// return noteLocation;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void getTags(String noteTagsLocation) throws Exception {
|
||||||
|
// this.mockMvc.perform(get(noteTagsLocation))
|
||||||
|
// .andExpect(status().isOk())
|
||||||
|
// .andExpect(jsonPath("_embedded.tags", hasSize(1)));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void tagExistingNote(String noteLocation, String tagLocation) throws Exception {
|
||||||
|
// Map<String, Object> update = new HashMap<String, Object>();
|
||||||
|
// update.put("tags", Arrays.asList(tagLocation));
|
||||||
|
// this.mockMvc.perform(patch(noteLocation)
|
||||||
|
// .contentType(MediaTypes.HAL_JSON)
|
||||||
|
// .content(objectMapper.writeValueAsString(update)))
|
||||||
|
// .andExpect(status().isNoContent());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MvcResult getTaggedExistingNote(String noteLocation) throws Exception {
|
||||||
|
// return this.mockMvc.perform(get(noteLocation)).andExpect(status().isOk()).andReturn();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void getTagsForExistingNote(String noteTagsLocation) throws Exception {
|
||||||
|
// this.mockMvc.perform(get(noteTagsLocation))
|
||||||
|
// .andExpect(status().isOk()).andExpect(jsonPath("_embedded.tags", hasSize(1)));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String getLink(MvcResult result, String rel)
|
||||||
|
// throws UnsupportedEncodingException {
|
||||||
|
// return JsonPath.parse(result.getResponse().getContentAsString()).read("_links." + rel + ".href");
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue