You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XStream进行JSON反序列化遇CannotResolveClassException求助

JSON反序列化失败问题排查与解决

问题现象

XML反序列化正常,JSON反序列化时抛出如下异常,提示无法解析name类:

Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : name
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /AcademicGroup/students/name
line number         : -1
class[1]            : AcademicGroup
required-type[1]    : AcademicGroup
converter-type[1]   : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version             : 1.4.20
-------------------------------
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:81)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:68)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:74)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:68)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:52)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:136)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1464)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1441)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1407)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1352)
    at AcademicGroupJSONDeserialization.main(AcademicGroupJSONDeserialization.java:14)
Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: name
    at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:81)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
    at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
    at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
    at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
    at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
    at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
    at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
    at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readBareItem(AbstractCollectionConverter.java:131)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:117)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:99)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:92)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:86)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:81)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:74)
    ... 16 more

Process finished with exit code 1

待反序列化的JSON内容:

{"AcademicGroup": {
  "students": [
    {
      "name": "John Doe",
      "age": 20
    },
    {
      "name": "Jane Smith",
      "age": 22
    }
  ]
}}

用到的代码

序列化代码

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class AcademicGroupSerialization {
    public static void main(String[] args) {
        AcademicGroup academicGroup = new AcademicGroup();
        Student student1 = new Student("John Doe", 20);
        Student student2 = new Student("Jane Smith", 22);
        academicGroup.addStudent(student1);
        academicGroup.addStudent(student2);

        // Serializing to xml
        XStream xStream = new XStream();
        xStream.alias("AcademicGroup", AcademicGroup.class);
        String xml = xStream.toXML(academicGroup);
        try (FileWriter fw = new FileWriter("AcademicGroup.xml"); PrintWriter out = new PrintWriter(fw)) {
            out.println(xml);
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        // Serializing to JSON
        xStream = new XStream(new JsonHierarchicalStreamDriver());
        xStream.alias("AcademicGroup", AcademicGroup.class);
        String json = xStream.toXML(academicGroup);
        try (FileWriter fw = new FileWriter("AcademicGroup.json");
             PrintWriter out = new PrintWriter(fw)) {
            out.println(json);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

反序列化代码

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;

import java.io.File;

public class AcademicGroupJSONDeserialization {
    public static void main(String[] args) {
        XStream xStream = new XStream(new JettisonMappedXmlDriver());
        xStream.addPermission(AnyTypePermission.ANY);

        xStream.alias("AcademicGroup", AcademicGroup.class);

        AcademicGroup academicGroup = (AcademicGroup) xStream.fromXML(new File("AcademicGroup.json"));
        System.out.println(academicGroup);
    }
}

实体类代码

import java.util.ArrayList;
import java.util.List;

public class AcademicGroup {
    private List<Student> students = new ArrayList<>();

    public void addStudent(Student student) {
        students.add(student);
    }

    public List<Student> getStudents() {
        return students;
    }

    @Override
    public String toString() {
        return "Student.AcademicGroup{" +
                "students=" + students +
                '}';
    }
}

public class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Геттеры и сеттеры
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

问题原因

  1. JSON驱动不匹配:序列化用JsonHierarchicalStreamDriver,反序列化用JettisonMappedXmlDriver,两者对JSON结构的解析逻辑不一致,导致XStream无法识别集合中的对象。
  2. 缺少实体类别名:未给Student类设置XStream别名,XStream无法将JSON中的对象映射到Student类,误把name字段当作类名解析。
  3. 缺少无参构造函数:Student类只有带参构造,XStream反射实例化对象时必须依赖无参构造,否则无法创建对象实例。

修复方案

1. 统一JSON驱动

序列化和反序列化使用同一种JSON驱动,两种可选方式:

方式一:统一使用JsonHierarchicalStreamDriver

修改反序列化代码,替换驱动并添加Student别名:

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;

import java.io.File;

public class AcademicGroupJSONDeserialization {
    public static void main(String[] args) {
        XStream xStream = new XStream(new JsonHierarchicalStreamDriver());
        xStream.addPermission(AnyTypePermission.ANY);

        xStream.alias("AcademicGroup", AcademicGroup.class);
        xStream.alias("student", Student.class); // 给Student类添加别名

        AcademicGroup academicGroup = (AcademicGroup) xStream.fromXML(new File("AcademicGroup.json"));
        System.out.println(academicGroup);
    }
}

方式二:统一使用JettisonMappedXmlDriver

修改序列化代码中的JSON部分,使用JettisonMappedXmlDriver并添加Student别名:

// Serializing to JSON
xStream = new XStream(new JettisonMappedXmlDriver());
xStream.alias("AcademicGroup", AcademicGroup.class);
xStream.alias("student", Student.class);
String json = xStream.toXML(academicGroup);

同时反序列化代码也要添加xStream.alias("student", Student.class);。

2. 给Student类添加无参构造函数

修改Student类,补充无参构造:

public class Student {
    String name;
    int age;

    // 添加无参构造函数
    public Student() {}

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 原有getter、setter和toString方法保持不变
}

3. 重新生成JSON文件

修改序列化代码后,重新运行生成新的JSON文件,再执行反序列化即可成功。

内容的提问来源于stack exchange,提问作者Давид Чобанян

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:47:04