如何用Jackson将含动态键的YAML反序列化为Java POJO?
解决动态键YAML反序列化为Java POJO的问题
步骤1:添加必要依赖
确保项目包含Jackson的YAML处理相关依赖,以Maven为例:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.15.2</version> </dependency>
步骤2:自定义反序列化器
由于YAML的动态键结构与目标POJO不匹配,需要编写自定义反序列化器完成结构转换:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; public class PathsWrapperDeserializer extends StdDeserializer<PathsWrapper> { public PathsWrapperDeserializer() { super(PathsWrapper.class); } @Override public PathsWrapper deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode rootNode = parser.getCodec().readTree(parser); JsonNode pathsNode = rootNode.get("paths"); List<Path> pathList = new ArrayList<>(); // 遍历动态URL键 Iterator<Map.Entry<String, JsonNode>> pathEntries = pathsNode.fields(); while (pathEntries.hasNext()) { Map.Entry<String, JsonNode> pathEntry = pathEntries.next(); String url = pathEntry.getKey(); JsonNode methodsNode = pathEntry.getValue(); List<Method> methodList = new ArrayList<>(); // 遍历动态HTTP方法键 Iterator<Map.Entry<String, JsonNode>> methodEntries = methodsNode.fields(); while (methodEntries.hasNext()) { Map.Entry<String, JsonNode> methodEntry = methodEntries.next(); String methodName = methodEntry.getKey(); JsonNode methodDetails = methodEntry.getValue(); Method method = new Method(); method.setMethod(methodName); method.setSummary(methodDetails.get("summary").asText()); method.setDescription(methodDetails.get("description").asText()); methodList.add(method); } Path path = new Path(); path.setUrl(url); path.setMethods(methodList); pathList.add(path); } PathsWrapper wrapper = new PathsWrapper(); wrapper.setPaths(pathList); return wrapper; } }
步骤3:为POJO添加反序列化注解
在PathsWrapper类上指定自定义反序列化器,并为所有POJO补充Getter/Setter方法:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = PathsWrapperDeserializer.class) public class PathsWrapper { private List<Path> paths; public List<Path> getPaths() { return paths; } public void setPaths(List<Path> paths) { this.paths = paths; } }
public class Path { private String url; private List<Method> methods; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public List<Method> getMethods() { return methods; } public void setMethods(List<Method> methods) { this.methods = methods; } }
public class Method { private String method; private String summary; private String description; public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
步骤4:执行反序列化
编写代码读取YAML文件并完成反序列化:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import java.io.File; import java.io.IOException; public class YamlDeserializerExample { public static void main(String[] args) { ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); try { PathsWrapper wrapper = mapper.readValue(new File("your-yaml-file.yaml"), PathsWrapper.class); // 验证反序列化结果 for (Path path : wrapper.getPaths()) { System.out.println("URL: " + path.getUrl()); for (Method method : path.getMethods()) { System.out.println(" Method: " + method.getMethod()); System.out.println(" Summary: " + method.getSummary()); System.out.println(" Description: " + method.getDescription()); } } } catch (IOException e) { e.printStackTrace(); } } }
注意事项
- 原YAML存在语法错误,
/account后缺少冒号,修正后的正确YAML如下:
paths: /user: get: summary: Example summary description: Some description /account: post: summary: Another summary description: Another description
内容的提问来源于stack exchange,提问作者Vicardo
相关产品推荐
相关产品推荐

