Java 如何在Jackson中创建自定义泛型反序列化器?
我希望在Jackson中为Enum类的集合创建一个自定义反序列化器。因为自定义反序列化器的行为对于所有枚举都是相同的。我想为我的所有枚举类创建公共反序列化程序 我尝试按如下方式进行常规自定义反序列化:Java 如何在Jackson中创建自定义泛型反序列化器?,java,enums,jackson,Java,Enums,Jackson,我希望在Jackson中为Enum类的集合创建一个自定义反序列化器。因为自定义反序列化器的行为对于所有枚举都是相同的。我想为我的所有枚举类创建公共反序列化程序 我尝试按如下方式进行常规自定义反序列化: class MyEnumDeserialize<T> extends JsonDeserializer<T> { private Class beanClass; public MyEnumDeserialize() { }
class MyEnumDeserialize<T> extends JsonDeserializer<T> {
private Class beanClass;
public MyEnumDeserialize() {
}
public MyEnumDeserialize(Class beanClass) {
this.beanClass = beanClass;
}
@Override
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
TreeNode node = jsonParser.getCodec().readTree(jsonParser);
T type = null;
try{
if(node.get("attr") != null){
// I don't know how to call ENUM static method here as I don't have context information here
if (type != null) {
return type;
}
}
}catch(Exception e){
type = null;
}
return null;
}
}
module.setDeserializerModifier(new BeanDeserializerModifier()
{
@Override public JsonDeserializer<?> modifyEnumDeserializer(DeserializationConfig config,
JavaType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
{
if (beanDesc.getBeanClass().isEnum()) {
return new MyEnumDeserialize<>(beanDesc.getBeanClass());
}
return deserializer;
}
});
class MyEnumDeserialize<T extends Enum> extends JsonDeserializer<T> {
private Class beanClass;
public MyEnumDeserialize() {
}
public MyEnumDeserialize(Class beanClass) {
this.beanClass = beanClass;
}
@Override
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
TreeNode node = jsonParser.getCodec().readTree(jsonParser);
T type = null;
try{
if(node.isValueNode()){
ValueNode valueNode = (ValueNode)node;
Method method = this.beanClass.getDeclaredMethod("get",short.class);
type = (T)method.invoke(null, Short.parseShort(valueNode.asText()));
if (type != null) {
return type;
}
}
}catch(Exception e){
type = null;
}
return type;
类MyEnumDeserialize扩展JsonDeserializer{
私家班beanClass;
公共MyEnumDeserialize(){
}
公共MyEnumDeserialize(beanClass类){
this.beanClass=beanClass;
}
@凌驾
公共T反序列化(JsonParser JsonParser,DeserializationContext DeserializationContext)引发IOException{
TreeNode节点=jsonParser.getCodec().readTree(jsonParser);
T type=null;
试一试{
if(node.get(“attr”)!=null){
//我不知道如何在这里调用ENUM静态方法,因为这里没有上下文信息
if(type!=null){
返回类型;
}
}
}捕获(例外e){
type=null;
}
返回null;
}
}
问题是我想在反序列化程序中调用枚举静态方法,但由于没有任何可用的类/枚举上下文信息,因此无法执行此操作。你能帮我知道我怎样才能做到这一点吗。我设法使以下解决方案奏效: 我创建了一个模块并修改了EnumDeserializer,如下所示:
class MyEnumDeserialize<T> extends JsonDeserializer<T> {
private Class beanClass;
public MyEnumDeserialize() {
}
public MyEnumDeserialize(Class beanClass) {
this.beanClass = beanClass;
}
@Override
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
TreeNode node = jsonParser.getCodec().readTree(jsonParser);
T type = null;
try{
if(node.get("attr") != null){
// I don't know how to call ENUM static method here as I don't have context information here
if (type != null) {
return type;
}
}
}catch(Exception e){
type = null;
}
return null;
}
}
module.setDeserializerModifier(new BeanDeserializerModifier()
{
@Override public JsonDeserializer<?> modifyEnumDeserializer(DeserializationConfig config,
JavaType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
{
if (beanDesc.getBeanClass().isEnum()) {
return new MyEnumDeserialize<>(beanDesc.getBeanClass());
}
return deserializer;
}
});
class MyEnumDeserialize<T extends Enum> extends JsonDeserializer<T> {
private Class beanClass;
public MyEnumDeserialize() {
}
public MyEnumDeserialize(Class beanClass) {
this.beanClass = beanClass;
}
@Override
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
TreeNode node = jsonParser.getCodec().readTree(jsonParser);
T type = null;
try{
if(node.isValueNode()){
ValueNode valueNode = (ValueNode)node;
Method method = this.beanClass.getDeclaredMethod("get",short.class);
type = (T)method.invoke(null, Short.parseShort(valueNode.asText()));
if (type != null) {
return type;
}
}
}catch(Exception e){
type = null;
}
return type;
module.setDeserializerModifier(新的BeanDeserializerModifier()
{
@重写公共JsonDeserializer modifyEnumDeserializer(反序列化配置,
JavaType类型、BeanDescription beanDesc、JsonDeserializer反序列化程序)
{
if(beanDesc.getBeanClass().isEnum()){
返回新的MyEnumDeserialize(beanDesc.getBeanClass());
}
返回反序列化器;
}
});
类MyEnumDeserialize扩展JsonDeserializer{
私家班beanClass;
公共MyEnumDeserialize(){
}
公共MyEnumDeserialize(beanClass类){
this.beanClass=beanClass;
}
@凌驾
公共T反序列化(JsonParser JsonParser,DeserializationContext DeserializationContext)引发IOException{
TreeNode节点=jsonParser.getCodec().readTree(jsonParser);
T type=null;
试一试{
if(node.isValueNode()){
ValueNode ValueNode=(ValueNode)节点;
Method=this.beanClass.getDeclaredMethod(“get”,简称.class);
type=(T)method.invoke(null,Short.parseShort(valueNode.astex());
if(type!=null){
返回类型;
}
}
}捕获(例外e){
type=null;
}
返回类型;
}
}
尽管现在,我无法提供严格的类型检查(使用“”创建实例)。此反序列化程序是否应仅处理枚举,因此不应是某个枚举?JSON的小示例也会很有帮助。@pirho Yes T应是某个枚举。实际上,我的应用程序中有流。在一个流中,我接收ENUM的整数值,在另一个流中,我接收ENUM的字符串名称。我有大约10个枚举类,所以试图创建自定义泛型序列化程序和反序列化程序。@pirho让我们假设我现在有两个枚举类(StudentType和StudentUniform)。我可能会收到以下JSON{“studentType”:“10”,“studentUniform”:“1”}。@pirho我设法找到了一个解决方案。你能复习一下吗