问题起因
公司项目,在调用其他服务时突然报错。具体报错如下
Caused by: feign.codec.EncodeException: Error converting request body
--------------
Caused by: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class java.lang.Object]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.lang.Object and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.xxx.xxx.api.po.request.CreateOrderRequest["cardId"])
这个异常是由Jackson库抛出的,通常表示在序列化时找不到适当的序列化器。具体来说,错误消息中提到了找不到java.lang.Object类的序列化器,并且没有发现任何属性来创建BeanSerializer。
看报错原因应该是feign调用其他服务时对象序列化出现。CreateOrderRequest这个类的cardId字段 是Object类型的。原因在于Object是一个非常通用的类,而Jackson需要知道如何正确地将对象转换为特定格式(例如JSON)。 默认情况下,Jackson的ObjectMapper会尝试使用通用的对象序列化机制,但对于一些类型(如Object),它可能无法确定如何正确地序列化对象。
有几个可能的原因:
泛型信息缺失: Object是一个泛型类,它可以包含任何类型的对象。在序列化时,如果没有足够的信息告诉Jackson如何序列化泛型类型,它可能会遇到困难。
自定义序列化器缺失: Jackson可能没有为java.lang.Object提供默认的序列化器。对于通用的类型,你可能需要提供自定义的序列化器。 解决这个问题的方法之一是明确告诉Jackson如何处理Object类型。
java序列化是一种将对象转换为字节流的过程,以便可以在网络上传输或将对象保存到文件中。序列化主要用于对象的持久性存储和网络通信。在Java中,通过实现java.io.Serializable接口来实现对象的序列化和反序列化。
解决方案:
方案1:增加配置文件
@Configuration
public class BeanConfig {
@Bean
public ObjectMapper objectMapper(){
return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
}
}
或者
@Configuration
public class BeanConfig {
@Bean
public Jackson2ObjectMapperBuilder objectMapper(){
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToDisable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
return builder;
}
}
方案2:对象允许为空的字段对象上,添加JsonIgnore注解
import com.fasterxml.jackson.annotation.JsonIgnore;
@JsonIgnore
private Object cardId;
注意使用@JsonIgnore 是在json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。那么最后返回的json数据,将不会包含cardId这个属性值。
使用@JsonSerialize注解: 在你的自定义类上使用@JsonSerialize注解,指定一个适当的序列化器。
public class YourClass {
@JsonSerialize(using = YourCustomSerializer.class)
private Object yourField;
// 其他成员和方法
}
public class YourCustomSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// 自定义序列化逻辑
// ...
}
}