隐藏杰克逊序列化中受保护的字段

时间:2023-01-12 18:05:22

For some reason I am not able to hide protected fields (without setter), via ObjectMapper configuration, from being serialized to a JSON string.

出于某种原因,我无法通过ObjectMapper配置隐藏受保护的字段(没有setter),从而被序列化为JSON字符串。

My POJO:

public class Item {

    protected String sn;
    private String name;

    public Item(){
        sn = "43254667";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSn() {
        return sn;
    }

}

My mapper:

mapper.setVisibility(PropertyAccessor.SETTER, Visibility.PUBLIC_ONLY);
mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.NONE);

The output is:

输出是:

{
  "sn" : "43254667",
  "name" : "abc"
}

UPDATE: I cannot modify the Item class, hence I cannot use annotations.

更新:我无法修改Item类,因此我无法使用注释。

2 个解决方案

#1


2  

Use @JsonIgnore

You could annotate the field or method with @JsonIgnore.

您可以使用@JsonIgnore注释字段或方法。

It's a marker annotation that indicates that the annotated method or field is to be ignored by introspection-based serialization and deserialization functionality.

它是一个标记注释,指示基于内省的序列化和反序列化功能将忽略带注释的方法或字段。

Use as following:

使用如下:

public class Item {

    @JsonIgnore
    protected String sn;

    ...
}

Or as following:

或者如下:

public class Item {

    ...

    @JsonIgnore
    public String getSn() {
        return sn;
    }
}

Use @JsonIgnore with mix-ins

Based on your comment, you could use mix-in annotations when modifying the classes is not an option, as described in this answer.

根据您的评论,您可以在修改类时使用混合注释不是一个选项,如本答案中所述。

You can think of it as kind of aspect-oriented way of adding more annotations during runtime, to augment statically defined ones.

您可以将其视为在运行时添加更多注释的面向方面的方式,以增加静态定义的注释。

First, define a mix-in annotation interface (class would do as well):

首先,定义一个混合注释接口(类也可以):

public interface ItemMixIn {

    @JsonIgnore
    String getSn();
}

Then configure your ObjectMapper to use the defined interface as a mix-in for your POJO:

然后配置您的ObjectMapper以使用定义的接口作为POJO的混合:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Item.class, ItemMixIn.class);

For extra details, check the documentation.

有关其他详细信息,请查看文档。

Use a BeanSerializerModifier

Based on your comment, you may consider a BeanSerializerModifier, as following:

根据您的评论,您可以考虑使用BeanSerializerModifier,如下所示:

public class CustomSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
        BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {

        // In this method you can add, remove or replace any of passed properties

        return beanProperties;
    }
}

Then register the custom serializer as a module in your ObjectMapper.

然后在ObjectMapper中将自定义序列化程序注册为模块。

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {

    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanSerializerModifier(new CustomSerializerModifier());
    }
});

#2


0  

You've instructed your mapper to serialize public getters:

您已指示您的映射器序列化公共getter:

mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY);

That's why Jackson will serialize the sn field (You have a public getter here in the end).

这就是为什么杰克逊将序列化sn领域(你最终在这里有一个公共吸气者)。

To get rid of the serialized sn field, simply annotate your getter with @JsonIgnore:

要删除序列化的sn字段,只需使用@JsonIgnore注释你的getter:

public class Item{
  protected String sn;
  private String name;

  public Item(){
      sn = "43254667";
  }

  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  @JsonIgnore
  public String getSn() {
      return sn;
  }

}

If you cannot annotate your class, you can always write a custom serializer for your POJO or use Mixins

如果您无法为您的课程注释,您可以随时为您的POJO编写自定义序列化程序或使用Mixins

#1


2  

Use @JsonIgnore

You could annotate the field or method with @JsonIgnore.

您可以使用@JsonIgnore注释字段或方法。

It's a marker annotation that indicates that the annotated method or field is to be ignored by introspection-based serialization and deserialization functionality.

它是一个标记注释,指示基于内省的序列化和反序列化功能将忽略带注释的方法或字段。

Use as following:

使用如下:

public class Item {

    @JsonIgnore
    protected String sn;

    ...
}

Or as following:

或者如下:

public class Item {

    ...

    @JsonIgnore
    public String getSn() {
        return sn;
    }
}

Use @JsonIgnore with mix-ins

Based on your comment, you could use mix-in annotations when modifying the classes is not an option, as described in this answer.

根据您的评论,您可以在修改类时使用混合注释不是一个选项,如本答案中所述。

You can think of it as kind of aspect-oriented way of adding more annotations during runtime, to augment statically defined ones.

您可以将其视为在运行时添加更多注释的面向方面的方式,以增加静态定义的注释。

First, define a mix-in annotation interface (class would do as well):

首先,定义一个混合注释接口(类也可以):

public interface ItemMixIn {

    @JsonIgnore
    String getSn();
}

Then configure your ObjectMapper to use the defined interface as a mix-in for your POJO:

然后配置您的ObjectMapper以使用定义的接口作为POJO的混合:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Item.class, ItemMixIn.class);

For extra details, check the documentation.

有关其他详细信息,请查看文档。

Use a BeanSerializerModifier

Based on your comment, you may consider a BeanSerializerModifier, as following:

根据您的评论,您可以考虑使用BeanSerializerModifier,如下所示:

public class CustomSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
        BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {

        // In this method you can add, remove or replace any of passed properties

        return beanProperties;
    }
}

Then register the custom serializer as a module in your ObjectMapper.

然后在ObjectMapper中将自定义序列化程序注册为模块。

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule() {

    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanSerializerModifier(new CustomSerializerModifier());
    }
});

#2


0  

You've instructed your mapper to serialize public getters:

您已指示您的映射器序列化公共getter:

mapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY);

That's why Jackson will serialize the sn field (You have a public getter here in the end).

这就是为什么杰克逊将序列化sn领域(你最终在这里有一个公共吸气者)。

To get rid of the serialized sn field, simply annotate your getter with @JsonIgnore:

要删除序列化的sn字段,只需使用@JsonIgnore注释你的getter:

public class Item{
  protected String sn;
  private String name;

  public Item(){
      sn = "43254667";
  }

  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  @JsonIgnore
  public String getSn() {
      return sn;
  }

}

If you cannot annotate your class, you can always write a custom serializer for your POJO or use Mixins

如果您无法为您的课程注释,您可以随时为您的POJO编写自定义序列化程序或使用Mixins