XStream fromXML()方法抛出异常的原因及修复方案
问题原因
抛出ForbiddenClassException是因为XStream的安全机制限制:从1.4.7版本开始,XStream为防范反序列化漏洞,默认仅允许反序列化Java标准库的核心类,自定义的ListaPersonas和Persona类不在默认许可范围内,调用fromXML()时会被权限拦截,触发异常。
修复方案
需要显式配置XStream,允许反序列化你的自定义类,常用两种方式:
方式1:允许指定单个类
在创建XStream实例后、执行序列化/反序列化操作前,添加权限配置:
// 方式A:通过NoTypePermission添加例外类 xstream.addPermission(new NoTypePermission().withExceptions(ListaPersonas.class, Persona.class)); // 方式B:用更简洁的allowTypes方法 xstream.allowTypes(new Class[]{ListaPersonas.class, Persona.class});
方式2:允许整个包下的类(适用于自定义类同包场景)
如果ListaPersonas和Persona属于同一包(比如com.yourpackage),可直接授权整个包:
xstream.allowTypesByWildcard(new String[]{"com.yourpackage.**"});
修改后的完整代码
import java.io.*; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.security.NoTypePermission; public class EscribirPersonas { public static void main(String[] args) throws IOException, ClassNotFoundException { File fichero = new File("FichPersona.dat"); FileInputStream filein = new FileInputStream(fichero); ObjectInputStream dataIS = new ObjectInputStream(filein); System.out.println("Comienza el proceso..."); //Creamos el objeto Lista de Personas ListaPersonas listaper = new ListaPersonas(); try { while (true) {//lectura del fichero Persona persona = (Persona) dataIS.readObject(); listaper.add(persona); //añadimos persona a la lista } } catch (EOFException eo) {} dataIS.close(); //cerrar stream de entrada try { XStream xstream = new XStream(); // 添加安全权限,允许自定义类反序列化 xstream.addPermission(new NoTypePermission().withExceptions(ListaPersonas.class, Persona.class)); //cambiamos el nombre a las etiquetas XML xstream.alias("ListaPersonasMunicipio", ListaPersonas.class); xstream.alias("DatosPersona", Persona.class); //quitamos la etiqueta lista (atributo de la clase ListaPersonas) xstream.addImplicitCollection(ListaPersonas.class, "lista"); //Insertamos los objetos en el XML xstream.toXML(listaper, new FileOutputStream("Personas.xml")); System.out.println("Creado fichero XML..."); File ficheroXML = new File("Personas.xml"); FileInputStream fis = new FileInputStream (ficheroXML); Object o = xstream.fromXML(fis); } catch (Exception e) {e.printStackTrace();} } // fin main } // fin clase
注意事项
- 禁止在生产环境使用
xstream.addPermission(AnyTypePermission.ANY),这会完全关闭安全检查,存在反序列化攻击风险。 - 遵循最小权限原则,仅授权实际需要反序列化的类或包。
内容的提问来源于stack exchange,提问作者errorrelativo
相关产品推荐
相关产品推荐

