
feign.jackson.JacksonIteratorDecoder Maven / Gradle / Ivy
/**
* Copyright 2012-2020 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.jackson;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.*;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import static feign.Util.UTF_8;
import static feign.Util.ensureClosed;
/**
* Jackson decoder which return a closeable iterator. Returned iterator auto-close the
* {@code Response} when it reached json array end or failed to parse stream. If this iterator is
* not fetched till the end, it has to be casted to {@code Closeable} and explicity
* {@code Closeable#close} by the consumer.
*
*
*
* Example:
*
*
*
* Feign.builder()
* .decoder(JacksonIteratorDecoder.create())
* .doNotCloseAfterDecode() // Required to fetch the iterator after the response is processed, need to be close
* .target(GitHub.class, "https://api.github.com");
* interface GitHub {
* {@literal @}RequestLine("GET /repos/{owner}/{repo}/contributors")
* Iterator contributors(@Param("owner") String owner, @Param("repo") String repo);
* }
*
*/
public final class JacksonIteratorDecoder implements Decoder {
private final ObjectMapper mapper;
JacksonIteratorDecoder(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public Object decode(Response response, Type type) throws IOException {
if (response.body() == null)
return null;
Reader reader = response.body().asReader(UTF_8);
if (!reader.markSupported()) {
reader = new BufferedReader(reader, 1);
}
try {
// Read the first byte to see if we have any data
reader.mark(1);
if (reader.read() == -1) {
return null; // Eagerly returning null avoids "No content to map due to end-of-input"
}
reader.reset();
return new JacksonIterator
© 2015 - 2025 Weber Informatics LLC | Privacy Policy