Feign provides comprehensive JSON support through Gson and Jackson encoders/decoders for seamless JSON request and response handling.
Gson-based JSON encoding and decoding with Google's Gson library.
/**
* JSON encoder using Google Gson library
*/
public final class GsonEncoder implements Encoder {
/** Create encoder with default Gson instance */
public GsonEncoder();
/** Create encoder with custom Gson instance */
public GsonEncoder(Gson gson);
/** Encode object to JSON request body */
public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
}
/**
* JSON decoder using Google Gson library
*/
public final class GsonDecoder implements Decoder {
/** Create decoder with default Gson instance */
public GsonDecoder();
/** Create decoder with custom Gson instance */
public GsonDecoder(Gson gson);
/** Decode JSON response to object */
public Object decode(Response response, Type type) throws IOException;
}
/**
* Factory for creating Gson instances with Feign-specific configuration
*/
public final class GsonFactory {
/** Create Gson instance with Date handling and null serialization */
public static Gson create();
/** Create Gson instance with custom type adapters */
public static Gson create(Iterable<TypeAdapter<?>> adapters);
}Jackson-based JSON encoding and decoding with FasterXML Jackson library.
/**
* JSON encoder using Jackson library
*/
public class JacksonEncoder implements Encoder {
/** Create encoder with default ObjectMapper */
public JacksonEncoder();
/** Create encoder with custom ObjectMapper */
public JacksonEncoder(ObjectMapper mapper);
/** Encode object to JSON request body */
public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
}
/**
* JSON decoder using Jackson library
*/
public class JacksonDecoder implements Decoder {
/** Create decoder with default ObjectMapper */
public JacksonDecoder();
/** Create decoder with custom ObjectMapper */
public JacksonDecoder(ObjectMapper mapper);
/** Decode JSON response to object */
public Object decode(Response response, Type type) throws IOException;
}Jackson support with JAXB annotation processing for XML-to-JSON mapping.
/**
* JSON encoder using Jackson with JAXB annotation support
*/
public class JacksonJaxbJsonEncoder extends JacksonEncoder {
/** Create encoder with JAXB-configured ObjectMapper */
public JacksonJaxbJsonEncoder();
/** Create encoder with custom JAXB-configured ObjectMapper */
public JacksonJaxbJsonEncoder(ObjectMapper mapper);
}
/**
* JSON decoder using Jackson with JAXB annotation support
*/
public class JacksonJaxbJsonDecoder extends JacksonDecoder {
/** Create decoder with JAXB-configured ObjectMapper */
public JacksonJaxbJsonDecoder();
/** Create decoder with custom JAXB-configured ObjectMapper */
public JacksonJaxbJsonDecoder(ObjectMapper mapper);
}import feign.Feign;
import feign.gson.GsonEncoder;
import feign.gson.GsonDecoder;
// Simple Gson configuration
GitHub github = Feign.builder()
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");
// Custom Gson configuration
Gson customGson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.create();
API api = Feign.builder()
.encoder(new GsonEncoder(customGson))
.decoder(new GsonDecoder(customGson))
.target(API.class, "https://api.example.com");import feign.Feign;
import feign.jackson.JacksonEncoder;
import feign.jackson.JacksonDecoder;
import com.fasterxml.jackson.databind.ObjectMapper;
// Simple Jackson configuration
API api = Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.target(API.class, "https://api.example.com");
// Custom ObjectMapper configuration
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
API api = Feign.builder()
.encoder(new JacksonEncoder(mapper))
.decoder(new JacksonDecoder(mapper))
.target(API.class, "https://api.example.com");import feign.Feign;
import feign.jackson.jaxb.JacksonJaxbJsonEncoder;
import feign.jackson.jaxb.JacksonJaxbJsonDecoder;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "user")
class User {
@XmlElement(name = "user_name")
private String username;
@XmlElement(name = "user_email")
private String email;
}
// JAXB-aware JSON processing
API api = Feign.builder()
.encoder(new JacksonJaxbJsonEncoder())
.decoder(new JacksonJaxbJsonDecoder())
.target(API.class, "https://api.example.com");import feign.RequestLine;
import feign.Param;
import feign.Body;
import java.util.List;
interface UserAPI {
@RequestLine("GET /users/{id}")
User getUser(@Param("id") String userId);
@RequestLine("GET /users")
List<User> getAllUsers();
@RequestLine("POST /users")
@Headers("Content-Type: application/json")
User createUser(User user);
@RequestLine("PUT /users/{id}")
@Headers("Content-Type: application/json")
User updateUser(@Param("id") String userId, User user);
}
class User {
private String id;
private String name;
private String email;
// getters and setters
}dependencies {
compile 'com.netflix.feign:feign-gson:8.18.0'
}dependencies {
compile 'com.netflix.feign:feign-jackson:8.18.0'
}dependencies {
compile 'com.netflix.feign:feign-jackson-jaxb:8.18.0'
}// Custom date format
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create();
// Handle null values
Gson gson = new GsonBuilder()
.serializeNulls()
.create();
// Custom field naming
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();// Configure deserialization
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
// Configure serialization
ObjectMapper mapper = new ObjectMapper()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// Property naming strategies
ObjectMapper mapper = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);