Java的Spring项目的JSON序列化

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

Java Json Serialization for Spring Project

问题

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

我有一个POJO类,例如:

类A的POJO:

public class A{
   private String field1;
   private String field2;

   @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
   private Integer field3;
   
   // 获取器和设置器

}

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

输入:
field3 - 312548

输出:
field3 - "312,548"

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

自定义JsonSerializer:

public class NumberFormatterToString extends JsonSerializer<Integer> {

	@Override
	public void serialize(Integer value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
		jsonGenerator.writeObject(convertIntegerNumberFormat(value));
	}
	
	public static String convertIntegerNumberFormat(Integer i) {
		NumberFormat myFormat = NumberFormat.getInstance();
		myFormat.setGroupingUsed(true);

		return i != null ? myFormat.format(i) : null;

	}
	
	public static String convertDecimalNumberFormat(Double i) {

		DecimalFormat decimalFormat = new DecimalFormat("#.0000");
		decimalFormat.setGroupingUsed(true);
		decimalFormat.setGroupingSize(3);

		return i != null ? decimalFormat.format(i) : null;

	}

}

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

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

英文:

I have a pojo class, for example :

Class A Pojo:

public class A{
   private String field1;
   private String field2;

   @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
   private Integer field3;
   

//getters and setters

}

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:

public class NumberFormatterToString extends JsonSerializer&lt;Integer&gt; {

	@Override
	public void serialize(Integer value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
		jsonGenerator.writeObject(convertIntegerNumberFormat(value));
	}
	
	public static String convertIntegerNumberFormat(Integer i) {
		NumberFormat myFormat = NumberFormat.getInstance();
		myFormat.setGroupingUsed(true);

		return i != null ? myFormat.format(i) : null;

	}
	
	public static String convertDecimalNumberFormat(Double i) {

		DecimalFormat decimalFormat = new DecimalFormat(&quot;#.0000&quot;);
		decimalFormat.setGroupingUsed(true);
		decimalFormat.setGroupingSize(3);

		return i != null ? decimalFormat.format(i) : null;

	}

}

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:

public class A {
   private String field1;
   private String field2;

   @JsonDeserializer(using = NumberFormatterToInteger.class)
   @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
   private Integer field3;
}

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

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

希望能够起作用。

英文:

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

public class A {
   private String field1;
   private String field2;

   @JsonDeserializer(using = NumberFormatterToInteger.class)
   @JsonSerialize(using = NumberFormatterToString.class, as = String.class)
   private Integer field3;
}

and create custom class that extend JsonDeserializer

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

Hope it will work.

答案2

得分: 0

假设DTO的定义如下:

@JsonSerialize(using = InfoSerializer.class)
@JsonDeserialize(using = InfoDeserializer.class)
class Info {
    private String name;
    private String address;
    private Integer age;
}

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

class InfoSerializer extends JsonSerializer<Info> {

    @Override
    public void serialize(Info value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("name", value.getName());
        jsonGenerator.writeStringField("address", value.getAddress());
        jsonGenerator.writeStringField("age", value.getAge().toString());
        jsonGenerator.writeEndObject();
    }
}

class InfoDeserializer extends JsonDeserializer<Info> {

    @Override
    public Info deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        int age = Integer.parseInt(node.get("age").asText());
        String name = node.get("name").asText();
        String address = node.get("address").asText();

        Info info = new Info();
        info.setName(name);
        info.setAddress(address);
        info.setAge(age);

        return info;
    }
}

测试控制器:

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

输入数据:

{
    "name":"huawei",
    "address":"shen zhen",
    "age":"31"
}

测试控制器打印的消息:

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

客户端收到的响应:

{
    "name": "huawei",
    "address": "shen zhen",
    "age": "31"
}
英文:

Assume the definition of DTO is below:

@JsonSerialize(using = InfoSerializer.class)
@JsonDeserialize(using = InfoDeserializer.class)
class Info {
    private String name;
    private String address;
    private Integer age;
}

Info's Serializer and Deserializer definition

class InfoSerializer extends JsonSerializer&lt;Info&gt; {

    @Override
    public void serialize(Info value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField(&quot;name&quot;, value.getName());
        jsonGenerator.writeStringField(&quot;address&quot;, value.getAddress());
        jsonGenerator.writeStringField(&quot;age&quot;, value.getAge().toString());
        jsonGenerator.writeEndObject();
    }

}


class InfoDeserializer extends JsonDeserializer&lt;Info&gt; {

    @Override
    public Info deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        int age = Integer.parseInt(node.get(&quot;age&quot;).asText());
        String name = node.get(&quot;name&quot;).asText();
        String address = node.get(&quot;address&quot;).asText();

        Info info = new Info();
        info.setName(name);
        info.setAddress(address);
        info.setAge(age);

        return info;
    }
}

Test controller

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

input

{
    &quot;name&quot;:&quot;huawei&quot;,
    &quot;address&quot;:&quot;shen zhen&quot;,
    &quot;age&quot;:&quot;31&quot;
}

Test controller print message

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

The response client get

{
    &quot;name&quot;: &quot;huawei&quot;,
    &quot;address&quot;: &quot;shen zhen&quot;,
    &quot;age&quot;: &quot;31&quot;
}

答案3

得分: 0

我终于在代码逻辑中预期更改的任何地方调用了这个函数

```java
 public static String convertIntegerNumberFormat(Integer i) {
        NumberFormat myFormat = NumberFormat.getInstance();
        myFormat.setGroupingUsed(true);

        return i != null ? myFormat.format(i) : null;

    }
英文:

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

 public static String convertIntegerNumberFormat(Integer i) {
        NumberFormat myFormat = NumberFormat.getInstance();
        myFormat.setGroupingUsed(true);

        return i != null ? myFormat.format(i) : null;

    }

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:

确定