特定字段上的自定义Jackson序列化器 [英] Custom Jackson serializer on specific fields

查看:322
本文介绍了特定字段上的自定义Jackson序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找针对同一对象的多个杰克逊解串器,它们全部基于自定义注释.

I'm looking to have multiple jackson deserializers for the same object(s) all based on a custom annotation.

理想情况下,我会有一个POJO,如:

Ideally I'd have a single POJO like:

public class UserInfo {
   @Redacted    
   String ssn;

   String name;
}

在正常"条件下,我希望将此对象以默认方式序列化:

Under "normal" conditions I want this object to be serialized the default way:

{"ssn":"123-45-6789", "name":"Bob Smith"}

但是出于记录目的(例如),我想编辑SSN,以使其不会保存在我们的日志中:

but for logging purposes (for example) I want to redact the SSN so it doesn't get saved in our logs:

{"ssn":"xxx-xx-xxxx", "name":"Bob Smith"}

我还研究了使用 @JsonSerialize 并提出:

I've also looked into using @JsonSerialize and come up with:

public class UserInfo {

    @JsonSerialize(using = RedactedSerializer.class, as=String.class)
    String firstName;
    String lastName;

}

此问题是,它始终使用此规则.可以添加多个@JsonSerializers,而在运行时代码中仅使用指定的那个吗?

The problem with this is that it ALWAYS uses this rule. Can multiple @JsonSerializers be added and only the specified one be used within the runtime code?

我也看到过视图",但理想情况下,我想至少表明请求中存在该字段-即使我不知道该值.

I've also seen "views" but ideally I'd like to atleast show that the field was present on the request - even if I dont know the value.

推荐答案

100%安全的方法是在不同的请求中使用不同的DTO.但是,是的,如果您不能这样做,请使用@JsonView和自定义序列化程序,例如:

The 100% safe way would be to use different DTO in different requests. But yeah, if you cant do that, use @JsonView and custom serializer, something like:

class Views {
    public static class ShowSSN {}
}

private static class MyBean{
    @JsonSerialize(using = MyBeanSerializer.class)
    @JsonView(Views.ShowSSN.class)
    String ssn;
    //getter setter constructor
}

private class MyBeanSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String value, JsonGenerator gen,
                          SerializerProvider serializers) throws IOException {
        Class<?> jsonView =  serializers.getActiveView();
        if (jsonView == Views.ShowSSN.class) 
            gen.writeString(value); // your custom serialization code here
        else 
            gen.writeString("xxx-xx-xxxx");
    }
} 

并像这样使用它:

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    MyBean bean = new MyBean("123-45-6789");

    System.out.println(mapper.writerWithView(Views.ShowSSN.class)
                             .writeValueAsString(bean));
    // results in {"ssn":"123-45-6789"}

    System.out.println(mapper.writeValueAsString(bean));
    // results in {"ssn":"xxx-xx-xxxx"}
}

例如在春季,它真的很容易使用

Also for example in spring it would be really easy to use

@Controller
public class MyController {
    @GetMapping("/withView")       // results in {"ssn":"123-45-6789"}
    @JsonView(Views.ShowSSN.class)
    public @ResponseBody MyBean withJsonView() {
        return new MyBean("123-45-6789");
    }

    @GetMapping("/withoutView")    // results in {"ssn":"xxx-xx-xxxx"}
    public @ResponseBody MyBean withoutJsonView() {
        return new MyBean("123-45-6789");
    }

}

这篇关于特定字段上的自定义Jackson序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