MCPcopy Index your code
hub / github.com/OpenFeign/feign / SAXDecoder

Class SAXDecoder

sax/src/main/java/feign/sax/SAXDecoder.java:56–179  ·  view source on GitHub ↗

Decodes responses using SAX, which is supported both in normal JVM environments, as well Android. Basic example with with Feign.Builder api = Feign.builder() .decoder(SAXDecoder.builder() .registerContentHandler(ContentHandlerForFoo.class) .registerCon

Source from the content-addressed store, hash-verified

54 * </pre>
55 */
56public class SAXDecoder implements Decoder {
57
58 private final Map<Type, ContentHandlerWithResult.Factory<?>> handlerFactories;
59
60 private SAXDecoder(Map<Type, ContentHandlerWithResult.Factory<?>> handlerFactories) {
61 this.handlerFactories = handlerFactories;
62 }
63
64 public static Builder builder() {
65 return new Builder();
66 }
67
68 @Override
69 public Object decode(Response response, Type type) throws IOException, DecodeException {
70 if (response.status() == 404 || response.status() == 204) return Util.emptyValueOf(type);
71 if (response.body() == null) return null;
72 ContentHandlerWithResult.Factory<?> handlerFactory = handlerFactories.get(type);
73 checkState(
74 handlerFactory != null,
75 "type %s not in configured handlers %s",
76 type,
77 handlerFactories.keySet());
78 ContentHandlerWithResult<?> handler = handlerFactory.create();
79 try {
80 XMLReader xmlReader = XMLReaderFactory.createXMLReader();
81 xmlReader.setFeature("http://xml.org/sax/features/namespaces", false);
82 xmlReader.setFeature("http://xml.org/sax/features/validation", false);
83 /* Explicitly control sax configuration to prevent XXE attacks */
84 xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
85 xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
86 xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
87 xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
88 xmlReader.setContentHandler(handler);
89 InputStream inputStream = response.body().asInputStream();
90 try {
91 xmlReader.parse(new InputSource(inputStream));
92 } finally {
93 ensureClosed(inputStream);
94 }
95 return handler.result();
96 } catch (SAXException e) {
97 throw new DecodeException(response.status(), e.getMessage(), response.request(), e);
98 }
99 }
100
101 /** Implementations are not intended to be shared across requests. */
102 public interface ContentHandlerWithResult<T> extends ContentHandler {
103
104 /** expected to be set following a call to {@link XMLReader#parse(InputSource)} */
105 T result();
106
107 public interface Factory<T> {
108
109 ContentHandlerWithResult<T> create();
110 }
111 }
112
113 public static class Builder {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected