当使用Feign调用服务IPage分页接口时,会出现序列化异常。
解决方式如下:
添加配置文件IPageDeserializer,WebDataConvertConfig
public class IPageDeserializer extends StdDeserializer<IPage> { protected 
IPageDeserializer(Class<?> vc) { super(vc); } /** * Method that can be called 
to ask implementation to deserialize * JSON content into the value type this 
serializer handles. * Returned instance is to be constructed by method itself. 
* <p> * Pre-condition for this method is that the parser points to the * first 
event that is part of value to deserializer (and which * is never JSON 'null' 
literal, more on this below): for simple * types it may be the only value; and 
for structured types the * Object start marker or a FIELD_NAME. * </p> * <p> * 
The two possible input conditions for structured types result * from 
polymorphism via fields. In the ordinary case, Jackson * calls this method when 
it has encountered an OBJECT_START, * and the method implementation must 
advance to the next token to * see the first field name. If the application 
configures * polymorphism via a field, then the object looks like the 
following. * <pre> * { * "@class": "class name", * ... * } * </pre> * Jackson 
consumes the two tokens (the <tt>@class</tt> field name * and its value) in 
order to learn the class and select the deserializer. * Thus, the stream is 
pointing to the FIELD_NAME for the first field * after the @class. Thus, if you 
want your method to work correctly * both with and without polymorphism, you 
must begin your method with: * <pre> * if (p.getCurrentToken() == 
JsonToken.START_OBJECT) { * p.nextToken(); * } * </pre> * This results in the 
stream pointing to the field name, so that * the two conditions align. * <p> * 
Post-condition is that the parser will point to the last * event that is part 
of deserialized value (or in case deserialization * fails, event that was not 
recognized or usable, which may be * the same event as the one it pointed to 
upon call). * <p> * Note that this method is never called for JSON null 
literal, * and thus deserializers need (and should) not check for it. * * 
@param p Parsed used for reading JSON content * @param ctxt Context that can be 
used to access information about * this deserialization activity. * @return 
Deserialized value */ @Override public IPage deserialize(JsonParser p, 
DeserializationContext ctxt) throws IOException, JsonProcessingException { 
JsonNode node = p.getCodec().readTree(p); String s = node.toString(); 
ObjectMapper om = new ObjectMapper(); Page page = om.readValue(s,Page.class); 
return page; } } @Configuration public class WebDataConvertConfig extends 
WebMvcConfigurationSupport { @Override public void 
configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
converters.add(mappingJackson2HttpMessageConverter()); 
super.configureMessageConverters(converters); } @Bean public 
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { 
MappingJackson2HttpMessageConverter converter = new 
MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new 
ObjectMapper(); 
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
SimpleModule module = new SimpleModule(); module.addDeserializer(IPage.class, 
new IPageDeserializer(IPage.class)); mapper.registerModule(module); 
converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, 
MediaType.APPLICATION_JSON_UTF8,MediaType.APPLICATION_OCTET_STREAM)); 
converter.setObjectMapper(mapper); return converter; } }