Spring Boot中使用Jackson将天气API响应JSON映射为多POJO类问题咨询
Jackson 映射天气API响应到多个POJO实现方案
1. 前置依赖引入
Maven项目直接在pom.xml中添加Jackson核心依赖即可:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency>
Gradle项目对应添加implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'即可。
2. 定义对应层级的POJO类
JSON响应是三层嵌套结构:外层对象包含location、current两个子对象,current内部又嵌套condition子对象,POJO需要和这个结构对应:
2.1 位置信息类(Location)
对应JSON中location节点的字段:
import com.fasterxml.jackson.annotation.JsonProperty; public class Location { private String name; private String region; private String country; private Double lat; private Double lon; @JsonProperty("tz_id") // 字段名和JSON键名不一致时用该注解绑定 private String tzId; @JsonProperty("localtime_epoch") private Long localtimeEpoch; private String localtime; // 补充所有属性的getter、setter方法,也可直接用Lombok的@Data注解省略手写 public String getName() { return name; } public void setName(String name) { this.name = name; } // 其余getter、setter省略 }
2.2 天气状况类(Condition)
对应JSON中current.condition节点的字段:
public class Condition { private String text; private String icon; private Integer code; // getter、setter省略 }
2.3 当前天气类(Current)
对应JSON中current节点的字段,内部嵌套Condition类:
import com.fasterxml.jackson.annotation.JsonProperty; public class Current { @JsonProperty("last_updated_epoch") private Long lastUpdatedEpoch; @JsonProperty("last_updated") private String lastUpdated; @JsonProperty("temp_c") private Double tempC; @JsonProperty("temp_f") private Double tempF; @JsonProperty("is_day") private Integer isDay; private Condition condition; // 嵌套天气状况类 @JsonProperty("wind_mph") private Double windMph; @JsonProperty("wind_kph") private Double windKph; @JsonProperty("wind_degree") private Integer windDegree; @JsonProperty("wind_dir") private String windDir; @JsonProperty("pressure_mb") private Double pressureMb; @JsonProperty("pressure_in") private Double pressureIn; @JsonProperty("precip_mm") private Double precipMm; @JsonProperty("precip_in") private Double precipIn; private Integer humidity; private Integer cloud; @JsonProperty("feelslike_c") private Double feelslikeC; @JsonProperty("feelslike_f") private Double feelslikeF; @JsonProperty("vis_km") private Double visKm; @JsonProperty("vis_miles") private Double visMiles; private Double uv; @JsonProperty("gust_mph") private Double gustMph; @JsonProperty("gust_kph") private Double gustKph; // getter、setter省略 }
2.4 外层响应包装类(可选)
如果需要一次性解析整个JSON,可以新增外层包装类:
public class WeatherResponse { private Location location; private Current current; public Location getLocation() { return location; } public void setLocation(Location location) { this.location = location; } public Current getCurrent() { return current; } public void setCurrent(Current current) { this.current = current; } }
3. 执行反序列化操作
方案1:通过外层包装类一次性解析
拿到API返回的JSON字符串后直接转成外层包装类对象,即可提取所有对应POJO实例:
import com.fasterxml.jackson.databind.ObjectMapper; public class WeatherParseTest { public static void main(String[] args) { // 替换为实际调用天气API拿到的响应字符串 String jsonResponse = "API返回的JSON字符串"; ObjectMapper objectMapper = new ObjectMapper(); try { WeatherResponse resp = objectMapper.readValue(jsonResponse, WeatherResponse.class); // 直接获取各POJO实例 Location location = resp.getLocation(); Current current = resp.getCurrent(); Condition condition = current.getCondition(); // 后续业务逻辑 System.out.println("当前城市:" + location.getName()); System.out.println("当前温度:" + current.getTempC() + "℃"); System.out.println("天气状况:" + condition.getText()); } catch (Exception e) { e.printStackTrace(); } } }
方案2:单独解析指定节点(无需定义外层包装类)
如果只需要部分节点的POJO,也可以先解析为JsonNode再单独转对应类型:
JsonNode rootNode = objectMapper.readTree(jsonResponse); // 单独解析location节点为Location对象 Location location = objectMapper.treeToValue(rootNode.get("location"), Location.class); // 单独解析current节点为Current对象 Current current = objectMapper.treeToValue(rootNode.get("current"), Current.class);
4. 常用配置说明
- 忽略JSON中存在但POJO没有定义的字段,避免反序列化报错:
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - 空字符串转空对象不报错:
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
内容的提问来源于stack exchange,提问作者SkepticalTiger
相关产品推荐
相关产品推荐

