Skip to content

Commit 12e61b9

Browse files
chrismanningspencergibb
authored andcommitted
Adds Builder class to JAXBDecoder for disabling namespace-awareness. (OpenFeign#471)
Makes the SAX parser namespace aware by default (as it was prior to OpenFeign#415). Fixes OpenFeign#456
1 parent de85d2e commit 12e61b9

3 files changed

Lines changed: 46 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
### Version 9.4
2+
* Adds Builder class to JAXBDecoder for disabling namespace-awareness (defaults to true).
3+
14
### Version 9.3
25
* Adds `FallbackFactory`, allowing access to the cause of a Hystrix fallback
36
* Adds support for encoded parameters via `@Param(encoded = true)`

jaxb/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,12 @@ Response response = Feign.builder()
1616
.decoder(new JAXBDecoder(jaxbFactory))
1717
.target(Response.class, "https://apihost");
1818
```
19+
20+
`JAXBDecoder` can also be created with a builder to allow overriding some default parser options:
21+
22+
```java
23+
JAXBDecoder jaxbDecoder = new JAXBDecoder.Builder()
24+
.withJAXBContextFactory(jaxbFactory)
25+
.withNamespaceAware(false) // true by default
26+
.build();
27+
```

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,16 @@
5050
public class JAXBDecoder implements Decoder {
5151

5252
private final JAXBContextFactory jaxbContextFactory;
53+
private final boolean namespaceAware;
5354

5455
public JAXBDecoder(JAXBContextFactory jaxbContextFactory) {
5556
this.jaxbContextFactory = jaxbContextFactory;
57+
this.namespaceAware = true;
58+
}
59+
60+
private JAXBDecoder(Builder builder) {
61+
this.jaxbContextFactory = builder.jaxbContextFactory;
62+
this.namespaceAware = builder.namespaceAware;
5663
}
5764

5865
@Override
@@ -72,6 +79,7 @@ public Object decode(Response response, Type type) throws IOException {
7279
saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
7380
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
7481
saxParserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
82+
saxParserFactory.setNamespaceAware(namespaceAware);
7583

7684
Source source = new SAXSource(saxParserFactory.newSAXParser().getXMLReader(), new InputSource(response.body().asInputStream()));
7785
Unmarshaller unmarshaller = jaxbContextFactory.createUnmarshaller((Class) type);
@@ -88,4 +96,30 @@ public Object decode(Response response, Type type) throws IOException {
8896
}
8997
}
9098
}
99+
100+
public static class Builder {
101+
private boolean namespaceAware = true;
102+
private JAXBContextFactory jaxbContextFactory;
103+
104+
/**
105+
* Controls whether the underlying XML parser is namespace aware.
106+
* Default is true.
107+
*/
108+
public Builder withNamespaceAware(boolean namespaceAware) {
109+
this.namespaceAware = namespaceAware;
110+
return this;
111+
}
112+
113+
public Builder withJAXBContextFactory(JAXBContextFactory jaxbContextFactory) {
114+
this.jaxbContextFactory = jaxbContextFactory;
115+
return this;
116+
}
117+
118+
public JAXBDecoder build() {
119+
if (jaxbContextFactory == null) {
120+
throw new IllegalStateException("JAXBContextFactory must be non-null");
121+
}
122+
return new JAXBDecoder(this);
123+
}
124+
}
91125
}

0 commit comments

Comments
 (0)