tutorial mvc example java serialization

mvc - Serialización personalizada de Java



spring security module (3)

Java admite serialización personalizada . Lea la sección Personalizar el protocolo predeterminado.

Citar:

Sin embargo, hay una solución extraña pero astuta. Al utilizar una función incorporada del mecanismo de serialización, los desarrolladores pueden mejorar el proceso normal al proporcionar dos métodos dentro de sus archivos de clase. Esos métodos son:

  • private void writeObject (ObjectOutputStream out) arroja IOException;
  • private void readObject (ObjectInputStream in) arroja IOException, ClassNotFoundException;

En este método, lo que podría hacer es serializarlo en otros formularios si lo necesita, como ArrayList for Location que ilustró o JSON u otro formato de datos / método y reconstruirlo de nuevo en readObject ()

Con su ejemplo, agrega el siguiente código:

private void writeObject(ObjectOutputStream oos) throws IOException { // default serialization oos.defaultWriteObject(); // write the object List loc = new ArrayList(); loc.add(location.x); loc.add(location.y); loc.add(location.z); loc.add(location.uid); oos.writeObject(loc); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { // default deserialization ois.defaultReadObject(); List loc = (List)ois.readObject(); // Replace with real deserialization location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3)); // ... more code }

Tengo un objeto que contiene algunos campos no serializables que quiero serializar. Son de una API separada que no puedo cambiar, por lo que Serializable no es una opción. El problema principal es la clase de ubicación. Contiene cuatro cosas que se pueden serializar que necesitaría, todas las entradas. ¿Cómo puedo usar read / writeObject para crear un método de serialización personalizado que pueda hacer algo como esto?

// writeObject: List<Integer> loc = new ArrayList<Integer>(); loc.add(location.x); loc.add(location.y); loc.add(location.z); loc.add(location.uid); // ... serialization code // readObject: List<Integer> loc = deserialize(); // Replace with real deserialization location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3)); // ... more code

¿Cómo puedo hacer esto?


Si debe ser una serialización de Java, la única forma que conozco es redefinir readObject() y writeObject() en todas las clases que tengan una referencia a una instancia de Location como se muestra en la respuesta de Momo. Tenga en cuenta que esto no le permitirá serializar una Location[] , y le solicitará que subclasifique toda la Collection<Location> aparece en su código. Además, requiere que los campos de tipo Location se marquen como transitorios, lo que excluirá que sus definiciones se escriban en la secuencia de serialización, lo que frustrará la detección de cambios de clase incompatibles.

Una mejor manera sería simplemente anular ObjectOutputStream.writeObject . Por desgracia, ese método es final . En su lugar, podría anular ObjectOutputStream.writeObjectOverride() , pero ese método no puede delegar la implementación predeterminada, ObjectOutputStream.writeObject0() porque ese método es private . Por supuesto, podría invocar el método privado utilizando la reflexión, pero ...

Por lo tanto, recomiendo verificar sus restricciones. ¿Tiene que ser la serialización de Java? ¿Realmente no puedes cambiar la definición de Location de clase?

Si tiene el código fuente para clasificar la Location , es bastante trivial agregar implements Serializable y agregarlo a su classpath. Sí, tendrá que hacer esto de nuevo cada vez que actualice la biblioteca, pero podría ser mejor que la alternativa ...


Similar a la respuesta de @momo pero sin usar una lista y los valores int auto-boxed que lo harán mucho más compacto.

private void writeObject(ObjectOutputStream oos) throws IOException { // default serialization oos.defaultWriteObject(); // write the object oos.writeInt(location.x); oos.writeInt(location.y); oos.writeInt(location.z); oos.writeInt(location.uid); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { // default deserialization ois.defaultReadObject(); location = new Location(ois.readInt(), ois.readInt(), ois.readInt(), ois.readInt()); // ... more code }