如何用Jackson将部分JSON参数转换为Java DTO的新成员变量
我来给你分享两种实用的实现方式,都能完美满足你的需求:
方法一:利用
@JsonCreator构造方法(推荐,简洁直观) 这种方式不需要额外编写反序列化器,直接在构造方法里完成参数转换与赋值,非常适配你的场景。
首先定义RectangleDto类:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonProperty; public class RectangleDto { private final int area; private final String uselessParameter; // 用@JsonCreator标注构造方法,告诉Jackson用这个方法创建对象 @JsonCreator public RectangleDto( @JsonProperty("sideA") int sideA, @JsonProperty("sideB") int sideB, @JsonProperty("useless_parameter") String uselessParameter) { // 调用你已有的面积计算逻辑(这里示例直接用乘法) this.area = sideA * sideB; this.uselessParameter = uselessParameter; } // 按要求重写toString方法 @Override public String toString() { return String.format("RectangleDto{area = %d, useless_parameter = \"%s\"}", area, uselessParameter); } // 你提到的@JsonGetter用于序列化时映射字段名 @JsonGetter("useless_parameter") public String getUselessParameter() { return uselessParameter; } // 若需要序列化area字段,可添加对应的getter public int getArea() { return area; } }
使用ObjectMapper反序列化的测试代码:
import com.fasterxml.jackson.databind.ObjectMapper; public class Main { public static void main(String[] args) throws Exception { String json = "{\"sideA\" : 2, \"sideB\" : 4, \"useless_parameter\" : \"useless_information\"}"; ObjectMapper mapper = new ObjectMapper(); RectangleDto dto = mapper.readValue(json, RectangleDto.class); System.out.println(dto); // 输出:RectangleDto{area = 8, useless_parameter = "useless_information"} } }
方法二:自定义
JsonDeserializer(更灵活,适配复杂场景) 如果你的转换逻辑比较复杂,或者需要复用转换规则,自定义反序列化器会是更好的选择。
首先编写自定义反序列化器:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; public class RectangleDtoDeserializer extends JsonDeserializer<RectangleDto> { @Override public RectangleDto deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); // 从JSON中提取所需参数 int sideA = node.get("sideA").asInt(); int sideB = node.get("sideB").asInt(); String uselessParameter = node.get("useless_parameter").asText(); // 调用你已有的面积计算方法 int area = calculateArea(sideA, sideB); return new RectangleDto(area, uselessParameter); } // 假设这是你已有的面积计算方法 private int calculateArea(int sideA, int sideB) { return sideA * sideB; } }
然后在RectangleDto类上标注使用该反序列化器:
import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = RectangleDtoDeserializer.class) public class RectangleDto { private final int area; private final String uselessParameter; // 普通构造方法,供反序列化器调用 public RectangleDto(int area, String uselessParameter) { this.area = area; this.uselessParameter = uselessParameter; } @Override public String toString() { return String.format("RectangleDto{area = %d, useless_parameter = \"%s\"}", area, uselessParameter); } @JsonGetter("useless_parameter") public String getUselessParameter() { return uselessParameter; } public int getArea() { return area; } }
测试代码和方法一完全一致,运行后同样能得到预期输出。
小提醒
你提到的@JsonGetter主要用于序列化阶段,用来绑定Java属性与JSON字段名;反序列化时如果需要指定字段映射,@JsonProperty会更准确,方法一中的构造方法已经用它完成了JSON键与参数的绑定。
内容的提问来源于stack exchange,提问作者Yevhenii S.
相关产品推荐
相关产品推荐

