Skip to content

Commit 3aec1a5

Browse files
author
ricardo
committed
Added test for decoding generics with JAXB
1 parent 1cfec6f commit 3aec1a5

File tree

2 files changed

+58
-14
lines changed

2 files changed

+58
-14
lines changed

jaxb/src/main/java/feign/jaxb/JAXBDecoder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
package feign.jaxb;
1515

1616
import java.io.IOException;
17-
import java.lang.reflect.ParameterizedType;
1817
import java.lang.reflect.Type;
18+
import java.lang.reflect.ParameterizedType;
1919
import javax.xml.bind.JAXBException;
2020
import javax.xml.bind.Unmarshaller;
2121
import javax.xml.parsers.ParserConfigurationException;
@@ -37,13 +37,13 @@
3737
*
3838
* <pre>
3939
* JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder()
40-
* .withMarshallerJAXBEncoding("UTF-8")
41-
* .withMarshallerSchemaLocation("http://apihost http://apihost/schema.xsd")
40+
* .withMarshallerJAXBEncoding(&quot;UTF-8&quot;)
41+
* .withMarshallerSchemaLocation(&quot;http://apihost http://apihost/schema.xsd&quot;)
4242
* .build();
43-
*
43+
*
4444
* api = Feign.builder()
4545
* .decoder(new JAXBDecoder(jaxbFactory))
46-
* .target(MyApi.class, "http://api");
46+
* .target(MyApi.class, &quot;http://api&quot;);
4747
* </pre>
4848
* <p>
4949
* The JAXBContextFactory should be reused across requests as it caches the created JAXB contexts.

jaxb/src/test/java/feign/jaxb/JAXBCodecTest.java

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ public void encodesXml() throws Exception {
4747
new JAXBEncoder(new JAXBContextFactory.Builder().build())
4848
.encode(mock, MockObject.class, template);
4949

50-
assertThat(template).hasBody(
51-
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><mockObject><value>Test</value></mockObject>");
50+
assertThat(template)
51+
.hasBody(
52+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><mockObject><value>Test</value></mockObject>");
5253
}
5354

5455
@Test
@@ -122,11 +123,14 @@ public void encodesXmlWithCustomJAXBNoNamespaceSchemaLocation() throws Exception
122123
RequestTemplate template = new RequestTemplate();
123124
encoder.encode(mock, MockObject.class, template);
124125

125-
assertThat(template).hasBody("<?xml version=\"1.0\" encoding=\"UTF-8\" " +
126-
"standalone=\"yes\"?><mockObject xsi:noNamespaceSchemaLocation=\"http://apihost/schema.xsd\" "
127-
+
128-
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
129-
"<value>Test</value></mockObject>");
126+
assertThat(template)
127+
.hasBody(
128+
"<?xml version=\"1.0\" encoding=\"UTF-8\" "
129+
+
130+
"standalone=\"yes\"?><mockObject xsi:noNamespaceSchemaLocation=\"http://apihost/schema.xsd\" "
131+
+
132+
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
133+
"<value>Test</value></mockObject>");
130134
}
131135

132136
@Test
@@ -178,9 +182,11 @@ public void decodesXml() throws Exception {
178182

179183
@Test
180184
public void doesntDecodeParameterizedTypes() throws Exception {
181-
thrown.expect(UnsupportedOperationException.class);
185+
thrown.expect(feign.codec.DecodeException.class);
182186
thrown.expectMessage(
183-
"JAXB only supports decoding raw types. Found java.util.Map<java.lang.String, ?>");
187+
"java.util.Map is an interface, and JAXB can't handle interfaces.\n"
188+
+ "\tthis problem is related to the following location:\n"
189+
+ "\t\tat java.util.Map");
184190

185191
class ParameterizedHolder {
186192

@@ -199,6 +205,44 @@ class ParameterizedHolder {
199205
new JAXBDecoder(new JAXBContextFactory.Builder().build()).decode(response, parameterized);
200206
}
201207

208+
@XmlRootElement
209+
static class Box<T> {
210+
211+
@XmlElement
212+
private T t;
213+
214+
public void set(T t) {
215+
this.t = t;
216+
}
217+
218+
}
219+
220+
@Test
221+
public void decodeAnnotatedParameterizedTypes() throws Exception {
222+
JAXBContextFactory jaxbContextFactory =
223+
new JAXBContextFactory.Builder().withMarshallerFormattedOutput(true).build();
224+
225+
Encoder encoder = new JAXBEncoder(jaxbContextFactory);
226+
227+
Box<String> boxStr = new Box<>();
228+
boxStr.set("hi");
229+
Box<Box<String>> boxBoxStr = new Box<>();
230+
boxBoxStr.set(boxStr);
231+
RequestTemplate template = new RequestTemplate();
232+
encoder.encode(boxBoxStr, Box.class, template);
233+
234+
Response response = Response.builder()
235+
.status(200)
236+
.reason("OK")
237+
.request(Request.create("GET", "/api", Collections.emptyMap(), null, Util.UTF_8))
238+
.headers(Collections.<String, Collection<String>>emptyMap())
239+
.body(template.body())
240+
.build();
241+
242+
new JAXBDecoder(new JAXBContextFactory.Builder().build()).decode(response, Box.class);
243+
244+
}
245+
202246
/** Enabled via {@link feign.Feign.Builder#decode404()} */
203247
@Test
204248
public void notFoundDecodesToEmpty() throws Exception {

0 commit comments

Comments
 (0)