基于jackson 多态数据类型处理rest api 业务
jackson 支持多态数据类型处理,基于此特性我们可以实现灵活强大的类型处理,业务规则处理
同时基于此可以实现动态插件化的业务处理
参考使用
- 抽象类型定义
MyUser
package com.dalong;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonAutoDetect(fieldVisibility= JsonAutoDetect.Visibility.PUBLIC_ONLY, getterVisibility= JsonAutoDetect.Visibility.NONE, isGetterVisibility= JsonAutoDetect.Visibility.NONE, setterVisibility= JsonAutoDetect.Visibility.NONE)
public abstract class MyUser<T> {
public abstract String printVersion();
public String getType(){
return this.getClass().getAnnotation(SourceType.class).value();
}
public abstract T instance();
}
SourceType 注解定义
package com.dalong;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SourceType {
String value();
String label() default "";
String uiConfig() default "";
boolean configurable() default true;
boolean listable() default true;
boolean externalQuerySupported() default false;
}
- 子类
FirstMyUser
package com.dalong;
import java.util.UUID;
@SourceType(value ="FirstMyUser-dalongdemo")
public class FirstMyUser extends MyUser<FirstMyUser> {
public String name;
public String classType;
@Override
public String printVersion() {
return UUID.randomUUID().toString();
}
@Override
public FirstMyUser instance() {
return this;
}
}
SecondMyUser
package com.dalong;
import java.util.UUID;
@SourceType(value ="SecondMyUser-dalongdemoapp")
public class SecondMyUser extends MyUser<SecondMyUser> {
public String name;
public String classType;
@Override
public String printVersion() {
return UUID.randomUUID().toString();
}
@Override
public SecondMyUser instance() {
return this;
}
}
- 使用
package com.dalong;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import java.lang.reflect.InvocationTargetException;
public class App {
static ObjectMapper objectMapper = new ObjectMapper();
public static void main(String[] args) throws JsonProcessingException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
objectMapper.registerSubtypes(new NamedType(FirstMyUser.class, "dalongdemo"));
objectMapper.registerSubtypes(new NamedType(SecondMyUser.class, "dalongdemoapp"));
FirstMyUser bean = new FirstMyUser();
bean.name="dalong";
bean.classType="testapp";
String s = objectMapper.writeValueAsString(bean);
System.out.println(s);
SecondMyUser bean2 = new SecondMyUser();
bean2.name="dalong2";
bean2.classType="testapp2";
String s2 = objectMapper.writeValueAsString(bean2);
System.out.println(s2);
MyUser myUser= objectMapper.readValue(s,MyUser.class);
MyUser myUser2= objectMapper.readValue(s2,MyUser.class);
System.out.println(myUser.getType());
System.out.println(myUser2.getType());
Object ob= myUser2.instance();
Object result = ob.getClass().getMethod("getType",null).invoke(ob,null);
System.out.println(result.toString());
}
}
- 效果
说明
集成rest 的玩法,可以基于一个通用的rest 接口定义,基于不同的类型,使用如果类似的方法,同时集成上plugin 处理机制就可以灵活的控制业务数据处理了
参考如下示意集成模式
参考资料
https://www.baeldung.com/jackson-annotations
https://fasterxml.github.io/jackson-annotations/javadoc/2.4/com/fasterxml/jackson/annotation/JsonTypeInfo.html