如何在 RestController 中使用基于 JsonView 的两个不同的 getter 进行序列化?
How do I serialize using two different getters based on JsonView in RestController?
我希望能够序列化基于 JsonView 的对象中的字段。不一定是JsonView,只是我一直在探索的。基本上在 RestController class 上使用 @JsonView 注释,它会序列化我的 POJO。
但是我有一个用户和管理员视图,其中有一个对象:
地图秘密;
对于 Admin 视图,我希望 key:value 都显示并序列化,但对于用户,我只想要一个 List 键,或者如果它更简单,保留 Map 但只显示键和所有值切换为“****”4 个星号或其他内容。
我考虑过使用两个 getter,但 JsonView 注释无法像两个 getter 可以有不同的视图那样工作,而 Jackson 知道调用哪一个。
我不确定 JsonView 是否是这里最好的东西。也许是基于视图或某些自定义序列化程序进行序列化的 JsonGetter 方法,但我认为可能有一种更直接的方法可以使用 Jackson 和少量注释来完成
我想做的是:
Person.java
Map<String,String> secrets;
这将序列化为(对于管理员):
{
"person":{
"secrets":{
"password":"123456",
"creditCard":"1234 5678 9101"
}
}
}
这将序列化为(对于用户):
{
"person":{
"secrets":{
"password":"****",
"creditCard":"****"
}
}
}
但是我想我能做的是
@JsonView(View.User.class)
Map<String,String> getSecrets(){
this.secrets.forEach(value -> "****") //code would be different but basically setting all values to ****
return secrets;
}
@JsonView(View.Admin.class)
Map<String,String> getSecrets(){
//Returning secrets as they should be
return secrets;
}
您可以尝试为对象映射器定义一个自定义序列化器,这样无论何时使用对象映射器进行序列化,您都可以检查并将密码和信用卡字段转换为您 choose.For 示例
的值
public class ItemSerializer extends StdSerializer<Item> {
public ItemSerializer() {
this(null);
}
public ItemSerializer(Class<Item> t) {
super(t);
}
@Override
public void serialize(
Item value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("id", value.id);
jgen.writeStringField("itemName", value.itemName);
jgen.writeNumberField("owner", value.owner.id);
jgen.writeEndObject();
}
}
您可以提供一个使用此自定义序列化程序的对象映射器,
Item myItem = new Item(1, "theItem", new User(2, "theUser"));
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Item.class, new ItemSerializer());
mapper.registerModule(module);
String serialized = mapper.writeValueAsString(myItem);
在您的情况下,您可以在 spring 上下文中使用自定义序列化程序注册 objectmapper bean,并让 jackson 使用您的对象映射器 bean。
或使用 @JsonSerialize
注释,例如:
public class Event {
public String name;
@JsonSerialize(using = CustomDateSerializer.class)
public Date eventDate;
}
Public class CustomDateSerializer extends StdSerializer<Date> {
private static SimpleDateFormat formatter
= new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
public CustomDateSerializer() {
this(null);
}
public CustomDateSerializer(Class<Date> t) {
super(t);
}
@Override
public void serialize(
Date value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
}
}
参考:
我希望能够序列化基于 JsonView 的对象中的字段。不一定是JsonView,只是我一直在探索的。基本上在 RestController class 上使用 @JsonView 注释,它会序列化我的 POJO。 但是我有一个用户和管理员视图,其中有一个对象:
地图秘密;
对于 Admin 视图,我希望 key:value 都显示并序列化,但对于用户,我只想要一个 List 键,或者如果它更简单,保留 Map 但只显示键和所有值切换为“****”4 个星号或其他内容。
我考虑过使用两个 getter,但 JsonView 注释无法像两个 getter 可以有不同的视图那样工作,而 Jackson 知道调用哪一个。
我不确定 JsonView 是否是这里最好的东西。也许是基于视图或某些自定义序列化程序进行序列化的 JsonGetter 方法,但我认为可能有一种更直接的方法可以使用 Jackson 和少量注释来完成
我想做的是:
Person.java
Map<String,String> secrets;
这将序列化为(对于管理员):
{
"person":{
"secrets":{
"password":"123456",
"creditCard":"1234 5678 9101"
}
}
}
这将序列化为(对于用户):
{
"person":{
"secrets":{
"password":"****",
"creditCard":"****"
}
}
}
但是我想我能做的是
@JsonView(View.User.class)
Map<String,String> getSecrets(){
this.secrets.forEach(value -> "****") //code would be different but basically setting all values to ****
return secrets;
}
@JsonView(View.Admin.class)
Map<String,String> getSecrets(){
//Returning secrets as they should be
return secrets;
}
您可以尝试为对象映射器定义一个自定义序列化器,这样无论何时使用对象映射器进行序列化,您都可以检查并将密码和信用卡字段转换为您 choose.For 示例
的值public class ItemSerializer extends StdSerializer<Item> {
public ItemSerializer() {
this(null);
}
public ItemSerializer(Class<Item> t) {
super(t);
}
@Override
public void serialize(
Item value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("id", value.id);
jgen.writeStringField("itemName", value.itemName);
jgen.writeNumberField("owner", value.owner.id);
jgen.writeEndObject();
}
}
您可以提供一个使用此自定义序列化程序的对象映射器,
Item myItem = new Item(1, "theItem", new User(2, "theUser"));
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Item.class, new ItemSerializer());
mapper.registerModule(module);
String serialized = mapper.writeValueAsString(myItem);
在您的情况下,您可以在 spring 上下文中使用自定义序列化程序注册 objectmapper bean,并让 jackson 使用您的对象映射器 bean。
或使用 @JsonSerialize
注释,例如:
public class Event {
public String name;
@JsonSerialize(using = CustomDateSerializer.class)
public Date eventDate;
}
Public class CustomDateSerializer extends StdSerializer<Date> {
private static SimpleDateFormat formatter
= new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
public CustomDateSerializer() {
this(null);
}
public CustomDateSerializer(Class<Date> t) {
super(t);
}
@Override
public void serialize(
Date value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
}
}
参考: