Browse Source
* Add Moshi * Update README.md --------- Co-authored-by: Vikramaditya Chhapwale <cvikramad@gmail.com>pull/2185/head
Vik
1 year ago
committed by
GitHub
13 changed files with 707 additions and 0 deletions
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
Moshi Codec |
||||
=================== |
||||
|
||||
This module adds support for encoding and decoding JSON via the Moshi library. |
||||
|
||||
Add `MoshiEncoder` and/or `MoshiDecoder` to your `Feign.Builder` like so: |
||||
|
||||
```java |
||||
GitHub github = Feign.builder() |
||||
.encoder(new MoshiEncoder()) |
||||
.decoder(new MoshiDecoder()) |
||||
.target(GitHub.class, "https://api.github.com"); |
||||
``` |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
|
||||
Copyright 2012-2023 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/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<parent> |
||||
<groupId>io.github.openfeign</groupId> |
||||
<artifactId>parent</artifactId> |
||||
<version>13.0-SNAPSHOT</version> |
||||
</parent> |
||||
|
||||
<artifactId>feign-moshi</artifactId> |
||||
<name>Feign Moshi</name> |
||||
<description>Feign Moshi</description> |
||||
|
||||
<properties> |
||||
<main.basedir>${project.basedir}/..</main.basedir> |
||||
</properties> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>${project.groupId}</groupId> |
||||
<artifactId>feign-core</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.squareup.moshi</groupId> |
||||
<artifactId>moshi</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
<version>${guava.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>${project.groupId}</groupId> |
||||
<artifactId>feign-core</artifactId> |
||||
<type>test-jar</type> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.google.common.io.CharStreams; |
||||
import com.squareup.moshi.JsonAdapter; |
||||
import com.squareup.moshi.JsonDataException; |
||||
import com.squareup.moshi.JsonEncodingException; |
||||
import com.squareup.moshi.Moshi; |
||||
import feign.Response; |
||||
import feign.Util; |
||||
import feign.codec.Decoder; |
||||
import java.io.IOException; |
||||
import java.io.Reader; |
||||
import java.lang.reflect.Type; |
||||
import static feign.Util.UTF_8; |
||||
import static feign.Util.ensureClosed; |
||||
|
||||
public class MoshiDecoder implements Decoder { |
||||
private final Moshi moshi; |
||||
|
||||
public MoshiDecoder(Moshi moshi) { |
||||
this.moshi = moshi; |
||||
} |
||||
|
||||
public MoshiDecoder() { |
||||
this.moshi = new Moshi.Builder().build(); |
||||
} |
||||
|
||||
public MoshiDecoder(Iterable<JsonAdapter<?>> adapters) { |
||||
this(MoshiFactory.create(adapters)); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Object decode(Response response, Type type) throws IOException { |
||||
JsonAdapter<Object> jsonAdapter = moshi.adapter(type); |
||||
|
||||
if (response.status() == 404 || response.status() == 204) |
||||
return Util.emptyValueOf(type); |
||||
if (response.body() == null) |
||||
return null; |
||||
|
||||
Reader reader = response.body().asReader(UTF_8); |
||||
|
||||
try { |
||||
return parseJson(jsonAdapter, reader); |
||||
} catch (JsonDataException e) { |
||||
if (e.getCause() != null && e.getCause() instanceof IOException) { |
||||
throw (IOException) e.getCause(); |
||||
} |
||||
throw e; |
||||
} finally { |
||||
ensureClosed(reader); |
||||
} |
||||
} |
||||
|
||||
private Object parseJson(JsonAdapter<Object> jsonAdapter, Reader reader) throws IOException { |
||||
String targetString = CharStreams.toString(reader); |
||||
return jsonAdapter.fromJson(targetString); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.squareup.moshi.JsonAdapter; |
||||
import com.squareup.moshi.Moshi; |
||||
import feign.RequestTemplate; |
||||
import feign.codec.Encoder; |
||||
import java.lang.reflect.Type; |
||||
import java.util.Collections; |
||||
|
||||
public class MoshiEncoder implements Encoder { |
||||
|
||||
private final Moshi moshi; |
||||
|
||||
public MoshiEncoder() { |
||||
this.moshi = new Moshi.Builder().build(); |
||||
} |
||||
|
||||
public MoshiEncoder(Moshi moshi) { |
||||
this.moshi = moshi; |
||||
} |
||||
|
||||
public MoshiEncoder(Iterable<JsonAdapter<?>> adapters) { |
||||
this(MoshiFactory.create(adapters)); |
||||
} |
||||
|
||||
@Override |
||||
public void encode(Object object, Type bodyType, RequestTemplate template) { |
||||
JsonAdapter<Object> jsonAdapter = moshi.adapter(bodyType).indent(" "); |
||||
template.body(jsonAdapter.toJson(object)); |
||||
} |
||||
} |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.squareup.moshi.JsonAdapter; |
||||
import com.squareup.moshi.Moshi; |
||||
|
||||
public class MoshiFactory { |
||||
private MoshiFactory() {} |
||||
|
||||
/** |
||||
* Registers JsonAdapter by implicit type. Adds one to read numbers in a {@code Map<String, |
||||
* Object>} as Integers. |
||||
*/ |
||||
static Moshi create(Iterable<JsonAdapter<?>> adapters) { |
||||
Moshi.Builder builder = new Moshi.Builder(); |
||||
|
||||
for (JsonAdapter<?> adapter : adapters) { |
||||
builder.add(adapter.getClass(), adapter); |
||||
} |
||||
|
||||
return builder.build(); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.squareup.moshi.JsonAdapter; |
||||
import com.squareup.moshi.Moshi; |
||||
import feign.Request; |
||||
import feign.Response; |
||||
import feign.Util; |
||||
import org.junit.Test; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
import static feign.Util.UTF_8; |
||||
import static feign.assertj.FeignAssertions.assertThat; |
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertNull; |
||||
|
||||
public class MoshiDecoderTest { |
||||
|
||||
@Test |
||||
public void decodes() throws Exception { |
||||
|
||||
class Zone extends LinkedHashMap<String, Object> { |
||||
|
||||
Zone(String name) { |
||||
this(name, null); |
||||
} |
||||
|
||||
Zone(String name, String id) { |
||||
put("name", name); |
||||
if (id != null) { |
||||
put("id", id); |
||||
} |
||||
} |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
} |
||||
|
||||
List<Zone> zones = new LinkedList<>(); |
||||
zones.add(new Zone("denominator.io.")); |
||||
zones.add(new Zone("denominator.io.", "ABCD")); |
||||
|
||||
Response response = Response.builder() |
||||
.status(200) |
||||
.reason("OK") |
||||
.headers(Collections.emptyMap()) |
||||
.request(Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, |
||||
Util.UTF_8)) |
||||
.body(zonesJson, UTF_8) |
||||
.build(); |
||||
|
||||
assertEquals(zones, |
||||
new MoshiDecoder().decode(response, List.class)); |
||||
} |
||||
|
||||
private String zonesJson = ""//
|
||||
+ "[\n"//
|
||||
+ " {\n"//
|
||||
+ " \"name\": \"denominator.io.\"\n"//
|
||||
+ " },\n"//
|
||||
+ " {\n"//
|
||||
+ " \"name\": \"denominator.io.\",\n"//
|
||||
+ " \"id\": \"ABCD\"\n"//
|
||||
+ " }\n"//
|
||||
+ "]\n"; |
||||
|
||||
private final String videoGamesJson = "{\n " + |
||||
" \"hero\": {\n " + |
||||
" \"enemy\": \"Bowser\",\n " + |
||||
" \"name\": \"Luigi\"\n " + |
||||
"},\n " + |
||||
"\"name\": \"Super Mario\"\n " + |
||||
"}"; |
||||
|
||||
@Test |
||||
public void nullBodyDecodesToNull() throws Exception { |
||||
Response response = Response.builder() |
||||
.status(204) |
||||
.reason("OK") |
||||
.headers(Collections.emptyMap()) |
||||
.request(Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, |
||||
Util.UTF_8)) |
||||
.build(); |
||||
assertNull(new MoshiDecoder().decode(response, String.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void emptyBodyDecodesToNull() throws Exception { |
||||
Response response = Response.builder() |
||||
.status(204) |
||||
.reason("OK") |
||||
.headers(Collections.emptyMap()) |
||||
.request(Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, |
||||
Util.UTF_8)) |
||||
.body(new byte[0]) |
||||
.build(); |
||||
assertNull(new MoshiDecoder().decode(response, String.class)); |
||||
} |
||||
|
||||
|
||||
/** Enabled via {@link feign.Feign.Builder#dismiss404()} */ |
||||
@Test |
||||
public void notFoundDecodesToEmpty() throws Exception { |
||||
Response response = Response.builder() |
||||
.status(404) |
||||
.reason("NOT FOUND") |
||||
.headers(Collections.emptyMap()) |
||||
.request(Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, |
||||
Util.UTF_8)) |
||||
.build(); |
||||
assertThat((byte[]) new MoshiDecoder().decode(response, byte[].class)).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void customDecoder() throws Exception { |
||||
final UpperZoneJSONAdapter upperZoneAdapter = new UpperZoneJSONAdapter(); |
||||
|
||||
MoshiDecoder decoder = new MoshiDecoder(Collections.singleton(upperZoneAdapter)); |
||||
|
||||
List<Zone> zones = new LinkedList<>(); |
||||
zones.add(new Zone("DENOMINATOR.IO.")); |
||||
zones.add(new Zone("DENOMINATOR.IO.", "ABCD")); |
||||
|
||||
Response response = |
||||
Response.builder() |
||||
.status(200) |
||||
.reason("OK") |
||||
.headers(Collections.emptyMap()) |
||||
.request( |
||||
Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, |
||||
Util.UTF_8)) |
||||
.body(zonesJson, UTF_8) |
||||
.build(); |
||||
|
||||
assertEquals(zones, decoder.decode(response, UpperZoneJSONAdapter.class)); |
||||
} |
||||
|
||||
@Test |
||||
public void customObjectDecoder() throws Exception { |
||||
final JsonAdapter<VideoGame> videoGameJsonAdapter = |
||||
new Moshi.Builder().build().adapter(VideoGame.class); |
||||
|
||||
MoshiDecoder decoder = new MoshiDecoder(Collections.singleton(videoGameJsonAdapter)); |
||||
|
||||
VideoGame videoGame = new VideoGame("Super Mario", "Luigi", "Bowser"); |
||||
|
||||
Response response = |
||||
Response.builder() |
||||
.status(200) |
||||
.reason("OK") |
||||
.headers(Collections.emptyMap()) |
||||
.request( |
||||
Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, |
||||
Util.UTF_8)) |
||||
.body(videoGamesJson, UTF_8) |
||||
.build(); |
||||
|
||||
VideoGame actual = (VideoGame) decoder.decode(response, videoGameJsonAdapter.getClass()); |
||||
|
||||
assertThat(actual) |
||||
.isEqualToComparingFieldByFieldRecursively(videoGame); |
||||
} |
||||
} |
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.squareup.moshi.JsonAdapter; |
||||
import com.squareup.moshi.Moshi; |
||||
import feign.RequestTemplate; |
||||
import org.junit.Test; |
||||
import java.util.*; |
||||
import static feign.assertj.FeignAssertions.assertThat; |
||||
|
||||
public class MoshiEncoderTest { |
||||
|
||||
@Test |
||||
public void encodesMapObjectNumericalValuesAsInteger() { |
||||
Map<String, Object> map = new LinkedHashMap<>(); |
||||
map.put("foo", 1); |
||||
|
||||
RequestTemplate template = new RequestTemplate(); |
||||
new MoshiEncoder().encode(map, Map.class, template); |
||||
|
||||
assertThat(template).hasBody("{\n" //
|
||||
+ " \"foo\": 1\n" //
|
||||
+ "}"); |
||||
} |
||||
|
||||
@Test |
||||
public void encodesFormParams() { |
||||
|
||||
Map<String, Object> form = new LinkedHashMap<>(); |
||||
form.put("foo", 1); |
||||
form.put("bar", Arrays.asList(2, 3)); |
||||
|
||||
RequestTemplate template = new RequestTemplate(); |
||||
|
||||
new MoshiEncoder().encode(form, Map.class, template); |
||||
|
||||
assertThat(template).hasBody("{\n" //
|
||||
+ " \"foo\": 1,\n" //
|
||||
+ " \"bar\": [\n" //
|
||||
+ " 2,\n" //
|
||||
+ " 3\n" //
|
||||
+ " ]\n" //
|
||||
+ "}"); |
||||
} |
||||
|
||||
@Test |
||||
public void customEncoder() { |
||||
final UpperZoneJSONAdapter upperZoneAdapter = new UpperZoneJSONAdapter(); |
||||
|
||||
MoshiEncoder encoder = new MoshiEncoder(Collections.singleton(upperZoneAdapter)); |
||||
|
||||
List<Zone> zones = new LinkedList<>(); |
||||
zones.add(new Zone("denominator.io.")); |
||||
zones.add(new Zone("denominator.io.", "abcd")); |
||||
|
||||
RequestTemplate template = new RequestTemplate(); |
||||
encoder.encode(zones, UpperZoneJSONAdapter.class, template); |
||||
|
||||
assertThat(template).hasBody("" //
|
||||
+ "[\n" //
|
||||
+ " {\n" //
|
||||
+ " \"name\": \"DENOMINATOR.IO.\"\n" //
|
||||
+ " },\n" //
|
||||
+ " {\n" //
|
||||
+ " \"name\": \"DENOMINATOR.IO.\",\n" //
|
||||
+ " \"id\": \"ABCD\"\n" //
|
||||
+ " }\n" //
|
||||
+ "]"); |
||||
} |
||||
|
||||
@Test |
||||
public void customObjectEncoder() { |
||||
final JsonAdapter<VideoGame> videoGameJsonAdapter = |
||||
new Moshi.Builder().build().adapter(VideoGame.class); |
||||
MoshiEncoder encoder = new MoshiEncoder(Collections.singleton(videoGameJsonAdapter)); |
||||
|
||||
VideoGame videoGame = new VideoGame("Super Mario", "Luigi", "Bowser"); |
||||
|
||||
RequestTemplate template = new RequestTemplate(); |
||||
encoder.encode(videoGame, videoGameJsonAdapter.getClass(), template); |
||||
|
||||
|
||||
assertThat(template) |
||||
.hasBody("{\n" + |
||||
" \"hero\": {\n" + |
||||
" \"enemy\": \"Bowser\",\n" + |
||||
" \"name\": \"Luigi\"\n" + |
||||
" },\n" + |
||||
" \"name\": \"Super Mario\"\n" + |
||||
"}"); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.squareup.moshi.*; |
||||
import java.io.IOException; |
||||
import java.util.LinkedList; |
||||
import java.util.Map; |
||||
|
||||
class UpperZoneJSONAdapter extends JsonAdapter<LinkedList<Zone>> { |
||||
|
||||
@ToJson |
||||
public void toJson(JsonWriter out, LinkedList<Zone> value) throws IOException { |
||||
out.beginArray(); |
||||
for (Zone zone : value) { |
||||
out.beginObject(); |
||||
for (Map.Entry<String, Object> entry : zone.entrySet()) { |
||||
out.name(entry.getKey()).value(entry.getValue().toString().toUpperCase()); |
||||
} |
||||
out.endObject(); |
||||
} |
||||
out.endArray(); |
||||
} |
||||
|
||||
@FromJson |
||||
public LinkedList<Zone> fromJson(JsonReader in) throws IOException { |
||||
LinkedList<Zone> zones = new LinkedList<>(); |
||||
in.beginArray(); |
||||
while (in.hasNext()) { |
||||
in.beginObject(); |
||||
Zone zone = new Zone(); |
||||
while (in.hasNext()) { |
||||
zone.put(in.nextName(), in.nextString().toUpperCase()); |
||||
} |
||||
in.endObject(); |
||||
zones.add(zone); |
||||
} |
||||
in.endArray(); |
||||
return zones; |
||||
} |
||||
} |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import com.squareup.moshi.Json; |
||||
|
||||
public class VideoGame { |
||||
|
||||
@Json(name = "name") |
||||
public final String name; |
||||
|
||||
@Json(name = "hero") |
||||
public final Hero hero; |
||||
|
||||
public VideoGame(String name, String hero, String enemy) { |
||||
this.name = name; |
||||
this.hero = new Hero(hero, enemy); |
||||
} |
||||
|
||||
static class Hero { |
||||
@Json(name = "name") |
||||
public final String name; |
||||
|
||||
@Json(name = "enemy") |
||||
public final String enemyName; |
||||
|
||||
Hero(String name, String enemyName) { |
||||
this.name = name; |
||||
this.enemyName = enemyName; |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi; |
||||
|
||||
import java.util.LinkedHashMap; |
||||
|
||||
public class Zone extends LinkedHashMap<String, Object> { |
||||
|
||||
Zone() { |
||||
// for reflective instantiation.
|
||||
} |
||||
|
||||
Zone(String name) { |
||||
this(name, null); |
||||
} |
||||
|
||||
Zone(String name, String id) { |
||||
put("name", name); |
||||
if (id != null) { |
||||
put("id", id); |
||||
} |
||||
} |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
} |
||||
|
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
/* |
||||
* Copyright 2012-2023 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 feign.moshi.examples; |
||||
|
||||
import feign.Feign; |
||||
import feign.Param; |
||||
import feign.RequestLine; |
||||
import feign.moshi.MoshiDecoder; |
||||
import feign.moshi.MoshiEncoder; |
||||
import java.util.List; |
||||
|
||||
public class GithubExample { |
||||
|
||||
public static void main(String... args) { |
||||
GitHub github = Feign.builder().encoder(new MoshiEncoder()) |
||||
.decoder(new MoshiDecoder()) |
||||
.target(GitHub.class, "https://api.github.com"); |
||||
|
||||
System.out.println("Let's fetch and print a list of the contributors to this library."); |
||||
List<Contributor> contributors = github.contributors("netflix", "feign"); |
||||
for (Contributor contributor : contributors) { |
||||
System.out.println(contributor.login + " (" + contributor.contributions + ")"); |
||||
} |
||||
} |
||||
|
||||
interface GitHub { |
||||
|
||||
@RequestLine("GET /repos/{owner}/{repo}/contributors") |
||||
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo); |
||||
} |
||||
|
||||
static class Contributor { |
||||
|
||||
String login; |
||||
int contributions; |
||||
} |
||||
} |
Loading…
Reference in new issue