Java的Spring项目的JSON序列化

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

Java Json Serialization for Spring Project

问题

以下是您要求的翻译内容:

我有一个POJO类,例如:

类A的POJO:

  1. public class A{
  2. private String field1;
  3. private String field2;
  4. @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
  5. private Integer field3;
  6. // 获取器和设置器
  7. }

现在,当从Spring REST API返回field3时,我希望将其转换为类似于以下的内容:

输入:
field3 - 312548

输出:
field3 - "312,548"

我编写了自定义类JsonSerializer来实现这一点:

自定义JsonSerializer:

  1. public class NumberFormatterToString extends JsonSerializer<Integer> {
  2. @Override
  3. public void serialize(Integer value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
  4. jsonGenerator.writeObject(convertIntegerNumberFormat(value));
  5. }
  6. public static String convertIntegerNumberFormat(Integer i) {
  7. NumberFormat myFormat = NumberFormat.getInstance();
  8. myFormat.setGroupingUsed(true);
  9. return i != null ? myFormat.format(i) : null;
  10. }
  11. public static String convertDecimalNumberFormat(Double i) {
  12. DecimalFormat decimalFormat = new DecimalFormat("#.0000");
  13. decimalFormat.setGroupingUsed(true);
  14. decimalFormat.setGroupingSize(3);
  15. return i != null ? decimalFormat.format(i) : null;
  16. }
  17. }

如果我使用这个注解,即使在内部操作中也会进行转换,从而导致已经编写的基于整数的逻辑失败。
因此,我希望以某种方式配置它,即在所有内部操作中都应该将其视为整数,只有在通过API返回响应时才将其转换为字符串值。

我不确定应该如何配置这个问题。

英文:

I have a pojo class, for example :

Class A Pojo:

  1. public class A{
  2. private String field1;
  3. private String field2;
  4. @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
  5. private Integer field3;
  6. //getters and setters
  7. }

Now while returning field3 from spring REST API, i want it convert to something like

Input :
field3 - 312548

Output
field3 - "312,548"

I have written custom class JsonSerializer to do so:

Custom JsonSerializer:

  1. public class NumberFormatterToString extends JsonSerializer&lt;Integer&gt; {
  2. @Override
  3. public void serialize(Integer value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
  4. jsonGenerator.writeObject(convertIntegerNumberFormat(value));
  5. }
  6. public static String convertIntegerNumberFormat(Integer i) {
  7. NumberFormat myFormat = NumberFormat.getInstance();
  8. myFormat.setGroupingUsed(true);
  9. return i != null ? myFormat.format(i) : null;
  10. }
  11. public static String convertDecimalNumberFormat(Double i) {
  12. DecimalFormat decimalFormat = new DecimalFormat(&quot;#.0000&quot;);
  13. decimalFormat.setGroupingUsed(true);
  14. decimalFormat.setGroupingSize(3);
  15. return i != null ? decimalFormat.format(i) : null;
  16. }
  17. }

If i use this Annotation it converts it even while internal operations and thus causes already written Integer based logic to fail.
Thus i want to configure it in a way that, for all internal operation it should consider Integer, only while returning the response via API it should convert it to the String value.

I am not sure how exactly should i configure this?

答案1

得分: 0

可能你只需要创建自定义的反序列化器。尝试以类似的方式修改你的 POJO:

  1. public class A {
  2. private String field1;
  3. private String field2;
  4. @JsonDeserializer(using = NumberFormatterToInteger.class)
  5. @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
  6. private Integer field3;
  7. }

然后创建一个继承自 JsonDeserializer 的自定义类:

  1. public class NumberFormatterToInteger extends JsonDeserializer<Integer> {
  2. @Override
  3. public Integer deserialize(JsonParser parser, DeserializationContext context) {
  4. return YourParser.toInt(parser.getText()); // 一些类似这样的逻辑
  5. }
  6. }

希望能够起作用。

英文:

Probably all you have to do is to create custom deserializer. Try to modify your pojo in a similar way:

  1. public class A {
  2. private String field1;
  3. private String field2;
  4. @JsonDeserializer(using = NumberFormatterToInteger.class)
  5. @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
  6. private Integer field3;
  7. }

and create custom class that extend JsonDeserializer

  1. public class NumberFormatterToInteger extends JsonDeserializer&lt;Integer&gt; {
  2. @Override
  3. public Integer deserialize(JsonParser parser, DeserializationContext context) {
  4. return YourParser.toInt(parser.getText()); // some logic that could look like that
  5. }
  6. }

Hope it will work.

答案2

得分: 0

假设DTO的定义如下:

  1. @JsonSerialize(using = InfoSerializer.class)
  2. @JsonDeserialize(using = InfoDeserializer.class)
  3. class Info {
  4. private String name;
  5. private String address;
  6. private Integer age;
  7. }

Info的序列化器和反序列化器定义如下:

  1. class InfoSerializer extends JsonSerializer<Info> {
  2. @Override
  3. public void serialize(Info value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
  4. jsonGenerator.writeStartObject();
  5. jsonGenerator.writeStringField("name", value.getName());
  6. jsonGenerator.writeStringField("address", value.getAddress());
  7. jsonGenerator.writeStringField("age", value.getAge().toString());
  8. jsonGenerator.writeEndObject();
  9. }
  10. }
  11. class InfoDeserializer extends JsonDeserializer<Info> {
  12. @Override
  13. public Info deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
  14. JsonNode node = jsonParser.getCodec().readTree(jsonParser);
  15. int age = Integer.parseInt(node.get("age").asText());
  16. String name = node.get("name").asText();
  17. String address = node.get("address").asText();
  18. Info info = new Info();
  19. info.setName(name);
  20. info.setAddress(address);
  21. info.setAge(age);
  22. return info;
  23. }
  24. }

