【问题标题】:Jackson: How to set alias for properties dynamicallyJackson:如何动态设置属性的别名
【发布时间】:2018-08-08 19:23:53
【问题描述】:

我知道 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")

有没有办法做到这一点?

注意:也可以接受像excluding properties dynamically这样的解决方案

【问题讨论】:

    标签: java json jackson jackson2


    【解决方案1】:

    您可以通过自定义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}
    

    【讨论】:

    • 感谢您的回答,我会检查并通知您。
    • 进展如何??
    • 在您的示例中,无法检查类以添加别名。在您的情况下,所有定义为“getW”的方法都将被映射为“权重”,不管它是不是 Rectangle 的方法。
    • 解决方案是我指出的地方:杰克逊的AnnotationIntrospector。深入了解它(毕竟它是开源的)有很多方法可以被覆盖。
    猜你喜欢
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多