Jackson解析多态
小于 1 分钟
提示
Jackson解析多态
1. 定义接口
@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, visible = true, property = "businessFrom", include = JsonTypeInfo.As.EXISTING_PROPERTY)
@JsonTypeIdResolver(TaskJsonTypeResolver.class)
public interface TaskBusiness {
Integer getBusinessFrom();
}
2. 实现类
public class TaskJsonTypeResolver implements TypeIdResolver {
private JavaType _baseType;
@Override
public void init(JavaType javaType) {
if (!TaskBusiness.class.isAssignableFrom(javaType.getRawClass())) {
throw new RuntimeException("TaskJsonTypeResolver只支持TaskBusinessEntity的继承类!");
}
_baseType = javaType;
}
@Override
public String idFromValue(Object o) {
if (Objects.isNull(o)) {
return null;
}
TaskBusinessEntity taskBusinessEntity = (TaskBusinessEntity) o;
return Objects.isNull(taskBusinessEntity.getBusinessFrom()) ? StringPool.EMPTY : String.valueOf(taskBusinessEntity.getBusinessFrom());
}
@Override
public String idFromValueAndType(Object o, Class<?> aClass) {
return idFromValue(o);
}
@Override
public String idFromBaseType() {
return idFromValueAndType(null, _baseType.getRawClass());
}
@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
String className = BusinessFromType.TASK_DTO_CLASS_MAP.get(Func.toInt(id));
JavaType t = StringUtils.isBlank(className) ? null : context.resolveAndValidateSubType(this._baseType, className, LaissezFaireSubTypeValidator.instance);
return t == null && context instanceof DeserializationContext ?
((DeserializationContext) context).handleUnknownTypeId(this._baseType, id, this, "no such class found") : t;
}
@Override
public String getDescForKnownTypeIds() {
return "只实现TaskBusinessEntity的获取具体实现类";
}
@Override
public JsonTypeInfo.Id getMechanism() {
return JsonTypeInfo.Id.CUSTOM;
}
}
3. 定义类型
@Getter
@AllArgsConstructor
public enum BusinessFromType {
ORDER(1, ""),
CUSTOMER(66, "");
public static Map<Integer, String> TASK_DTO_CLASS_MAP = new HashMap<>();
static {
TASK_DTO_CLASS_MAP.put(ORDER.type, OrderTaskDTO.class.getName());
TASK_DTO_CLASS_MAP.put(CUSTOMER.type, CustomerTaskDTO.class.getName());
}
private final int type;
private final String name;
public static Optional<BusinessFromType> getType(Object type) {
if (Objects.isNull(type)) {
return Optional.empty();
}
int typeInt = Func.toInt(type, 0);
return Stream.of(BusinessFromType.values())
.filter(t -> t.getType() == typeInt)
.findFirst();
}
}