Merge remote-tracking branch 'origin/master'
Conflicts: RestEasy Example/src/main/java/com/baeldung/model/Movie.java RestEasy Example/src/main/webapp/WEB-INF/jboss-deployment-structure.xml RestEasy Example/src/test/java/com/baeldung/server/RestEasyClientTest.java RestEasy Example/src/test/resources/com/baeldung/server/movies/batman.json RestEasy Example/src/test/resources/com/baeldung/server/movies/transformer.json
This commit is contained in:
commit
3286ba0593
@ -5,196 +5,33 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "movie", propOrder = { "actors", "awards", "country", "director", "genre", "imdbId", "imdbRating", "imdbVotes", "language", "metascore", "plot", "poster", "rated", "released", "response", "runtime", "title", "type", "writer", "year" })
|
||||
@XmlType(name = "movie", propOrder = { "imdbId", "title" })
|
||||
public class Movie {
|
||||
|
||||
protected String actors;
|
||||
protected String awards;
|
||||
protected String country;
|
||||
protected String director;
|
||||
protected String genre;
|
||||
protected String imdbId;
|
||||
protected String imdbRating;
|
||||
protected String imdbVotes;
|
||||
protected String language;
|
||||
protected String metascore;
|
||||
protected String plot;
|
||||
protected String poster;
|
||||
protected String rated;
|
||||
protected String released;
|
||||
protected String response;
|
||||
protected String runtime;
|
||||
protected String title;
|
||||
protected String type;
|
||||
protected String writer;
|
||||
protected String year;
|
||||
|
||||
|
||||
public String getActors() {
|
||||
return actors;
|
||||
public Movie(String imdbId, String title) {
|
||||
this.imdbId = imdbId;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setActors(String value) {
|
||||
this.actors = value;
|
||||
}
|
||||
|
||||
public String getAwards() {
|
||||
return awards;
|
||||
}
|
||||
|
||||
public void setAwards(String value) {
|
||||
this.awards = value;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String value) {
|
||||
this.country = value;
|
||||
}
|
||||
|
||||
public String getDirector() {
|
||||
return director;
|
||||
}
|
||||
|
||||
public void setDirector(String value) {
|
||||
this.director = value;
|
||||
}
|
||||
|
||||
public String getGenre() {
|
||||
return genre;
|
||||
}
|
||||
|
||||
public void setGenre(String value) {
|
||||
this.genre = value;
|
||||
}
|
||||
public Movie() {}
|
||||
|
||||
public String getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbId(String value) {
|
||||
this.imdbId = value;
|
||||
}
|
||||
|
||||
public String getImdbRating() {
|
||||
return imdbRating;
|
||||
}
|
||||
|
||||
public void setImdbRating(String value) {
|
||||
this.imdbRating = value;
|
||||
}
|
||||
|
||||
public String getImdbVotes() {
|
||||
return imdbVotes;
|
||||
}
|
||||
|
||||
public void setImdbVotes(String value) {
|
||||
this.imdbVotes = value;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String value) {
|
||||
this.language = value;
|
||||
}
|
||||
|
||||
public String getMetascore() {
|
||||
return metascore;
|
||||
}
|
||||
|
||||
public void setMetascore(String value) {
|
||||
this.metascore = value;
|
||||
}
|
||||
|
||||
public String getPlot() {
|
||||
return plot;
|
||||
}
|
||||
|
||||
public void setPlot(String value) {
|
||||
this.plot = value;
|
||||
}
|
||||
|
||||
public String getPoster() {
|
||||
return poster;
|
||||
}
|
||||
|
||||
public void setPoster(String value) {
|
||||
this.poster = value;
|
||||
}
|
||||
|
||||
public String getRated() {
|
||||
return rated;
|
||||
}
|
||||
|
||||
public void setRated(String value) {
|
||||
this.rated = value;
|
||||
}
|
||||
|
||||
public String getReleased() {
|
||||
return released;
|
||||
}
|
||||
|
||||
public void setReleased(String value) {
|
||||
this.released = value;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(String value) {
|
||||
this.response = value;
|
||||
}
|
||||
|
||||
public String getRuntime() {
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public void setRuntime(String value) {
|
||||
this.runtime = value;
|
||||
public void setImdbId(String imdbId) {
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String value) {
|
||||
this.title = value;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String value) {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
public String getWriter() {
|
||||
return writer;
|
||||
}
|
||||
|
||||
public void setWriter(String value) {
|
||||
this.writer = value;
|
||||
}
|
||||
|
||||
public String getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(String value) {
|
||||
this.year = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Movie{" + "actors='" + actors + '\'' + ", awards='" + awards + '\'' + ", country='" + country + '\'' + ", director='" + director + '\'' + ", genre='" + genre + '\'' + ", imdbId='" + imdbId + '\'' + ", imdbRating='" + imdbRating + '\''
|
||||
+ ", imdbVotes='" + imdbVotes + '\'' + ", language='" + language + '\'' + ", metascore='" + metascore + '\'' + ", poster='" + poster + '\'' + ", rated='" + rated + '\'' + ", released='" + released + '\'' + ", response='" + response + '\''
|
||||
+ ", runtime='" + runtime + '\'' + ", title='" + title + '\'' + ", type='" + type + '\'' + ", writer='" + writer + '\'' + ", year='" + year + '\'' + '}';
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -218,4 +55,12 @@ public class Movie {
|
||||
result = 31 * result + (title != null ? title.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Movie{" +
|
||||
"imdbId='" + imdbId + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,11 @@
|
||||
<exclude-subsystems>
|
||||
<subsystem name="resteasy" />
|
||||
</exclude-subsystems>
|
||||
|
||||
<exclusions>
|
||||
<module name="javaee.api" />
|
||||
<module name="javax.ws.rs.api" />
|
||||
<module name="org.jboss.resteasy.resteasy-jaxrs" />
|
||||
</exclusions>
|
||||
|
||||
<local-last value="true" />
|
||||
</deployment>
|
||||
|
||||
</jboss-deployment-structure>
|
@ -130,7 +130,7 @@ public class RestEasyClientTest {
|
||||
|
||||
Response moviesResponse = simple.addMovie(batmanMovie);
|
||||
moviesResponse.close();
|
||||
batmanMovie.setImdbVotes("300,000");
|
||||
batmanMovie.setTitle("Batman Begins");
|
||||
moviesResponse = simple.updateMovie(batmanMovie);
|
||||
|
||||
if (moviesResponse.getStatus() != Response.Status.OK.getStatusCode()) {
|
||||
|
@ -1,22 +1,4 @@
|
||||
{
|
||||
"title": "Batman",
|
||||
"year": "1989",
|
||||
"rated": "PG-13",
|
||||
"released": "23 Jun 1989",
|
||||
"runtime": "126 min",
|
||||
"genre": "Action, Adventure",
|
||||
"director": "Tim Burton",
|
||||
"writer": "Bob Kane (Batman characters), Sam Hamm (story), Sam Hamm (screenplay), Warren Skaaren (screenplay)",
|
||||
"actors": "Michael Keaton, Jack Nicholson, Kim Basinger, Robert Wuhl",
|
||||
"plot": "The Dark Knight of Gotham City begins his war on crime with his first major enemy being the clownishly homicidal Joker.",
|
||||
"language": "English, French",
|
||||
"country": "USA, UK",
|
||||
"awards": "Won 1 Oscar. Another 9 wins & 22 nominations.",
|
||||
"poster": "http://ia.media-imdb.com/images/M/MV5BMTYwNjAyODIyMF5BMl5BanBnXkFtZTYwNDMwMDk2._V1_SX300.jpg",
|
||||
"metascore": "66",
|
||||
"imdbRating": "7.6",
|
||||
"imdbVotes": "256,000",
|
||||
"imdbId": "tt0096895",
|
||||
"type": "movie",
|
||||
"response": "True"
|
||||
"imdbId": "tt0096895"
|
||||
}
|
@ -1,22 +1,4 @@
|
||||
{
|
||||
"title": "Transformers",
|
||||
"year": "2007",
|
||||
"rated": "PG-13",
|
||||
"released": "03 Jul 2007",
|
||||
"runtime": "144 min",
|
||||
"genre": "Action, Adventure, Sci-Fi",
|
||||
"director": "Michael Bay",
|
||||
"writer": "Roberto Orci (screenplay), Alex Kurtzman (screenplay), John Rogers (story), Roberto Orci (story), Alex Kurtzman (story)",
|
||||
"actors": "Shia LaBeouf, Megan Fox, Josh Duhamel, Tyrese Gibson",
|
||||
"plot": "A long time ago, far away on the planet of Cybertron, a war is being waged between the noble Autobots (led by the wise Optimus Prime) and the devious Decepticons (commanded by the dreaded Megatron) for control over the Allspark, a mystical talisman that would grant unlimited power to whoever possesses it. The Autobots managed to smuggle the Allspark off the planet, but Megatron blasts off in search of it. He eventually tracks it to the planet of Earth (circa 1850), but his reckless desire for power sends him right into the Arctic Ocean, and the sheer cold forces him into a paralyzed state. His body is later found by Captain Archibald Witwicky, but before going into a comatose state Megatron uses the last of his energy to engrave into the Captain's glasses a map showing the location of the Allspark, and to send a transmission to Cybertron. Megatron is then carried away aboard the Captain's ship. A century later, Captain Witwicky's grandson Sam Witwicky (nicknamed Spike by his friends) buys his first car. To his shock, he discovers it to be Bumblebee, an Autobot in disguise who is to protect Spike, who possesses the Captain's glasses and the map engraved on them. But Bumblebee is not the only Transformer to have arrived on Earth - in the desert of Qatar, the Decepticons Blackout and Scorponok attack a U.S. military base, causing the Pentagon to send their special Sector Seven agents to capture all \"specimens of this alien race.\" Spike and his girlfriend Mikaela find themselves in the midst of a grand battle between the Autobots and the Decepticons, stretching from Hoover Dam all the way to Los Angeles. Meanwhile, deep inside Hoover Dam, the cryogenically stored body of Megatron awakens.",
|
||||
"language": "English, Spanish",
|
||||
"country": "USA",
|
||||
"awards": "Nominated for 3 Oscars. Another 18 wins & 40 nominations.",
|
||||
"poster": "http://ia.media-imdb.com/images/M/MV5BMTQwNjU5MzUzNl5BMl5BanBnXkFtZTYwMzc1MTI3._V1_SX300.jpg",
|
||||
"metascore": "61",
|
||||
"imdbRating": "7.1",
|
||||
"imdbVotes": "492,225",
|
||||
"imdbId": "tt0418279",
|
||||
"type": "movie",
|
||||
"response": "True"
|
||||
"imdbId": "tt0418279"
|
||||
}
|
@ -5,3 +5,6 @@
|
||||
### Relevant Articles:
|
||||
// - [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda)
|
||||
- [Java – Directory Size](http://www.baeldung.com/java-folder-size)
|
||||
- [Java – Try with Resources](http://www.baeldung.com/java-try-with-resources)
|
||||
- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips)
|
||||
- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator)
|
||||
|
@ -12,3 +12,4 @@
|
||||
- [Convert a Map to an Array, List or Set in Java](http://www.baeldung.com/convert-map-values-to-array-list-set)
|
||||
- [Java – Write to File](http://www.baeldung.com/java-write-to-file)
|
||||
- [Java Scanner](http://www.baeldung.com/java-scanner)
|
||||
- [Java Timer](http://www.baeldung.com/java-timer-and-timertask)
|
||||
|
@ -7,7 +7,6 @@
|
||||
- [Guava Collections Cookbook](http://www.baeldung.com/guava-collections)
|
||||
- [Guava Ordering Cookbook](http://www.baeldung.com/guava-order)
|
||||
- [Guava Functional Cookbook](http://www.baeldung.com/guava-functions-predicates)
|
||||
|
||||
- [Hamcrest Collections Cookbook](http://www.baeldung.com/hamcrest-collections-arrays)
|
||||
|
||||
- [Partition a List in Java](http://www.baeldung.com/java-list-split)
|
||||
- [Guava 18: What’s New?](http://www.baeldung.com/whats-new-in-guava-18)
|
||||
|
46
guava19/pom.xml
Normal file
46
guava19/pom.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?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>guava</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<configuration>
|
||||
<debug>true</debug>
|
||||
<optimize>true</optimize>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<showWarnings>true</showWarnings>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
36
guava19/src/main/java/com/baeldung/guava/entity/User.java
Normal file
36
guava19/src/main/java/com/baeldung/guava/entity/User.java
Normal file
@ -0,0 +1,36 @@
|
||||
package com.baeldung.guava.entity;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
|
||||
public class User{
|
||||
private long id;
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
public User(long id, String name, int age) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(User.class)
|
||||
.add("id", id)
|
||||
.add("name", name)
|
||||
.add("age", age)
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baeldung.guava;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class CharMatcherTest {
|
||||
@Test
|
||||
public void whenMatchingLetterOrString_ShouldReturnTrueForCorrectString() throws Exception {
|
||||
String inputString = "someString789";
|
||||
boolean result = CharMatcher.javaLetterOrDigit().matchesAllOf(inputString);
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCollapsingString_ShouldReturnStringWithDashesInsteadOfWhitespaces() throws Exception {
|
||||
String inputPhoneNumber = "8 123 456 123";
|
||||
String result = CharMatcher.whitespace().collapseFrom(inputPhoneNumber, '-');
|
||||
|
||||
assertEquals("8-123-456-123", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCountingDigitsInString_ShouldReturnActualCountOfDigits() throws Exception {
|
||||
String inputPhoneNumber = "8 123 456 123";
|
||||
int result = CharMatcher.digit().countIn(inputPhoneNumber);
|
||||
|
||||
assertEquals(10, result);
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.baeldung.guava;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
|
||||
import static org.hamcrest.core.AnyOf.anyOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class GuavaMiscUtilsTest {
|
||||
|
||||
@Test
|
||||
public void whenGettingLazyStackTrace_ListShouldBeReturned() throws Exception {
|
||||
IllegalArgumentException e = new IllegalArgumentException("Some argument is incorrect");
|
||||
|
||||
List<StackTraceElement> stackTraceElements = Throwables.lazyStackTrace(e);
|
||||
|
||||
assertTrue(stackTraceElements.size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multisetShouldCountHitsOfMultipleDuplicateObjects() throws Exception {
|
||||
List<String> userNames = Arrays.asList("David", "Eugene", "Alex", "Alex", "David", "David", "David");
|
||||
|
||||
Multiset<String> userNamesMultiset = HashMultiset.create(userNames);
|
||||
|
||||
assertEquals(7, userNamesMultiset.size());
|
||||
assertEquals(4, userNamesMultiset.count("David"));
|
||||
assertEquals(2, userNamesMultiset.count("Alex"));
|
||||
assertEquals(1, userNamesMultiset.count("Eugene"));
|
||||
assertThat(userNamesMultiset.elementSet(), anyOf(containsInAnyOrder("Alex", "David", "Eugene")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingNewConnectedRange_RangesShouldBeMerged() throws Exception {
|
||||
RangeSet<Integer> rangeSet = TreeRangeSet.create();
|
||||
|
||||
rangeSet.add(Range.closed(1, 10));
|
||||
rangeSet.add(Range.closed(5, 15));
|
||||
rangeSet.add(Range.closedOpen(10, 17));
|
||||
|
||||
assertTrue(rangeSet.encloses(Range.closedOpen(1, 17)));
|
||||
assertTrue(rangeSet.encloses(Range.closed(2, 3)));
|
||||
assertTrue(rangeSet.contains(15));
|
||||
assertFalse(rangeSet.contains(17));
|
||||
assertEquals(1, rangeSet.asDescendingSetOfRanges().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cartesianProductShouldReturnAllPossibleCombinations() throws Exception {
|
||||
List<String> first = Lists.newArrayList("value1", "value2");
|
||||
List<String> second = Lists.newArrayList("value3", "value4");
|
||||
|
||||
List<List<String>> cartesianProduct = Lists.cartesianProduct(first, second);
|
||||
|
||||
List<String> pair1 = Lists.newArrayList("value2", "value3");
|
||||
List<String> pair2 = Lists.newArrayList("value2", "value4");
|
||||
List<String> pair3 = Lists.newArrayList("value1", "value3");
|
||||
List<String> pair4 = Lists.newArrayList("value1", "value4");
|
||||
|
||||
assertThat(cartesianProduct, anyOf(containsInAnyOrder(pair1, pair2, pair3, pair4)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multisetShouldRemoveOccurrencesOfSpecifiedObjects() throws Exception {
|
||||
Multiset<String> multisetToModify = HashMultiset.create();
|
||||
Multiset<String> occurrencesToRemove = HashMultiset.create();
|
||||
|
||||
multisetToModify.add("John");
|
||||
multisetToModify.add("Max");
|
||||
multisetToModify.add("Alex");
|
||||
|
||||
occurrencesToRemove.add("Alex");
|
||||
occurrencesToRemove.add("John");
|
||||
|
||||
Multisets.removeOccurrences(multisetToModify, occurrencesToRemove);
|
||||
|
||||
assertEquals(1, multisetToModify.size());
|
||||
assertTrue(multisetToModify.contains("Max"));
|
||||
assertFalse(multisetToModify.contains("John"));
|
||||
assertFalse(multisetToModify.contains("Alex"));
|
||||
}
|
||||
}
|
34
guava19/src/test/java/com/baeldung/guava/HashingTest.java
Normal file
34
guava19/src/test/java/com/baeldung/guava/HashingTest.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.baeldung.guava;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.HashFunction;
|
||||
import com.google.common.hash.Hashing;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class HashingTest {
|
||||
@Test
|
||||
public void whenHashingInSha384_hashFunctionShouldBeReturned() throws Exception {
|
||||
int inputData = 15;
|
||||
|
||||
HashFunction hashFunction = Hashing.sha384();
|
||||
HashCode hashCode = hashFunction.hashInt(inputData);
|
||||
|
||||
assertEquals("0904b6277381dcfbdddd6b6c66e4e3e8f83d4690718d8e6f272c891f24773a12feaf8c449fa6e42240a621b2b5e3cda8",
|
||||
hashCode.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConcatenatingHashFunction_concatenatedHashShouldBeReturned() throws Exception {
|
||||
int inputData = 15;
|
||||
|
||||
HashFunction hashFunction = Hashing.concatenating(Hashing.crc32(), Hashing.crc32());
|
||||
HashFunction crc32Function = Hashing.crc32();
|
||||
|
||||
HashCode hashCode = hashFunction.hashInt(inputData);
|
||||
HashCode crc32HashCode = crc32Function.hashInt(inputData);
|
||||
|
||||
assertEquals(crc32HashCode.toString() + crc32HashCode.toString(), hashCode.toString());
|
||||
}
|
||||
}
|
45
guava19/src/test/java/com/baeldung/guava/TypeTokenTest.java
Normal file
45
guava19/src/test/java/com/baeldung/guava/TypeTokenTest.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.baeldung.guava;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TypeTokenTest {
|
||||
@Test
|
||||
public void whenCheckingIsAssignableFrom_shouldReturnTrueEvenIfGenericIsSpecified() throws Exception {
|
||||
ArrayList<String> stringList = new ArrayList<>();
|
||||
ArrayList<Integer> intList = new ArrayList<>();
|
||||
boolean isAssignableFrom = stringList.getClass().isAssignableFrom(intList.getClass());
|
||||
|
||||
assertTrue(isAssignableFrom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingIsSupertypeOf_shouldReturnFalseIfGenericIsSpecified() throws Exception {
|
||||
TypeToken<ArrayList<String>> listString = new TypeToken<ArrayList<String>>() {
|
||||
};
|
||||
TypeToken<ArrayList<Integer>> integerString = new TypeToken<ArrayList<Integer>>() {
|
||||
};
|
||||
|
||||
boolean isSupertypeOf = listString.isSupertypeOf(integerString);
|
||||
|
||||
assertFalse(isSupertypeOf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingIsSubtypeOf_shouldReturnTrueIfClassIsExtendedFrom() throws Exception {
|
||||
TypeToken<ArrayList<String>> stringList = new TypeToken<ArrayList<String>>() {
|
||||
};
|
||||
TypeToken<List> list = new TypeToken<List>() {
|
||||
};
|
||||
|
||||
boolean isSubtypeOf = stringList.isSubtypeOf(list);
|
||||
|
||||
assertTrue(isSubtypeOf);
|
||||
}
|
||||
}
|
@ -16,3 +16,4 @@
|
||||
- [HttpClient Basic Authentication](http://www.baeldung.com/httpclient-4-basic-authentication)
|
||||
- [Multipart Upload with HttpClient 4](http://www.baeldung.com/httpclient-multipart-upload)
|
||||
- [HttpAsyncClient Tutorial](http://www.baeldung.com/httpasyncclient-tutorial)
|
||||
- [HttpClient 4 Tutorial](http://www.baeldung.com/httpclient-guide)
|
||||
|
@ -10,3 +10,9 @@
|
||||
- [Jackson – Custom Deserializer](http://www.baeldung.com/jackson-deserialization)
|
||||
- [Jackson Exceptions – Problems and Solutions](http://www.baeldung.com/jackson-exception)
|
||||
- [Jackson Date](http://www.baeldung.com/jackson-serialize-dates)
|
||||
- [Jackson – Bidirectional Relationships](http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion)
|
||||
- [Jackson JSON Tutorial](http://www.baeldung.com/jackson)
|
||||
- [Jackson – Working with Maps and nulls](http://www.baeldung.com/jackson-map-null-values-or-null-key)
|
||||
- [Jackson – Decide What Fields Get Serialized/Deserializaed](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not)
|
||||
- [A Guide to Jackson Annotations](http://www.baeldung.com/jackson-annotations)
|
||||
- [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model)
|
||||
|
7
mockito-mocks-spring-beans/README.md
Normal file
7
mockito-mocks-spring-beans/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
=========
|
||||
|
||||
## Mockito Mocks into Spring Beans
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [Injecting Mockito Mocks into Spring Beans](http://www.baeldung.com/injecting-mocks-in-spring)
|
119
raml/modularization/api-before-modularization.raml
Normal file
119
raml/modularization/api-before-modularization.raml
Normal file
@ -0,0 +1,119 @@
|
||||
#%RAML 1.0
|
||||
title: API for REST Services used in the RAML tutorials on Baeldung.com
|
||||
documentation:
|
||||
- title: Overview
|
||||
- content: |
|
||||
This document defines the interface for the REST services
|
||||
used in the popular RAML Tutorial series at Baeldung.com.
|
||||
- title: Disclaimer:
|
||||
- content: |
|
||||
All names used in this definition are purely fictional.
|
||||
Any similarities between the names used in this tutorial and those of real persons, whether living or dead, are merely coincidental.
|
||||
- title: Copyright
|
||||
- content: Copyright 2016 by Baeldung.com. All rights reserved.
|
||||
version: v1
|
||||
protocols: [ HTTPS ]
|
||||
baseUri: http://rest-api.baeldung.com/api/{version}
|
||||
mediaType: application/json
|
||||
securedBy: basicAuth
|
||||
securitySchemes:
|
||||
- basicAuth:
|
||||
description: Each request must contain the headers necessary for
|
||||
basic authentication
|
||||
type: Basic Authentication
|
||||
describedBy:
|
||||
headers:
|
||||
Authorization:
|
||||
description: |
|
||||
Used to send the Base64 encoded "username:password"
|
||||
credentials
|
||||
type: string
|
||||
responses:
|
||||
401:
|
||||
description: |
|
||||
Unauthorized. Either the provided username and password
|
||||
combination is invalid, or the user is not allowed to
|
||||
access the content provided by the requested URL.
|
||||
types:
|
||||
Foo: !include types/Foo.raml
|
||||
Bar: !include types/Bar.raml
|
||||
Error: !include types/Error.raml
|
||||
resourceTypes:
|
||||
- collection:
|
||||
usage: Use this resourceType to represent a collection of items
|
||||
description: A collection of <<resourcePathName|!uppercamelcase>>
|
||||
get:
|
||||
description: |
|
||||
Get all <<resourcePathName|!uppercamelcase>>,
|
||||
optionally filtered
|
||||
is: [ hasResponseCollection ]
|
||||
post:
|
||||
description: |
|
||||
Create a new <<resourcePathName|!uppercamelcase|!singularize>>
|
||||
is: [ hasRequestItem ]
|
||||
- item:
|
||||
usage: Use this resourceType to represent any single item
|
||||
description: A single <<typeName>>
|
||||
get:
|
||||
description: Get a <<typeName>> by <<resourcePathName>>
|
||||
is: [ hasResponseItem, hasNotFound ]
|
||||
put:
|
||||
description: Update a <<typeName>> by <<resourcePathName>>
|
||||
is: [ hasRequestItem, hasResponseItem, hasNotFound ]
|
||||
delete:
|
||||
description: Delete a <<typeName>> by <<resourcePathName>>
|
||||
is: [ hasNotFound ]
|
||||
responses:
|
||||
204:
|
||||
traits:
|
||||
- hasRequestItem:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>
|
||||
- hasResponseItem:
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>
|
||||
example: !include examples/<<typeName>>.json
|
||||
- hasResponseCollection:
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>[]
|
||||
example: !include examples/<<typeName|!pluralize>>.json
|
||||
- hasNotFound:
|
||||
responses:
|
||||
404:
|
||||
body:
|
||||
application/json:
|
||||
type: Error
|
||||
example: !include examples/Error.json
|
||||
/foos:
|
||||
type: collection
|
||||
typeName: Foo
|
||||
get:
|
||||
queryParameters:
|
||||
name?: string
|
||||
ownerName?: string
|
||||
/{fooId}:
|
||||
type: item
|
||||
typeName: Foo
|
||||
/name/{name}:
|
||||
get:
|
||||
description: List all foos with a certain name
|
||||
typeName: Foo
|
||||
is: [ hasResponseCollection ]
|
||||
/bars:
|
||||
type: collection
|
||||
typeName: Bar
|
||||
/{barId}:
|
||||
type: item
|
||||
typeName: Bar
|
||||
/fooId/{fooId}:
|
||||
get:
|
||||
description: Get all bars for the matching fooId
|
||||
typeName: Bar
|
||||
is: [ hasResponseCollection ]
|
50
raml/modularization/api-with-libraries.raml
Normal file
50
raml/modularization/api-with-libraries.raml
Normal file
@ -0,0 +1,50 @@
|
||||
#%RAML 1.0
|
||||
title: API for REST Services used in the RAML tutorials on Baeldung.com
|
||||
documentation:
|
||||
- title: Overview
|
||||
- content: |
|
||||
This document defines the interface for the REST services
|
||||
used in the popular RAML Tutorial series at Baeldung.com.
|
||||
- title: Disclaimer:
|
||||
- content: |
|
||||
All names used in this definition are purely fictional.
|
||||
Any similarities between the names used in this tutorial and those of real persons, whether living or dead, are merely coincidental.
|
||||
- title: Copyright
|
||||
- content: Copyright 2016 by Baeldung.com. All rights reserved.
|
||||
uses:
|
||||
mySecuritySchemes: !include libraries/security.raml
|
||||
myDataTypes: !include libraries/dataTypes.raml
|
||||
myResourceTypes: !include libraries/resourceTypes.raml
|
||||
myTraits: !include libraries/traits.raml
|
||||
version: v1
|
||||
protocols: [ HTTPS ]
|
||||
baseUri: http://rest-api.baeldung.com/api/{version}
|
||||
mediaType: application/json
|
||||
securedBy: [ mySecuritySchemes.basicAuth ]
|
||||
/foos:
|
||||
type: myResourceTypes.collection
|
||||
typeName: myDataTypes.Foo
|
||||
get:
|
||||
queryParameters:
|
||||
name?: string
|
||||
ownerName?: string
|
||||
/{fooId}:
|
||||
type: myResourceTypes.item
|
||||
typeName: myDataTypes.Foo
|
||||
/name/{name}:
|
||||
get:
|
||||
description: List all foos with a certain name
|
||||
typeName: myDataTypes.Foo
|
||||
is: [ myTraits.hasResponseCollection ]
|
||||
/bars:
|
||||
type: myResourceTypes.collection
|
||||
typeName: myDataTypes.Bar
|
||||
/{barId}:
|
||||
type: myResourceTypes.item
|
||||
typeName: myDataTypes.Bar
|
||||
/fooId/{fooId}:
|
||||
get:
|
||||
description: Get all bars for the matching fooId
|
||||
type: myResourceTypes.item
|
||||
typeName: myDataTypes.Bar
|
||||
is: [ myTraits.hasResponseCollection ]
|
74
raml/modularization/api-with-typed-fragments.raml
Normal file
74
raml/modularization/api-with-typed-fragments.raml
Normal file
@ -0,0 +1,74 @@
|
||||
#%RAML 1.0
|
||||
title: API for REST Services used in the RAML tutorials on Baeldung.com
|
||||
documentation:
|
||||
- title: Overview
|
||||
- content: |
|
||||
This document defines the interface for the REST services
|
||||
used in the popular RAML Tutorial series at Baeldung.com.
|
||||
- title: Disclaimer:
|
||||
- content: |
|
||||
All names used in this definition are purely fictional.
|
||||
Any similarities between the names used in this tutorial and those of real persons, whether living or dead, are merely coincidental.
|
||||
- title: Copyright
|
||||
- content: Copyright 2016 by Baeldung.com. All rights reserved.
|
||||
version: v1
|
||||
protocols: [ HTTPS ]
|
||||
baseUri: http://rest-api.baeldung.com/api/{version}
|
||||
mediaType: application/json
|
||||
securedBy: [ basicAuth ]
|
||||
securitySchemes:
|
||||
- basicAuth:
|
||||
description: Each request must contain the headers necessary for
|
||||
basic authentication
|
||||
type: Basic Authentication
|
||||
describedBy:
|
||||
headers:
|
||||
Authorization:
|
||||
description: |
|
||||
Used to send the Base64 encoded "username:password"
|
||||
credentials
|
||||
type: string
|
||||
responses:
|
||||
401:
|
||||
description: |
|
||||
Unauthorized. Either the provided username and password
|
||||
combination is invalid, or the user is not allowed to
|
||||
access the content provided by the requested URL.
|
||||
types:
|
||||
Foo: !include types/Foo.raml
|
||||
Bar: !include types/Bar.raml
|
||||
Error: !include types/Error.raml
|
||||
resourceTypes:
|
||||
- collection: !include resourceTypes/collection.raml
|
||||
- item: !include resourceTypes/item.raml
|
||||
traits:
|
||||
- hasRequestItem: !include traits/hasRequestItem.raml
|
||||
- hasResponseItem: !include traits/hasResponseItem.raml
|
||||
- hasResponseCollection: !include traits/hasResponseCollection.raml
|
||||
- hasNotFound: !include traits/hasNotFound.raml
|
||||
/foos:
|
||||
type: collection
|
||||
typeName: Foo
|
||||
get:
|
||||
queryParameters:
|
||||
name?: string
|
||||
ownerName?: string
|
||||
/{fooId}:
|
||||
type: item
|
||||
typeName: Foo
|
||||
/name/{name}:
|
||||
get:
|
||||
description: List all foos with a certain name
|
||||
typeName: Foo
|
||||
is: [ hasResponseCollection ]
|
||||
/bars:
|
||||
type: collection
|
||||
typeName: Bar
|
||||
/{barId}:
|
||||
type: item
|
||||
typeName: Bar
|
||||
/fooId/{fooId}:
|
||||
get:
|
||||
description: Get all bars for the matching fooId
|
||||
typeName: Bar
|
||||
is: [ hasResponseCollection ]
|
47
raml/modularization/api.raml
Normal file
47
raml/modularization/api.raml
Normal file
@ -0,0 +1,47 @@
|
||||
#%RAML 1.0
|
||||
title: Baeldung Foo REST Services API
|
||||
uses:
|
||||
security: !include libraries/security.raml
|
||||
version: v1
|
||||
protocols: [ HTTPS ]
|
||||
baseUri: http://rest-api.baeldung.com/api/{version}
|
||||
mediaType: application/json
|
||||
securedBy: [ security.basicAuth ]
|
||||
types:
|
||||
Foo: !include types/Foo.raml
|
||||
Bar: !include types/Bar.raml
|
||||
Error: !include types/Error.raml
|
||||
resourceTypes:
|
||||
- collection: !include resourceTypes/collection.raml
|
||||
- item: !include resourceTypes/item.raml
|
||||
traits:
|
||||
- hasRequestItem: !include traits/hasRequestItem.raml
|
||||
- hasResponseItem: !include traits/hasResponseItem.raml
|
||||
- hasResponseCollection: !include traits/hasResponseCollection.raml
|
||||
- hasNotFound: !include traits/hasNotFound.raml
|
||||
/foos:
|
||||
type: collection
|
||||
typeName: Foo
|
||||
get:
|
||||
queryParameters:
|
||||
name?: string
|
||||
ownerName?: string
|
||||
/{fooId}:
|
||||
type: item
|
||||
typeName: Foo
|
||||
/name/{name}:
|
||||
get:
|
||||
description: List all foos with a certain name
|
||||
typeName: Foo
|
||||
is: [ hasResponseCollection ]
|
||||
/bars:
|
||||
type: collection
|
||||
typeName: Bar
|
||||
/{barId}:
|
||||
type: item
|
||||
typeName: Bar
|
||||
/fooId/{fooId}:
|
||||
get:
|
||||
description: Get all bars for the matching fooId
|
||||
typeName: Bar
|
||||
is: [ hasResponseCollection ]
|
6
raml/modularization/examples/Bar.json
Normal file
6
raml/modularization/examples/Bar.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "First Bar",
|
||||
"city" : "Austin",
|
||||
"fooId" : 2
|
||||
}
|
19
raml/modularization/examples/Bars.json
Normal file
19
raml/modularization/examples/Bars.json
Normal file
@ -0,0 +1,19 @@
|
||||
[
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "First Bar",
|
||||
"city" : "Austin",
|
||||
"fooId" : 2
|
||||
},
|
||||
{
|
||||
"id" : 2,
|
||||
"name" : "Second Bar",
|
||||
"city" : "Dallas",
|
||||
"fooId" : 1
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"name" : "Third Bar",
|
||||
"fooId" : 2
|
||||
}
|
||||
]
|
4
raml/modularization/examples/Error.json
Normal file
4
raml/modularization/examples/Error.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"message" : "Not found",
|
||||
"code" : 1001
|
||||
}
|
4
raml/modularization/examples/Foo.json
Normal file
4
raml/modularization/examples/Foo.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "First Foo"
|
||||
}
|
16
raml/modularization/examples/Foos.json
Normal file
16
raml/modularization/examples/Foos.json
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "First Foo",
|
||||
"ownerName" : "Jack Robinson"
|
||||
},
|
||||
{
|
||||
"id" : 2,
|
||||
"name" : "Second Foo"
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"name" : "Third Foo",
|
||||
"ownerName" : "Chuck Norris"
|
||||
}
|
||||
]
|
@ -0,0 +1,16 @@
|
||||
#%RAML 1.0 Extension
|
||||
# File located at:
|
||||
# /extensions/en_US/additionalResources.raml
|
||||
masterRef: /api.raml
|
||||
usage: This extension defines additional resources for version 2 of the API.
|
||||
version: v2
|
||||
/foos:
|
||||
/bar/{barId}:
|
||||
get:
|
||||
description: |
|
||||
Get the foo that is related to the bar having barId = {barId}
|
||||
typeName: Foo
|
||||
queryParameters:
|
||||
barId?: integer
|
||||
typeName: Foo
|
||||
is: [ hasResponseItem ]
|
19
raml/modularization/libraries/dataTypes.raml
Normal file
19
raml/modularization/libraries/dataTypes.raml
Normal file
@ -0,0 +1,19 @@
|
||||
#%RAML 1.0 Library
|
||||
# This is the file /libraries/dataTypes.raml
|
||||
usage: This library defines the data types for the API
|
||||
types:
|
||||
Foo:
|
||||
properties:
|
||||
id: integer
|
||||
name: string
|
||||
ownerName?: string
|
||||
Bar:
|
||||
properties:
|
||||
id: integer
|
||||
name: string
|
||||
city?: string
|
||||
fooId: integer
|
||||
Error:
|
||||
properties:
|
||||
code: integer
|
||||
message: string
|
32
raml/modularization/libraries/resourceTypes.raml
Normal file
32
raml/modularization/libraries/resourceTypes.raml
Normal file
@ -0,0 +1,32 @@
|
||||
#%RAML 1.0 Library
|
||||
# This is the file /libraries/resourceTypes.raml
|
||||
usage: This library defines the resource types for the API
|
||||
uses:
|
||||
myTraits: !include traits.raml
|
||||
resourceTypes:
|
||||
collection:
|
||||
usage: Use this resourceType to represent a collection of items
|
||||
description: A collection of <<resourcePathName|!uppercamelcase>>
|
||||
get:
|
||||
description: |
|
||||
Get all <<resourcePathName|!uppercamelcase>>,
|
||||
optionally filtered
|
||||
is: [ myTraits.hasResponseCollection ]
|
||||
post:
|
||||
description: |
|
||||
Create a new <<resourcePathName|!uppercamelcase|!singularize>>
|
||||
is: [ myTraits.hasRequestItem ]
|
||||
item:
|
||||
usage: Use this resourceType to represent any single item
|
||||
description: A single <<typeName>>
|
||||
get:
|
||||
description: Get a <<typeName>> by <<resourcePathName>>
|
||||
is: [ myTraits.hasResponseItem, myTraits.hasNotFound ]
|
||||
put:
|
||||
description: Update a <<typeName>> by <<resourcePathName>>
|
||||
is: [ myTraits.hasRequestItem, myTraits.hasResponseItem, myTraits.hasNotFound ]
|
||||
delete:
|
||||
description: Delete a <<typeName>> by <<resourcePathName>>
|
||||
is: [ myTraits.hasNotFound ]
|
||||
responses:
|
||||
204:
|
20
raml/modularization/libraries/securitySchemes.raml
Normal file
20
raml/modularization/libraries/securitySchemes.raml
Normal file
@ -0,0 +1,20 @@
|
||||
#%RAML 1.0 Library
|
||||
# This is the file /libraries/securitySchemes.raml
|
||||
securitySchemes:
|
||||
- basicAuth:
|
||||
description: Each request must contain the headers necessary for
|
||||
basic authentication
|
||||
type: Basic Authentication
|
||||
describedBy:
|
||||
headers:
|
||||
Authorization:
|
||||
description: |
|
||||
Used to send the Base64 encoded "username:password"
|
||||
credentials
|
||||
type: string
|
||||
responses:
|
||||
401:
|
||||
description: |
|
||||
Unauthorized. Either the provided username and password
|
||||
combination is invalid, or the user is not allowed to
|
||||
access the content provided by the requested URL.
|
33
raml/modularization/libraries/traits.raml
Normal file
33
raml/modularization/libraries/traits.raml
Normal file
@ -0,0 +1,33 @@
|
||||
#%RAML 1.0 Library
|
||||
# This is the file /libraries/traits.raml
|
||||
usage: This library defines some basic traits
|
||||
traits:
|
||||
hasRequestItem:
|
||||
usage: Use this trait for resources whose request body is a single item
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>
|
||||
hasResponseItem:
|
||||
usage: Use this trait for resources whose response body is a single item
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>
|
||||
example: !include /examples/<<typeName>>.json
|
||||
hasResponseCollection:
|
||||
usage: Use this trait for resources whose response body is a collection of items
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>[]
|
||||
example: !include /examples/<<typeName|!pluralize>>.json
|
||||
hasNotFound:
|
||||
usage: Use this trait for resources that could respond with a 404 status
|
||||
responses:
|
||||
404:
|
||||
body:
|
||||
application/json:
|
||||
type: Error
|
||||
example: !include /examples/Error.json
|
13
raml/modularization/overlays/es_ES/additionalResources.raml
Normal file
13
raml/modularization/overlays/es_ES/additionalResources.raml
Normal file
@ -0,0 +1,13 @@
|
||||
#%RAML 1.0 Overlay
|
||||
# Archivo situado en:
|
||||
# /overlays/es_ES/additionalResources.raml
|
||||
masterRef: /api.raml
|
||||
usage: |
|
||||
Se trata de un español demasiado que describe los recursos adicionales
|
||||
para la versión 2 del API.
|
||||
version: v2
|
||||
/foos:
|
||||
/bar/{barId}:
|
||||
get:
|
||||
description: |
|
||||
Obtener el foo que se relaciona con el bar tomando barId = {barId}
|
23
raml/modularization/overlays/es_ES/documentationItems.raml
Normal file
23
raml/modularization/overlays/es_ES/documentationItems.raml
Normal file
@ -0,0 +1,23 @@
|
||||
#%RAML 1.0 Overlay
|
||||
# File located at (archivo situado en):
|
||||
# /overlays/es_ES/documentationItems.raml
|
||||
masterRef: /api.raml
|
||||
usage: |
|
||||
To provide user documentation and other descriptive text in Spanish
|
||||
(Para proporcionar la documentación del usuario y otro texto descriptivo en español)
|
||||
title: API para servicios REST utilizados en los tutoriales RAML en Baeldung.com
|
||||
documentation:
|
||||
- title: Descripción general
|
||||
- content: |
|
||||
Este documento define la interfaz para los servicios REST
|
||||
utilizados en la popular serie de RAML Tutorial en Baeldung.com
|
||||
- title: Renuncia
|
||||
- content: |
|
||||
Todos los nombres usados en esta definición son pura ficción.
|
||||
Cualquier similitud entre los nombres utilizados en este tutorial
|
||||
y los de las personas reales, ya sea vivo o muerto,
|
||||
no son más que coincidenta.
|
||||
|
||||
- title: Derechos de autor
|
||||
- content: |
|
||||
Derechos de autor 2016 por Baeldung.com. Todos los derechos reservados.
|
12
raml/modularization/resourceTypes/collection.raml
Normal file
12
raml/modularization/resourceTypes/collection.raml
Normal file
@ -0,0 +1,12 @@
|
||||
#%RAML 1.0 ResourceType
|
||||
usage: Use this resourceType to represent a collection of items
|
||||
description: A collection of <<resourcePathName|!uppercamelcase>>
|
||||
get:
|
||||
description: |
|
||||
Get all <<resourcePathName|!uppercamelcase>>,
|
||||
optionally filtered
|
||||
is: [ hasResponseCollection ]
|
||||
post:
|
||||
description: |
|
||||
Create a new <<resourcePathName|!uppercamelcase|!singularize>>
|
||||
is: [ hasRequestItem ]
|
14
raml/modularization/resourceTypes/item.raml
Normal file
14
raml/modularization/resourceTypes/item.raml
Normal file
@ -0,0 +1,14 @@
|
||||
#%RAML 1.0 ResourceType
|
||||
usage: Use this resourceType to represent any single item
|
||||
description: A single <<typeName>>
|
||||
get:
|
||||
description: Get a <<typeName>> by <<resourcePathName>>
|
||||
is: [ hasResponseItem, hasNotFound ]
|
||||
put:
|
||||
description: Update a <<typeName>> by <<resourcePathName>>
|
||||
is: [ hasRequestItem, hasResponseItem, hasNotFound ]
|
||||
delete:
|
||||
description: Delete a <<typeName>> by <<resourcePathName>>
|
||||
is: [ hasNotFound ]
|
||||
responses:
|
||||
204:
|
8
raml/modularization/traits/hasNotFound.raml
Normal file
8
raml/modularization/traits/hasNotFound.raml
Normal file
@ -0,0 +1,8 @@
|
||||
#%RAML 1.0 Trait
|
||||
usage: Use this trait for resources that could respond with a 404 status
|
||||
responses:
|
||||
404:
|
||||
body:
|
||||
application/json:
|
||||
type: Error
|
||||
example: !include /examples/Error.json
|
5
raml/modularization/traits/hasRequestItem.raml
Normal file
5
raml/modularization/traits/hasRequestItem.raml
Normal file
@ -0,0 +1,5 @@
|
||||
#%RAML 1.0 Trait
|
||||
usage: Use this trait for resources whose request body is a single item
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>
|
8
raml/modularization/traits/hasResponseCollection.raml
Normal file
8
raml/modularization/traits/hasResponseCollection.raml
Normal file
@ -0,0 +1,8 @@
|
||||
#%RAML 1.0 Trait
|
||||
usage: Use this trait for resources whose response body is a collection of items
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>[]
|
||||
example: !include /examples/<<typeName|!pluralize>>.json
|
8
raml/modularization/traits/hasResponseItem.raml
Normal file
8
raml/modularization/traits/hasResponseItem.raml
Normal file
@ -0,0 +1,8 @@
|
||||
#%RAML 1.0 Trait
|
||||
usage: Use this trait for resources whose response body is a single item
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
type: <<typeName>>
|
||||
example: !include /examples/<<typeName>>.json
|
7
raml/modularization/types/Bar.raml
Normal file
7
raml/modularization/types/Bar.raml
Normal file
@ -0,0 +1,7 @@
|
||||
#%RAML 1.0 DataType
|
||||
|
||||
properties:
|
||||
id: integer
|
||||
name: string
|
||||
city?: string
|
||||
fooId: integer
|
5
raml/modularization/types/Error.raml
Normal file
5
raml/modularization/types/Error.raml
Normal file
@ -0,0 +1,5 @@
|
||||
#%RAML 1.0 DataType
|
||||
|
||||
properties:
|
||||
code: integer
|
||||
message: string
|
6
raml/modularization/types/Foo.raml
Normal file
6
raml/modularization/types/Foo.raml
Normal file
@ -0,0 +1,6 @@
|
||||
#%RAML 1.0 DataType
|
||||
|
||||
properties:
|
||||
id: integer
|
||||
name: string
|
||||
ownerName?: string
|
@ -8,3 +8,4 @@ This project is used to replicate Spring Exceptions only.
|
||||
### Relevant articles:
|
||||
- [Properties with Spring](http://www.baeldung.com/2012/02/06/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage
|
||||
- [Spring Profiles](http://www.baeldung.com/spring-profiles)
|
||||
- [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor)
|
||||
|
@ -1 +1,7 @@
|
||||
=========
|
||||
|
||||
## Spring Batch
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to Spring Batch](http://www.baeldung.com/introduction-to-spring-batch)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to Spring Data Cassandra](http://www.baeldung.com/spring-data-cassandra-tutorial)
|
||||
- [Using the CassandraTemplate from Spring Data](http://www.baeldung.com/spring-data-cassandratemplate-cqltemplate)
|
||||
|
||||
### Build the Project with Tests Running
|
||||
```
|
||||
|
11
spring-data-mongodb/README.md
Normal file
11
spring-data-mongodb/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
=========
|
||||
|
||||
## Spring Data MongoDB
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [A Guide to Queries in Spring Data MongoDB](http://www.baeldung.com/queries-in-spring-data-mongodb)
|
||||
- [Spring Data MongoDB – Indexes, Annotations and Converters](http://www.baeldung.com/spring-data-mongodb-index-annotations-converter)
|
||||
- [Custom Cascading in Spring Data MongoDB](http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb)
|
||||
- [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs)
|
||||
- [Introduction to Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-tutorial)
|
7
spring-freemarker/README.md
Normal file
7
spring-freemarker/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
=========
|
||||
|
||||
## Using FreeMarker in Spring MVC
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to Using FreeMarker in Spring MVC](http://www.baeldung.com/freemarker-in-spring-mvc-tutorial)
|
@ -7,6 +7,7 @@
|
||||
- [The DAO with Spring 3 and Hibernate](http://www.baeldung.com/2011/12/02/the-persistence-layer-with-spring-3-1-and-hibernate/)
|
||||
- [Hibernate Pagination](http://www.baeldung.com/hibernate-pagination)
|
||||
- [Sorting with Hibernate](http://www.baeldung.com/hibernate-sort)
|
||||
- [Auditing with JPA, Hibernate, and Spring Data JPA](http://www.baeldung.com/database-auditing-jpa)
|
||||
|
||||
|
||||
### Quick Start
|
||||
|
@ -9,3 +9,4 @@
|
||||
- [The DAO with JPA and Spring](http://www.baeldung.com/spring-dao-jpa)
|
||||
- [JPA Pagination](http://www.baeldung.com/jpa-pagination)
|
||||
- [Sorting with JPA](http://www.baeldung.com/jpa-sort)
|
||||
- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases)
|
||||
|
6
spring-katharsis/README.md
Normal file
6
spring-katharsis/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
=========
|
||||
|
||||
## Java Web Application
|
||||
|
||||
### Relevant Articles:
|
||||
- [JSON API in a Java Web Application](http://www.baeldung.com/json-api-java-spring-web-app)
|
@ -4,3 +4,7 @@
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [Spring Bean Annotations](http://www.baeldung.com/spring-bean-annotations)
|
||||
- [Introduction to Pointcut Expressions in Spring](http://www.baeldung.com/spring-aop-pointcut-tutorial)
|
||||
- [Introduction to Advice Types in Spring](http://www.baeldung.com/spring-aop-advice-tutorial)
|
||||
- [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial)
|
||||
|
32
spring-openid/.classpath
Normal file
32
spring-openid/.classpath
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
48
spring-openid/.project
Normal file
48
spring-openid/.project
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>spring-openid</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
68
spring-openid/pom.xml
Normal file
68
spring-openid/pom.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<?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>org.baeldung</groupId>
|
||||
<artifactId>spring-openid</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>spring-openid</name>
|
||||
<description>Spring OpenID sample project</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.3.2.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-jwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
</project>
|
@ -0,0 +1,51 @@
|
||||
package org.baeldung.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.client.OAuth2ClientContext;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
||||
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
|
||||
|
||||
@Configuration
|
||||
@EnableOAuth2Client
|
||||
public class GoogleOpenIdConnectConfig {
|
||||
@Value("${google.clientId}")
|
||||
private String clientId;
|
||||
|
||||
@Value("${google.clientSecret}")
|
||||
private String clientSecret;
|
||||
|
||||
@Value("${google.accessTokenUri}")
|
||||
private String accessTokenUri;
|
||||
|
||||
@Value("${google.userAuthorizationUri}")
|
||||
private String userAuthorizationUri;
|
||||
|
||||
@Value("${google.redirectUri}")
|
||||
private String redirectUri;
|
||||
|
||||
@Bean
|
||||
public OAuth2ProtectedResourceDetails googleOpenId() {
|
||||
final AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
|
||||
details.setClientId(clientId);
|
||||
details.setClientSecret(clientSecret);
|
||||
details.setAccessTokenUri(accessTokenUri);
|
||||
details.setUserAuthorizationUri(userAuthorizationUri);
|
||||
details.setScope(Arrays.asList("openid", "email"));
|
||||
details.setPreEstablishedRedirectUri(redirectUri);
|
||||
details.setUseCurrentUri(false);
|
||||
return details;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OAuth2RestTemplate googleOpenIdTemplate(final OAuth2ClientContext clientContext) {
|
||||
final OAuth2RestTemplate template = new OAuth2RestTemplate(googleOpenId(), clientContext);
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package org.baeldung.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Controller
|
||||
public class HomeController {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@RequestMapping("/")
|
||||
@ResponseBody
|
||||
public final String home() {
|
||||
final String username = SecurityContextHolder.getContext().getAuthentication().getName();
|
||||
logger.info(username);
|
||||
return "Welcome, " + username;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.baeldung.config;
|
||||
|
||||
import org.baeldung.security.OpenIdConnectFilter;
|
||||
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.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Autowired
|
||||
private OAuth2RestTemplate restTemplate;
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring().antMatchers("/resources/**");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenIdConnectFilter myFilter() {
|
||||
final OpenIdConnectFilter filter = new OpenIdConnectFilter("/google-login");
|
||||
filter.setRestTemplate(restTemplate);
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.addFilterAfter(new OAuth2ClientContextFilter(), AbstractPreAuthenticatedProcessingFilter.class)
|
||||
.addFilterAfter(myFilter(), OAuth2ClientContextFilter.class)
|
||||
.httpBasic().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/google-login"))
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
// .antMatchers("/","/index*").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
;
|
||||
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package org.baeldung.config;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringOpenidApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringOpenidApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package org.baeldung.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.jwt.Jwt;
|
||||
import org.springframework.security.jwt.JwtHelper;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestOperations;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class OpenIdConnectFilter extends AbstractAuthenticationProcessingFilter {
|
||||
public OAuth2RestOperations restTemplate;
|
||||
|
||||
public OpenIdConnectFilter(String defaultFilterProcessesUrl) {
|
||||
super(defaultFilterProcessesUrl);
|
||||
setAuthenticationManager(new NoopAuthenticationManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||
|
||||
OAuth2AccessToken accessToken;
|
||||
try {
|
||||
accessToken = restTemplate.getAccessToken();
|
||||
} catch (final OAuth2Exception e) {
|
||||
throw new BadCredentialsException("Could not obtain access token", e);
|
||||
}
|
||||
try {
|
||||
final String idToken = accessToken.getAdditionalInformation().get("id_token").toString();
|
||||
final Jwt tokenDecoded = JwtHelper.decode(idToken);
|
||||
System.out.println("===== : " + tokenDecoded.getClaims());
|
||||
|
||||
final Map<String, String> authInfo = new ObjectMapper().readValue(tokenDecoded.getClaims(), Map.class);
|
||||
|
||||
final OpenIdConnectUserDetails user = new OpenIdConnectUserDetails(authInfo, accessToken);
|
||||
return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
||||
} catch (final InvalidTokenException e) {
|
||||
throw new BadCredentialsException("Could not obtain user details from token", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setRestTemplate(OAuth2RestTemplate restTemplate2) {
|
||||
restTemplate = restTemplate2;
|
||||
|
||||
}
|
||||
|
||||
private static class NoopAuthenticationManager implements AuthenticationManager {
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
throw new UnsupportedOperationException("No authentication should be done with this AuthenticationManager");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package org.baeldung.security;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
|
||||
public class OpenIdConnectUserDetails implements UserDetails {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String userId;
|
||||
private String username;
|
||||
private OAuth2AccessToken token;
|
||||
|
||||
public OpenIdConnectUserDetails(Map<String, String> userInfo, OAuth2AccessToken token) {
|
||||
this.userId = userInfo.get("sub");
|
||||
this.username = userInfo.get("email");
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public OAuth2AccessToken getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(OAuth2AccessToken token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
6
spring-openid/src/main/resources/application.properties
Normal file
6
spring-openid/src/main/resources/application.properties
Normal file
@ -0,0 +1,6 @@
|
||||
server.port=8081
|
||||
google.clientId=497324626536-d6fphsh1qpl2o6j2j66nukajrfqc0rtq.apps.googleusercontent.com
|
||||
google.clientSecret=vtueZycMsrRjjCjnY6JzbEZT
|
||||
google.accessTokenUri=https://www.googleapis.com/oauth2/v3/token
|
||||
google.userAuthorizationUri=https://accounts.google.com/o/oauth2/auth
|
||||
google.redirectUri=http://localhost:8081/google-login
|
@ -7,3 +7,4 @@
|
||||
- [Spring @RequestMapping](http://www.baeldung.com/spring-requestmapping)
|
||||
- [Http Message Converters with the Spring Framework](http://www.baeldung.com/spring-httpmessageconverter-rest)
|
||||
- [Redirect in Spring](http://www.baeldung.com/spring-redirect-and-forward)
|
||||
- [Returning Custom Status Codes from Spring Controllers](http://www.baeldung.com/spring-mvc-controller-custom-http-status-code)
|
||||
|
@ -7,7 +7,14 @@
|
||||
- [Spring Security Registration Tutorial](http://www.baeldung.com/spring-security-registration)
|
||||
- [The Registration Process With Spring Security](http://www.baeldung.com/registration-with-spring-mvc-and-spring-security)
|
||||
- [Registration – Activate a New Account by Email](http://www.baeldung.com/registration-verify-user-by-email)
|
||||
|
||||
- [Registration with Spring Security – Password Encoding](http://www.baeldung.com/spring-security-registration-password-encoding-bcrypt)
|
||||
- [Spring Security – Roles and Privileges](http://www.baeldung.com/role-and-privilege-for-spring-security-registration)
|
||||
- [Prevent Brute Force Authentication Attempts with Spring Security](http://www.baeldung.com/spring-security-block-brute-force-authentication-attempts)
|
||||
- [Spring Security – Reset Your Password](http://www.baeldung.com/spring-security-registration-i-forgot-my-password)
|
||||
- [Spring Security Registration – Resend Verification Email](http://www.baeldung.com/spring-security-registration-verification-email)
|
||||
- [The Registration API becomes RESTful](http://www.baeldung.com/registration-restful-api)
|
||||
- [Registration – Password Strength and Rules](http://www.baeldung.com/registration-password-strength-and-rules)
|
||||
- [Updating your Password](http://www.baeldung.com/updating-your-password/)
|
||||
|
||||
### Build the Project
|
||||
```
|
||||
|
@ -5,7 +5,7 @@
|
||||
### Relevant Article:
|
||||
- [Spring Security - security none, filters none, access permitAll](http://www.baeldung.com/security-none-filters-none-access-permitAll)
|
||||
- [Spring Security Basic Authentication](http://www.baeldung.com/spring-security-basic-authentication)
|
||||
|
||||
- [Intro to Spring Security LDAP](http://www.baeldung.com/spring-security-ldap)
|
||||
|
||||
### Notes
|
||||
- the project uses Spring Boot - simply run 'SampleLDAPApplication.java' to start up Spring Boot with a Tomcat container and embedded LDAP server.
|
||||
|
@ -13,7 +13,14 @@
|
||||
- [Integration Testing with the Maven Cargo plugin](http://www.baeldung.com/2011/10/16/how-to-set-up-integration-testing-with-the-maven-cargo-plugin/)
|
||||
- [Introduction to Spring Data JPA](http://www.baeldung.com/2011/12/22/the-persistence-layer-with-spring-data-jpa/)
|
||||
- [Project Configuration with Spring](http://www.baeldung.com/2012/03/12/project-configuration-with-spring/)
|
||||
|
||||
- [REST Query Language with Spring and JPA Criteria](http://www.baeldung.com/rest-search-language-spring-jpa-criteria)
|
||||
- [REST Query Language with Spring Data JPA Specifications](http://www.baeldung.com/rest-api-search-language-spring-data-specifications)
|
||||
- [REST Query Language with Spring Data JPA and QueryDSL](http://www.baeldung.com/rest-api-search-language-spring-data-querydsl)
|
||||
- [REST Query Language – Advanced Search Operations](http://www.baeldung.com/rest-api-query-search-language-more-operations)
|
||||
- [Metrics for your Spring REST API](http://www.baeldung.com/spring-rest-api-metrics)
|
||||
- [REST Query Language with RSQL](http://www.baeldung.com/rest-api-search-language-rsql-fiql)
|
||||
- [Spring RestTemplate Tutorial](http://www.baeldung.com/rest-template)
|
||||
- [A Guide to CSRF Protection in Spring Security](http://www.baeldung.com/spring-security-csrf)
|
||||
|
||||
### Build the Project
|
||||
```
|
||||
|
@ -5,3 +5,5 @@
|
||||
|
||||
### Relevant Articles:
|
||||
- [Spring REST Service Security](http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/)
|
||||
- [Setting Up Swagger 2 with a Spring REST API](http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api)
|
||||
- [Custom Error Message Handling for REST API](http://www.baeldung.com/global-error-handler-in-a-spring-rest-api)
|
||||
|
7
spring-zuul/README.md
Normal file
7
spring-zuul/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
=========
|
||||
|
||||
## Spring REST with a Zuul
|
||||
|
||||
|
||||
### Relevant Articles:
|
||||
- [Spring REST with a Zuul Proxy](http://www.baeldung.com/spring-rest-with-zuul-proxy)
|
Loading…
x
Reference in New Issue
Block a user