测试控制器:

  1. @PostMapping(value = "/test/mapper")
  2. public Mono<Info> test(@RequestBody Info info) {
  3. System.out.println(info);
  4. return Mono.just(info);
  5. }

输入数据:

  1. {
  2. "name":"huawei",
  3. "address":"shen zhen",
  4. "age":"31"
  5. }

测试控制器打印的消息:

  1. Info{name='huawei', address='shen zhen', age=31}

客户端收到的响应:

  1. {
  2. "name": "huawei",
  3. "address": "shen zhen",
  4. "age": "31"
  5. }
英文:

Assume the definition of DTO is below:

  1. @JsonSerialize(using = InfoSerializer.class)
  2. @JsonDeserialize(using = InfoDeserializer.class)
  3. class Info {
  4. private String name;
  5. private String address;
  6. private Integer age;
  7. }

Info's Serializer and Deserializer definition

  1. class InfoSerializer extends JsonSerializer&lt;Info&gt; {
  2. @Override
  3. public void serialize(Info value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
  4. jsonGenerator.writeStartObject();
  5. jsonGenerator.writeStringField(&quot;name&quot;, value.getName());
  6. jsonGenerator.writeStringField(&quot;address&quot;, value.getAddress());
  7. jsonGenerator.writeStringField(&quot;age&quot;, value.getAge().toString());
  8. jsonGenerator.writeEndObject();
  9. }
  10. }
  11. class InfoDeserializer extends JsonDeserializer&lt;Info&gt; {
  12. @Override
  13. public Info deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
  14. JsonNode node = jsonParser.getCodec().readTree(jsonParser);
  15. int age = Integer.parseInt(node.get(&quot;age&quot;).asText());
  16. String name = node.get(&quot;name&quot;).asText();
  17. String address = node.get(&quot;address&quot;).asText();
  18. Info info = new Info();
  19. info.setName(name);
  20. info.setAddress(address);
  21. info.setAge(age);
  22. return info;
  23. }
  24. }

Test controller

  1. @PostMapping(value = &quot;/test/mapper&quot;)
  2. public Mono&lt;Info&gt; test(@RequestBody Info info) {
  3. System.out.println(info);
  4. return Mono.just(info);
  5. }

input

  1. {
  2. &quot;name&quot;:&quot;huawei&quot;,
  3. &quot;address&quot;:&quot;shen zhen&quot;,
  4. &quot;age&quot;:&quot;31&quot;
  5. }

Test controller print message

  1. Info{name=&#39;huawei&#39;, address=&#39;shen zhen&#39;, age=31}

The response client get

  1. {
  2. &quot;name&quot;: &quot;huawei&quot;,
  3. &quot;address&quot;: &quot;shen zhen&quot;,
  4. &quot;age&quot;: &quot;31&quot;
  5. }

答案3

得分: 0

  1. 我终于在代码逻辑中预期更改的任何地方调用了这个函数
  2. ```java
  3. public static String convertIntegerNumberFormat(Integer i) {
  4. NumberFormat myFormat = NumberFormat.getInstance();
  5. myFormat.setGroupingUsed(true);
  6. return i != null ? myFormat.format(i) : null;
  7. }
英文:

I have finally called this function anywhere where change was expected in the logic of code.

  1. public static String convertIntegerNumberFormat(Integer i) {
  2. NumberFormat myFormat = NumberFormat.getInstance();
  3. myFormat.setGroupingUsed(true);
  4. return i != null ? myFormat.format(i) : null;
  5. }

huangapple
  • 本文由 发表于 2020年10月15日 19:52:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/64371013.html
匿名

发表评论

匿名网友

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

确定