如何在RestController中使用基于JsonView的两个不同的getter进行序列化? [英] How do I serialize using two different getters based on JsonView in RestController?

查看:98
本文介绍了如何在RestController中使用基于JsonView的两个不同的getter进行序列化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够基于JsonView序列化对象中的字段.不必是JsonView,这只是我一直在探索的东西.基本上在RestController类上使用@JsonView批注,它将序列化我的POJO. 但是我有一个用户和管理员视图,其中有一个对象:

I want the ability to serialize a field in an object based on the JsonView. It doesn't have to be JsonView, it's just what I have been exploring. Basically using @JsonView annotation on RestController class, it would serialize my POJO. However I have a User and Admin view where there is an object:

地图机密;

对于管理员视图,我希望key:value都显示并序列化,但是对于用户,我只希望使用List键,或者如果它更简单,请保留Map但只显示键,并且所有值都切换到'****'4个星号或其他内容.

That for an Admin view I want both key:value to show up and serialize, but for a User I would only want a List keys or if its simpler, keep Map but only show the key and all of the values switch to '****' 4 asteriks or something.

我考虑过要有两个吸气剂,但是JsonView注释不能像两个吸气剂可以有不同的视图而杰克逊知道要调用哪个视图那样工作.

I thought about having two getters but the JsonView annotation doesn't work like that where two getters can have different views and Jackson knows which one to call.

我不确定JsonView是这里最好的东西.也许是一种基于视图或某些自定义序列化器进行序列化的JsonGetter方法,但是我认为可能会有一种更直接的方法来使用Jackson和很少的批注进行

I'm not sure JsonView is the best thing here. Perhaps a JsonGetter method that serializes based on view or some custom serializer, but I think there might be a more straightforward way to do it with Jackson and few annotations

我想要做的是:

Person.java
Map<String,String> secrets;

这将序列化为(对于管理员):

This would serialize to (for Admin):

{
"person":{
  "secrets":{
     "password":"123456",
     "creditCard":"1234 5678 9101"
   }
 }
}

这将序列化为(对于用户):

This would serialize to (for User):

{
"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;
}

推荐答案

您可以尝试为对象映射器定义自定义序列化器,这样,只要 object mapper 用于序列化时,您可以检查密码和信用卡字段并将其转换为您选择的值.例如

You can try defining a custom serializer for the object mapper , so that whenever the object mapper is used for serialization you can check and convert the password and credit card field to the value you choose.For example

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();
    }
}

您可以提供一个使用该自定义序列化程序的对象映射器,

You can provide an object mapper that utilizes this custom serializer then,

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.

In your case you can register the objectmapper bean with the custom serializer in the spring context and make jackson use your object mapper 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));
    }
}

引用:

https://www.baeldung.com/jackson-json-view-annotation

https://www.baeldung.com/jackson-custom-serialization

这篇关于如何在RestController中使用基于JsonView的两个不同的getter进行序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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