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;
}
我有一个 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
的自定义 classpublic 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;
}