-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create example that uses springboot (#1782)
- Loading branch information
Showing
8 changed files
with
466 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Wikipedia Example with Springboot | ||
================================= | ||
|
||
This is an example of advanced json response parsing, including pagination. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
Copyright 2012-2022 The Feign Authors | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
in compliance with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software distributed under the License | ||
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
or implied. See the License for the specific language governing permissions and limitations under | ||
the License. | ||
--> | ||
<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/maven-v4_0_0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>io.github.openfeign</groupId> | ||
<artifactId>parent</artifactId> | ||
<version>12.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<groupId>io.github.openfeign</groupId> | ||
<artifactId>feign-example-wikipedia-with-springboot</artifactId> | ||
<packaging>jar</packaging> | ||
<name>Wikipedia Example</name> | ||
|
||
<properties> | ||
<main.basedir>${project.basedir}/..</main.basedir> | ||
</properties> | ||
|
||
<dependencyManagement> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.cloud</groupId> | ||
<artifactId>spring-cloud-dependencies</artifactId> | ||
<version>2021.0.4</version> | ||
<type>pom</type> | ||
<scope>import</scope> | ||
</dependency> | ||
</dependencies> | ||
</dependencyManagement> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.github.openfeign</groupId> | ||
<artifactId>feign-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.github.openfeign</groupId> | ||
<artifactId>feign-gson</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.cloud</groupId> | ||
<artifactId>spring-cloud-starter-openfeign</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-exec</artifactId> | ||
<version>1.3</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<defaultGoal>package</defaultGoal> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-maven-plugin</artifactId> | ||
<configuration> | ||
<mainClass>example.wikipedia.WikipediaApplication</mainClass> | ||
<layout>ZIP</layout> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>repackage</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
|
||
<plugin> | ||
<groupId>org.skife.maven</groupId> | ||
<artifactId>really-executable-jar-maven-plugin</artifactId> | ||
<version>1.5.0</version> | ||
<configuration> | ||
<programFile>wikipedia</programFile> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>really-executable-jar</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-failsafe-plugin</artifactId> | ||
<version>${maven-surefire-plugin.version}</version> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>integration-test</goal> | ||
<goal>verify</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
97 changes: 97 additions & 0 deletions
97
example-wikipedia-with-springboot/src/main/java/example/wikipedia/ResponseAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright 2012-2022 The Feign Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package example.wikipedia; | ||
|
||
import com.google.gson.TypeAdapter; | ||
import com.google.gson.stream.JsonReader; | ||
import com.google.gson.stream.JsonWriter; | ||
import java.io.IOException; | ||
|
||
abstract class ResponseAdapter<X> extends TypeAdapter<WikipediaClient.Response<X>> { | ||
|
||
/** | ||
* name of the key inside the {@code query} dict which holds the elements desired. ex. {@code | ||
* pages}. | ||
*/ | ||
protected abstract String query(); | ||
|
||
/** | ||
* Parses the contents of a result object. | ||
* <p/> | ||
* <br> | ||
* ex. If {@link #query()} is {@code pages}, then this would parse the value of each key in the | ||
* dict {@code pages}. In the example below, this would first start at line {@code 3}. | ||
* <p/> | ||
* | ||
* <pre> | ||
* "pages": { | ||
* "2576129": { | ||
* "pageid": 2576129, | ||
* "title": "Burchell's zebra", | ||
* --snip-- | ||
* </pre> | ||
*/ | ||
protected abstract X build(JsonReader reader) throws IOException; | ||
|
||
/** | ||
* the wikipedia api doesn't use json arrays, rather a series of nested objects. | ||
*/ | ||
@Override | ||
public WikipediaClient.Response<X> read(JsonReader reader) throws IOException { | ||
WikipediaClient.Response<X> pages = new WikipediaClient.Response<X>(); | ||
reader.beginObject(); | ||
while (reader.hasNext()) { | ||
String nextName = reader.nextName(); | ||
if ("query".equals(nextName)) { | ||
reader.beginObject(); | ||
while (reader.hasNext()) { | ||
if (query().equals(reader.nextName())) { | ||
reader.beginObject(); | ||
while (reader.hasNext()) { | ||
// each element is in form: "id" : { object } | ||
// this advances the pointer to the value and skips the key | ||
reader.nextName(); | ||
reader.beginObject(); | ||
pages.add(build(reader)); | ||
reader.endObject(); | ||
} | ||
reader.endObject(); | ||
} else { | ||
reader.skipValue(); | ||
} | ||
} | ||
reader.endObject(); | ||
} else if ("continue".equals(nextName)) { | ||
reader.beginObject(); | ||
while (reader.hasNext()) { | ||
if ("gsroffset".equals(reader.nextName())) { | ||
pages.nextOffset = reader.nextLong(); | ||
} else { | ||
reader.skipValue(); | ||
} | ||
} | ||
reader.endObject(); | ||
} else { | ||
reader.skipValue(); | ||
} | ||
} | ||
reader.endObject(); | ||
return pages; | ||
} | ||
|
||
@Override | ||
public void write(JsonWriter out, WikipediaClient.Response<X> response) throws IOException { | ||
throw new UnsupportedOperationException(); | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
example-wikipedia-with-springboot/src/main/java/example/wikipedia/WikipediaApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* Copyright 2012-2022 The Feign Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package example.wikipedia; | ||
|
||
import example.wikipedia.WikipediaClient.Page; | ||
import example.wikipedia.WikipediaClient.Response; | ||
import example.wikipedia.WikipediaClient.Wikipedia; | ||
import java.util.Iterator; | ||
import javax.annotation.PostConstruct; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.cloud.openfeign.EnableFeignClients; | ||
|
||
@SpringBootApplication | ||
@EnableFeignClients | ||
public class WikipediaApplication { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(WikipediaApplication.class, args).start();; | ||
} | ||
|
||
@Autowired | ||
private Wikipedia wikipedia; | ||
|
||
@PostConstruct | ||
public void run() { | ||
System.out.println("Let's search for PTAL!"); | ||
Iterator<Page> pages = lazySearch(wikipedia, "PTAL"); | ||
while (pages.hasNext()) { | ||
System.out.println(pages.next().title); | ||
} | ||
} | ||
|
||
/** | ||
* this will lazily continue searches, making new http calls as necessary. | ||
* | ||
* @param wikipedia used to search | ||
* @param query see {@link Wikipedia#search(String)}. | ||
*/ | ||
static Iterator<Page> lazySearch(final Wikipedia wikipedia, final String query) { | ||
final Response<Page> first = wikipedia.search(query); | ||
if (first.nextOffset == null) { | ||
return first.iterator(); | ||
} | ||
return new Iterator<Page>() { | ||
Iterator<Page> current = first.iterator(); | ||
Long nextOffset = first.nextOffset; | ||
|
||
@Override | ||
public boolean hasNext() { | ||
while (!current.hasNext() && nextOffset != null) { | ||
System.out.println("Wow.. even more results than " + nextOffset); | ||
Response<Page> nextPage = wikipedia.resumeSearch(query, nextOffset); | ||
current = nextPage.iterator(); | ||
nextOffset = nextPage.nextOffset; | ||
} | ||
return current.hasNext(); | ||
} | ||
|
||
@Override | ||
public Page next() { | ||
return current.next(); | ||
} | ||
|
||
@Override | ||
public void remove() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
}; | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
example-wikipedia-with-springboot/src/main/java/example/wikipedia/WikipediaClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright 2012-2022 The Feign Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
package example.wikipedia; | ||
|
||
import java.util.ArrayList; | ||
import org.springframework.cloud.openfeign.FeignClient; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestMethod; | ||
|
||
public class WikipediaClient { | ||
|
||
|
||
|
||
@FeignClient(value = "jplaceholder", url = "https://en.wikipedia.org/", | ||
configuration = WikipediaClientConfiguration.class) | ||
public static interface Wikipedia { | ||
|
||
|
||
@RequestMapping(method = RequestMethod.GET, | ||
value = "/w/api.php?action=query&continue=&generator=search&prop=info&format=json&gsrsearch={search}") | ||
Response<Page> search(@PathVariable("search") String search); | ||
|
||
|
||
@RequestMapping(method = RequestMethod.GET, | ||
value = "/w/api.php?action=query&continue=&generator=search&prop=info&format=json&gsrsearch={search}&gsroffset={offset}") | ||
Response<Page> resumeSearch(@PathVariable("search") String search, | ||
@PathVariable("offset") long offset); | ||
} | ||
|
||
static class Page { | ||
|
||
long id; | ||
String title; | ||
} | ||
|
||
public static class Response<X> extends ArrayList<X> { | ||
|
||
/** | ||
* when present, the position to resume the list. | ||
*/ | ||
Long nextOffset; | ||
} | ||
} |
Oops, something went wrong.