Dynamic addition of fasterxml Annotation?

前端 未结 2 745
闹比i
闹比i 2021-01-24 04:20

Is there a way to set @JsonProperty annotation dynamically like:

class A {

    @JsonProperty(\"newB\") //adding this dynamically
    private String b;

}


        
相关标签:
2条回答
  • 2021-01-24 04:48

    this is a very late answer but, if it helps you or others, you should be able to change annotations at runtime. Check this link:

    https://www.baeldung.com/java-reflection-change-annotation-params

    Modifying annotations might be a bit messy and I prefer other options.

    Mixin's are a good static option but if you need to change properties at runtime you can use a custom serializer (or deserializer). Then register your serializer with the ObjectMapper of your choosing (writing formats like json / xml are now provided for free via Jackson). Here are some additional examples:

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

    custom deserializer: https://www.baeldung.com/jackson-deserialization

    i.e.:

        class A {
            //        @JsonProperty("newB") //adding this dynamically
            String b;
        }
    
        class ASerializer extends StdSerializer<A> {
    
            public ASerializer() {
                this(null);
            }
    
            public ASerializer(Class<A> a) {
                super(a);
            }
    
            @Override
            public void serialize(A a, JsonGenerator gen, SerializerProvider provider) throws IOException {
    
                if (a == null) {
                    gen.writeNull();
    
                } else {
                    gen.writeStartObject();
                    gen.writeStringField("newB", a.b);
                    gen.writeEndObject();
                }
            }
        }
    
        @Test
        public void test() throws JsonProcessingException {
            A a = new A();
            a.b = "bbb";
            String exp = "{\"newB\":\"bbb\"}";
    
            ObjectMapper mapper = new ObjectMapper();
    
            SimpleModule module = new SimpleModule();
            module.addSerializer(A.class, new ASerializer());
            mapper.registerModule(module);
    
            assertEquals(exp, mapper.writeValueAsString(a));
        }
    
    0 讨论(0)
  • 2021-01-24 04:54

    Assume that your POJO class looks like this:

    class PojoA {
    
        private String b;
    
        // getters, setters
    }
    

    Now, you have to create MixIn interface:

    interface PojoAMixIn {
    
        @JsonProperty("newB")
        String getB();
    }
    

    Simple usage:

    PojoA pojoA = new PojoA();
    pojoA.setB("B value");
    
    System.out.println("Without MixIn:");
    ObjectMapper mapper = new ObjectMapper();
    System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(pojoA));
    
    System.out.println("With MixIn:");
    ObjectMapper mapperWithMixIn = new ObjectMapper();
    mapperWithMixIn.addMixInAnnotations(PojoA.class, PojoAMixIn.class);
    System.out.println(mapperWithMixIn.writerWithDefaultPrettyPrinter().writeValueAsString(pojoA));
    

    Above program prints:

    Without MixIn:
    {
      "b" : "B value"
    }
    With MixIn:
    {
      "newB" : "B value"
    }
    
    0 讨论(0)
提交回复
热议问题