当使用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;
}
}