在feign中,返回值类型为Map< ObjectA, ObjectB>的情况时,发送jackson序列化失败,导致服务熔断,错误日志信息为
Can not find a (Map) Key deserializer for type
接口如下:
ResponseEntity<Map<EntityDto,List<XwbqDto>> mutipleGetLabels(@RequestBody List<EntityDto> entityDtos);
dto如下:
Data
public class EntityDto implements Serializable {
private static final long SERIAL_VERSION_UID = -4680948320252253717L;
private String entityId;
private String entityType;
public EntityDto() {
}
@Override
public int hashCode() {
int hashCode = (entityId + "-" + entityType).hashCode();
return hashCode;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
final EntityDto entityDto = (EntityDto) obj;
if (this == entityDto) {
return true;
} else {
if (entityId==null&&entityType==null) {
if (entityId == entityDto.getEntityId() && entityType == entityDto.getEntityType()) {
return true;
}
}
if (entityId==null&&entityType!=null){
if (entityId== entityDto.getEntityId()&&entityType.equals(entityDto.getEntityType())){
return true;
}
}
if (entityId!=null&&entityType==null){
if (entityId.equals(entityDto.getEntityId())&&entityType==entityDto.getEntityType()){
return true;
}
}
if (entityId!=null&&entityType!=null){
if (entityId.equals(entityDto.getEntityId())&&entityType.equals(entityDto.getEntityType())){
return true;
}
}
return false;
}
}
}
在接口正确拿到了ResponseEntity<Map<EntityDto,List<XwbqDto>>对应的返回结果后,feign会利用jackson对结果进行json转换,此时会发生序列化及反序列化失败,导致服务调用发生异常;
解决办法:修改Dto,添加序列化及反序列化规则
1.序列化:重载Dto的toString方法,并增加 @JsonValue注解
2.反序列化:重载Dto的构造器,与toString中的内容正好相反
修改后的Dto代码如下
@Data
public class EntityDto implements Serializable {
private static final long SERIAL_VERSION_UID = -4680948320252253717L;
private String entityId;
private String entityType;
public EntityDto() {
}
public EntityDto(String obInfo) {
String[] values=obInfo.split("-");
this.entityId=values[0];
this.entityType=values[1];
}
@Override
@JsonValue
public String toString(){
return this.entityId + "-" + this.entityType;
}
@Override
public int hashCode() {
int hashCode = (entityId + "-" + entityType).hashCode();
return hashCode;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
final EntityDto entityDto = (EntityDto) obj;
if (this == entityDto) {
return true;
} else {
if (entityId==null&&entityType==null) {
if (entityId == entityDto.getEntityId() && entityType == entityDto.getEntityType()) {
return true;
}
}
if (entityId==null&&entityType!=null){
if (entityId== entityDto.getEntityId()&&entityType.equals(entityDto.getEntityType())){
return true;
}
}
if (entityId!=null&&entityType==null){
if (entityId.equals(entityDto.getEntityId())&&entityType==entityDto.getEntityType()){
return true;
}
}
if (entityId!=null&&entityType!=null){
if (entityId.equals(entityDto.getEntityId())&&entityType.equals(entityDto.getEntityType())){
return true;
}
}
return false;
}
}
}