Java Json Spring 项目的序列化

Java Json Serialization for Spring Project

我有一个 pojo class,例如:

Class 一个 Pojo:

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

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

//getters and setters

}

现在从 spring REST API 返回 field3 时,我希望它转换成类似

的东西

输入: 字段 3 - 312548

输出 field3 - “312,548”

我已经编写了自定义 class 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 返回响应时,它应该将其转换为字符串值。

我不确定我应该如何配置它?

可能您所要做的就是创建自定义反序列化器。尝试以类似的方式修改您的 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

的自定义 class
public class NumberFormatterToInteger extends JsonDeserializer<Integer> {
   @Override
   public Integer deserialize(JsonParser parser, DeserializationContext context) {
      
      return YourParser.toInt(parser.getText()); // some logic that could look like that
   }
}

希望它能奏效。

假设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"
}

我终于在任何需要改变代码逻辑的地方调用了这个函数。

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

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

    }