欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springcloud中feign调用处理mybatis-plus Ipage反序列化问题

程序员文章站 2022-06-27 20:45:22
通过feign接口返回的分页列表IPage,出现报错,具体报错内容如下:feign.codec.DecodeException: Type definition error: [simple type, class com.baomidou.mybatisplus.core.metadata.IPage]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct...

通过feign接口返回的分页列表IPage,出现报错,具体报错内容如下:

feign.codec.DecodeException: Type definition error: [simple type, class com.baomidou.mybatisplus.core.metadata.IPage]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.baomidou.mybatisplus.core.metadata.IPage` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

通过对该问题的分析,因为com.baomidou.mybatisplus.core.metadata.IPage是一个接口,所以不能构建实例。抽象类型需要映射到实现类型,可以通过自定义反序列化或者包含额外的类型信息。

接下来,我们可以通过这个提示,自定义一个反序列化类来处理该问题,具体代码如下:

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;
    }
}

在Converter中配置进去即可,代码如下:

@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;
    }


}

 

至此,问题解决。

本文地址:https://blog.csdn.net/terminator_J/article/details/107493404