Gson自定义序列化用于带有自定义注释的字段

huangapple go评论105阅读模式
英文:

Gson custom serialization for fields with custom annotation

问题

  1. <!-- language: java -->
  2. class Demo {
  3. private String name;
  4. private int total;
  5. ...
  6. }

当我使用 gson 序列化一个 Demo 对象时,在正常情况下会得到类似这样的结果:

  1. {"name": "hello world", "total": 100}

现在,我有一个注解 @Xyz,可以添加到任何类的任何属性上。(我可以将此注解应用于任何属性,但目前如果仅限于 String 类型就可以。)

  1. <!-- language: java -->
  2. class Demo {
  3. @Xyz
  4. private String name;
  5. private int total;
  6. ...
  7. }

当我在类属性上使用这个注解时,序列化的数据应该符合以下格式:

  1. {"name": {"value": "hello world", "xyzEnabled": true}, "total": 100}

请注意,无论类的类型如何,此注解都可以应用于任何(String)字段。如果我能在自定义的序列化器的 serialize 方法中获取特定字段的已声明注解,那对我来说将是有效的。

请指导如何实现这一点。

英文:

<!-- language: java -->

  1. class Demo {
  2. private String name;
  3. private int total;
  4. ...
  5. }

When I'm serializing an object of demo with gson, I'll get something like this in the normal scenario:

  1. {&quot;name&quot;: &quot;hello world&quot;, &quot;total&quot;: 100}

Now, I have an annotation @Xyz which can be added to any attribute of any class. (The attribute to which I can apply this annotation can be anything, but for now it should be okay if it is just String type )

<!-- language: java -->

  1. class Demo {
  2. @Xyz
  3. private String name;
  4. private int total;
  5. ...
  6. }

When I've the annotation on the class attribute, the serialized data should be of the following format:

  1. {&quot;name&quot;: {&quot;value&quot;: &quot;hello world&quot;, &quot;xyzEnabled&quot;: true}, &quot;total&quot;: 100}

Please note that this annotation can be applied to any (String) field regardless of the type of the class. If I could somehow get the declared annotations for that specific field on the custom serialiser serialize method, that would work for me.

Please advice how to achieve this.

答案1

得分: 6

I think you meant to use annotation JsonAdapter with your custom behaviour

这是一个示例类 Xyz,它扩展了 JsonSerializer<String>、JsonDeserializer<String>。

  1. import com.google.gson.*;
  2. import java.lang.reflect.Type;
  3. public class Xyz implements JsonSerializer&lt;String&gt;, JsonDeserializer&lt;String&gt; {
  4. @Override
  5. public JsonElement serialize(String element, Type typeOfSrc, JsonSerializationContext context) {
  6. JsonObject object = new JsonObject();
  7. object.addProperty("value", element);
  8. object.addProperty("xyzEnabled", true);
  9. return object;
  10. }
  11. @Override
  12. public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
  13. return json.getAsString();
  14. }
  15. }

这是一个示例用法:

  1. import com.google.gson.annotations.JsonAdapter;
  2. public class Demo {
  3. @JsonAdapter(Xyz.class)
  4. public String name;
  5. public int total;
  6. }

我写了一些额外的测试,也许它们会帮助你解决这个问题:

  1. import com.google.gson.Gson;
  2. import org.junit.Test;
  3. import static org.junit.Assert.assertEquals;
  4. public class Custom {
  5. @Test
  6. public void serializeTest() {
  7. //given
  8. Demo demo = new Demo();
  9. demo.total = 100;
  10. demo.name = "hello world";
  11. //when
  12. String json = new Gson().toJson(demo);
  13. //then
  14. assertEquals("{\"name\":{\"value\":\"hello world\",\"xyzEnabled\":true},\"total\":100}", json);
  15. }
  16. @Test
  17. public void deserializeTest() {
  18. //given
  19. String json = "{\"name\":\"hello world\",\"total\":100}";
  20. //when
  21. Demo demo = new Gson().fromJson(json, Demo.class);
  22. //then
  23. assertEquals("hello world", demo.name);
  24. assertEquals(100, demo.total);
  25. }
  26. }

请注意,以上是你提供的代码的翻译部分,没有其他内容。

英文:

I think you meant to use annotation JsonAdapter with your custom behaviour

This is a sample class Xyz which extends JsonSerializer<String>, JsonDeserializer<String>

  1. import com.google.gson.*;
  2. import java.lang.reflect.Type;
  3. public class Xyz implements JsonSerializer&lt;String&gt;, JsonDeserializer&lt;String&gt; {
  4. @Override
  5. public JsonElement serialize(String element, Type typeOfSrc, JsonSerializationContext context) {
  6. JsonObject object = new JsonObject();
  7. object.addProperty(&quot;value&quot;, element);
  8. object.addProperty(&quot;xyzEnabled&quot;, true);
  9. return object;
  10. }
  11. @Override
  12. public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
  13. return json.getAsString();
  14. }
  15. }

this is a sample use

  1. import com.google.gson.annotations.JsonAdapter;
  2. public class Demo {
  3. @JsonAdapter(Xyz.class)
  4. public String name;
  5. public int total;
  6. }

I've written some more tests maybe they'll help you to solve this problem more

  1. import com.google.gson.Gson;
  2. import org.junit.Test;
  3. import static org.junit.Assert.assertEquals;
  4. public class Custom {
  5. @Test
  6. public void serializeTest() {
  7. //given
  8. Demo demo = new Demo();
  9. demo.total = 100;
  10. demo.name = &quot;hello world&quot;;
  11. //when
  12. String json = new Gson().toJson(demo);
  13. //then
  14. assertEquals(&quot;{\&quot;name\&quot;:{\&quot;value\&quot;:\&quot;hello world\&quot;,\&quot;xyzEnabled\&quot;:true},\&quot;total\&quot;:100}&quot;, json);
  15. }
  16. @Test
  17. public void deserializeTest() {
  18. //given
  19. String json = &quot;{ \&quot;name\&quot;: \&quot;hello world\&quot;, \&quot;total\&quot;: 100}&quot;;
  20. //when
  21. Demo demo = new Gson().fromJson(json, Demo.class);
  22. //then
  23. assertEquals(&quot;hello world&quot;, demo.name);
  24. assertEquals(100, demo.total);
  25. }
  26. }

huangapple
  • 本文由 发表于 2020年4月7日 17:35:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/61076945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定