首页 > 解决方案 > Jackson:如何动态设置属性的别名

问题描述

我知道 Jackson 支持 Mixin,我可以为以下属性设置别名:

public final class Rectangle {
    private int w;

    public Rectangle(int w) {
       this.w = w;
    }

    public int getW() { return w; }
    }
}

abstract class MixIn {
  MixIn(@JsonProperty("width") int w) { }

  @JsonProperty("width") abstract int getW();
}

并这样做:

objectMapper.addMixInAnnotations(Rectangle.class, MixIn.class);

但我不想用注释来做。我想动态添加别名,例如:

objectMapper.addAlias(Rectangle.class, "w", "width")

有没有办法做到这一点?

注意:也可以接受 动态排除属性等解决方案

标签: javajsonjacksonjackson2

解决方案


您可以使用 custom 来实现这一点,AnnotationIntrospector您可以在其中拦截和修改 Jackson 检测和使用@JsonProperty(即使字段/方法未注释)

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

public class DynamicPropertyAliasIntrospector extends JacksonAnnotationIntrospector
{
    @Override
    public PropertyName findNameForSerialization(Annotated a)
    {
        // if get method has @JsonProperty, return that
        PropertyName pn = super.findNameForSerialization(a);
        if (a.hasAnnotation(JsonProperty.class)) {
            return pn;
        }
        // if not annotated, value may be set dynamically 
        if (a.getName().equals("getW")) {
            // value may be set from external source as well (properties file, etc)
            pn = new PropertyName("width");
        }
        return pn;
    }
}

用法:将自定义注释内省器的实例传递给对象映射器:

public static void main(String[] args)
{
    ObjectMapper mapper = new ObjectMapper();
    mapper.setAnnotationIntrospector(new DynamicPropertyAliasIntrospector());
    Rectangle r = new Rectangle(3);
    try {
        mapper.writeValue(System.out, r);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

输出:

{"width":3}

推荐阅读