Jackson XML能否像JSON那样实现无需注解的自定义反序列化?
实现Jackson XML自定义反序列化(无注解)
当然可以!Jackson XML模块提供了和Jackson JSON几乎一致的自定义反序列化能力,完全能满足你不用注解、手动实现XML到List<User>映射的需求。下面是具体的实现步骤和示例:
1. 确保依赖到位
如果是Maven项目,先引入Jackson XML的核心依赖:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.15.2</version> <!-- 替换为最新稳定版即可 --> </dependency>
2. 编写自定义反序列化器
和JSON的JsonDeserializer逻辑类似,Jackson XML的自定义反序列化器继承StdDeserializer,我们会用XmlParser来处理XML节点的解析:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.dataformat.xml.XmlParser; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class UserListDeserializer extends StdDeserializer<List<User>> { // 必须提供无参构造方法 public UserListDeserializer() { this(null); } protected UserListDeserializer(Class<?> vc) { super(vc); } @Override public List<User> deserialize(JsonParser parser, DeserializationContext ctx) throws IOException, JsonProcessingException { // 强转为XmlParser,方便处理XML特有的节点操作 XmlParser xmlParser = (XmlParser) parser; List<User> userList = new ArrayList<>(); User currentUser = null; // 遍历XML节点,逐个解析字段 while (xmlParser.nextToken() != null) { String nodeName = xmlParser.getCurrentName(); if (nodeName == null) continue; // 根据节点名映射到User对象的属性 switch (nodeName) { case "user": currentUser = new User(); userList.add(currentUser); break; case "id": if (currentUser != null) { currentUser.setId(xmlParser.getValueAsInt()); } break; case "name": if (currentUser != null) { currentUser.setName(xmlParser.getValueAsString()); } break; case "email": if (currentUser != null) { currentUser.setEmail(xmlParser.getValueAsString()); } break; // 其他User属性按需添加对应的case } } return userList; } }
3. 注册反序列化器到XmlMapper
接下来把自定义反序列化器注册到XmlMapper中,全程不需要任何注解:
import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import java.util.List; public class XmlToListDemo { public static void main(String[] args) throws IOException { // 示例XML内容 String xmlContent = """ <users> <user> <id>1</id> <name>Alice</name> <email>alice@example.com</email> </user> <user> <id>2</id> <name>Bob</name> <email>bob@example.com</email> </user> </users> """; // 创建XmlMapper并注册自定义反序列化器 XmlMapper xmlMapper = new XmlMapper(); SimpleModule module = new SimpleModule(); // 为List<User>类型绑定自定义反序列化器 module.addDeserializer(List.class, new UserListDeserializer()); xmlMapper.registerModule(module); // 执行反序列化 List<User> users = xmlMapper.readValue(xmlContent, List.class); // 验证结果 users.forEach(user -> System.out.println(user.getName() + " - " + user.getEmail())); } }
关键细节说明
XmlParser是JsonParser的子类,所以你可以复用很多JSON解析里熟悉的方法,比如nextToken()、getValueAsInt()等,同时它还支持XML特有的操作(比如处理命名空间、节点属性等)。- 如果你的XML结构有嵌套或者特殊节点,只需要在
deserialize方法里调整节点遍历和字段映射的逻辑即可。 - 这种方式完全不需要在
User类上添加任何Jackson相关注解,所有映射规则都集中在自定义反序列化器里,完美契合你的需求。
内容的提问来源于stack exchange,提问作者Andrey Sukhovitsky
相关产品推荐
相关产品推荐

