我正在寻找基于自定义注释的相同对象的多个 jackson 反序列化器。
理想情况下,我有一个像这样的 POJO:
public class UserInfo {
@Redacted
String ssn;
String name;
}
在“正常”条件下,我希望这个对象以默认方式序列化:
{"ssn":"123-45-6789", "name":"Bob Smith"}
但出于记录目的(例如)我想编辑 SSN,这样它就不会保存在我们的日志中:
{"ssn":"xxx-xx-xxxx", "name":"Bob Smith"}
我也研究过使用 @JsonSerialize 并提出:
public class UserInfo {
@JsonSerialize(using = RedactedSerializer.class, as=String.class)
String firstName;
String lastName;
}
问题是它总是使用这个规则。是否可以添加多个@JsonSerializer 并在运行时代码中仅使用指定的一个?
我也看到过“ View ”,但理想情况下,我想至少表明请求中存在该字段 - 即使我不知道该值。
最佳答案
100% 安全的方法是在不同的请求中使用不同的 DTO。但是,是的,如果您不能这样做,请使用 @JsonView
和自定义序列化程序,例如:
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"}
}
另外比如在 Spring ,它会很容易使用
@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");
}
}
关于java - 特定字段上的自定义 Jackson 序列化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47129953/