En informática , el proceso de serialización ( o marshalling ) consiste en transformar la representación en memoria de un objeto a un formato de datos adecuado para su almacenamiento o transmisión , especialmente entre diferentes entornos de ejecución . Se utiliza normalmente cuando es necesario transferir datos entre distintas partes de un programa informático o de un programa a otro.
La técnica de marshaling simplifica las comunicaciones complejas, ya que permite utilizar objetos compuestos en lugar de estar restringido a objetos primitivos .
Comparación con la serialización
El término "marishing" se usa a veces como sinónimo de "serializing" , cuando en realidad la serialización es un paso en el proceso de marshalling de un objeto.
- El proceso de serialización describe la intención general de transferir un objeto activo de un cliente a un servidor (considerando cliente y servidor como conceptos abstractos y simétricos que se corresponden con los extremos de un enlace de comunicación arbitrario, como los sockets ). El objetivo de serializar un objeto es que este, presente en un programa en ejecución , también lo esté en otro ; es decir, un objeto del cliente debe transferirse al servidor, lo que constituye una forma de reificación que permite que la estructura, los datos y el estado del objeto transiten de un entorno de ejecución a otro, aprovechando una representación intermedia, serializada y "seca" (de importancia secundaria) que circula por el socket de comunicación.
- La serialización no necesariamente tiene esta misma intención, ya que solo se ocupa de transformar los datos para generar esa representación intermedia y "seca" del objeto (por ejemplo, en una secuencia de bytes) que luego podría materializarse en un entorno de ejecución diferente, o simplemente almacenarse en una base de datos, un archivo o en la memoria.
Por lo tanto, la serialización y la gestión de datos podrían realizarse de manera diferente, aunque generalmente se utiliza alguna forma de serialización para realizar la gestión de datos. [ 1 ]
El término deserialización es similar a la deserialización de un objeto "en el servidor", es decir, deserializarlo para recuperar un objeto vivo: el objeto serializado se transforma en una estructura de datos interna, es decir, un objeto vivo dentro del entorno de ejecución. Generalmente corresponde al proceso inverso de la serialización, aunque a veces ambos extremos del proceso activan lógica de negocio específica.
La definición precisa de serialización (marshalling) difiere entre lenguajes de programación como Python , Java y .NET , y en algunos contextos, se utiliza indistintamente con el término serialización.
Serialización en diferentes lenguajes de programación
Serializar un objeto significa convertir su estado en una secuencia de bytes de tal manera que dicha secuencia pueda convertirse de nuevo en una copia del objeto, lo que en esencia es la deserialización. Los distintos lenguajes de programación distinguen entre ambos conceptos. Algunos ejemplos:
En Python , el término "marshal" se utiliza para un tipo específico de "serialización" en la biblioteca estándar de Python [ 2 ] , que consiste en almacenar objetos internos de Python:
El módulo marshal existe principalmente para admitir la lectura y escritura del código "pseudocompilado" para módulos de Python de archivos .pyc .
…
Si estás serializando y deserializando objetos Python, usa el
picklemódulo en su lugar.
— La biblioteca estándar de Python [ 3 ]
En el RFC 2713 relacionado con Java , el serializado se utiliza para serializar objetos para su invocación remota . Un objeto serializado registra el estado del objeto original y contiene el código fuente ( aquí, el código fuente se refiere a una lista de URL desde donde se puede cargar el código del objeto, no al código fuente). Por lo tanto, para convertir el estado del objeto y el código fuente, es necesario deserializarlo. La interfaz de deserialización convierte automáticamente los datos serializados que contienen el código fuente en un objeto Java ejecutable en JAXB. Cualquier objeto que pueda deserializarse puede deserializarse. Sin embargo, lo contrario no tiene por qué ser cierto.
"Serializar" un objeto significa registrar su estado y código fuente de tal manera que, al deserializarlo, se obtenga una copia del original, posiblemente mediante la carga automática de las definiciones de clase. Se puede serializar cualquier objeto que sea serializable o remoto (es decir, que implemente la
java.rmi.Remoteinterfaz). La serialización es similar a la serialización, con la diferencia de que también registra el código fuente. La serialización se distingue de la serialización en que trata los objetos remotos de forma especial.…
Cualquier objeto cuyos métodos puedan invocarse [en un objeto de otra máquina virtual Java] debe implementar la
java.rmi.Remoteinterfaz. Cuando se invoca dicho objeto, sus argumentos se serializan y se envían desde la máquina virtual local a la remota, donde se deserializan y se utilizan.
— Esquema para representar objetos Java en un directorio LDAP (RFC 2713) [ 4 ]
En .NET , el término "marshalling" también se utiliza para referirse a la serialización cuando se utilizan llamadas remotas :
Cuando se serializa un objeto por valor, se crea una copia del objeto y se serializa en el servidor. Cualquier llamada a método que se realice en ese objeto se ejecuta en el servidor.
— Cómo serializar un objeto a un servidor remoto por valor usando Visual Basic .NET (Q301116) [ 5 ]
Uso y ejemplos
El proceso de marshaling se utiliza en implementaciones de diferentes mecanismos de llamada a procedimiento remoto (RPC), donde es necesario transportar datos entre procesos y/o entre hilos .
En el modelo de objetos componentes (COM) de Microsoft , los punteros de interfaz deben serializarse al cruzar los límites del apartamento COM. [ 6 ] [ 7 ] En .NET Framework , la conversión entre un tipo no administrado y un tipo CLR , como en el proceso P/Invoke , también es un ejemplo de una acción que requiere que se realice la serialización. [ 8 ]
Además, la serialización se utiliza ampliamente en scripts y aplicaciones que emplean las tecnologías XPCOM proporcionadas por el marco de trabajo de aplicaciones de Mozilla . El navegador Mozilla Firefox es una aplicación popular desarrollada con este marco de trabajo, que además permite que los lenguajes de scripting utilicen XPCOM a través de XPConnect (Cross-Platform Connect).
Ejemplo
En la familia de sistemas operativos Microsoft Windows, todos los controladores de dispositivos para Direct3D son controladores en modo kernel. La parte de la API que se ejecuta en modo usuario la gestiona el entorno de ejecución DirectX proporcionado por Microsoft.
Esto supone un problema porque llamar a operaciones en modo kernel desde el modo usuario requiere realizar una llamada al sistema , lo que inevitablemente obliga a la CPU a cambiar al modo kernel. Esta es una operación lenta, que tarda microsegundos en completarse. [ 9 ] Durante este tiempo, la CPU no puede realizar ninguna operación. Por lo tanto, minimizar el número de veces que debe realizarse esta operación de cambio optimizaría el rendimiento de forma sustancial.
Los controladores OpenGL de Linux se dividen en dos: un controlador de kernel y un controlador de espacio de usuario. El controlador de espacio de usuario se encarga de traducir todos los comandos OpenGL a código máquina para enviarlos a la GPU . Para reducir el número de llamadas al sistema, el controlador de espacio de usuario implementa la serialización. Si el búfer de comandos de la GPU está lleno de datos de renderizado, la API puede simplemente almacenar la llamada de renderizado solicitada en un búfer temporal y, cuando el búfer de comandos esté casi vacío, puede cambiar al modo kernel y agregar varios comandos almacenados a la vez.
Formatos
La serialización de datos requiere algún tipo de transferencia de datos, que utiliza un formato de datos específico que debe elegirse como destino de la serialización.
XML vs JSON vs…
XML es uno de esos formatos y medios para transferir datos entre sistemas. Microsoft, por ejemplo, lo utiliza como base de los formatos de archivo de los distintos componentes (Word, Excel, Access, PowerPoint, etc.) de la suite Microsoft Office (véase Office Open XML ).
Si bien esto suele resultar en un formato de transmisión extenso, la sintaxis XML, con sus etiquetas de inicio y fin completamente entre corchetes, permite diagnósticos más precisos y una recuperación más sencilla ante errores de transmisión o de disco. Además, dado que las etiquetas se repiten, se pueden utilizar métodos de compresión estándar para reducir el tamaño del contenido; todos los formatos de archivo de Office se crean comprimiendo el XML original. [ 10 ] Los formatos alternativos, como JSON (JavaScript Object Notation), son más concisos, pero, en consecuencia, menos robustos para la recuperación de errores.
Una vez que los datos se transfieren a un programa o aplicación, es necesario convertirlos de nuevo en un objeto para su uso. Por lo tanto, el proceso de deserialización se utiliza generalmente en el receptor de las implementaciones de los mecanismos de invocación de métodos remotos (RMI) y llamada a procedimientos remotos (RPC) para deserializar los objetos transmitidos y convertirlos en un formato ejecutable.
JAXB
JAXB o Arquitectura Java para Enlace XML es el marco de trabajo más común utilizado por los desarrolladores para serializar y deserializar objetos Java. JAXB permite la interconversión entre los tipos de datos fundamentales compatibles con Java y los tipos de datos estándar del esquema XML . [ 11 ]
XmlSerializer
System.Xml.Serialization.XmlSerializeres el marco de trabajo utilizado por los desarrolladores de C# para serializar y deserializar objetos C#. Una de las ventajas de C# sobre Java es que C# admite la serialización de forma nativa debido a la inclusión de la clase. Java, por otro lado, requiere un código de enlaceSystem.Xml.Serialization.XmlSerializer no nativo en forma de JAXB para admitir la serialización. [ 12 ]
De XML a una representación ejecutable
Un ejemplo de deserialización es la conversión de una representación XML de un objeto a la representación predeterminada del objeto en cualquier lenguaje de programación. Considere la siguiente clase:
clase pública Estudiante { cadena privada nombre ; entero privado id ;public String getName () { return this . name ; }public int getId () { return this . id ; }void setName ( String name ) { this . name = name ; }void setId ( int id ) { this.id = id ; } }- Representación XML de un
Studentobjeto específico:
<?xml version="1.0" encoding="UTF-8"?> <student id= "11235813" > <name> Alice </name> </student> <student id= "21345589" > <name> Bob </name> </student>- Representación ejecutable de ese
Studentobjeto:
Estudiante s1 = nuevo Estudiante (); s1 . setId ( 11235813 ); s1 . setName ( "Alice" ); Estudiante s2 = nuevo Estudiante (); s2 . setId ( 21345589 ); s2 . setName ( "Bob" );La deserialización es el proceso de convertir la representación XML a la representación Java ejecutable predeterminada y ejecutar ese código para obtener un objeto coherente y funcional. Si se hubiera elegido un formato diferente, el proceso de deserialización habría sido distinto, pero el resultado final en el entorno de ejecución de destino habría sido el mismo.
Deserialización en Java
Desmantelador en JAXB
El proceso de deserialización de datos XML en un objeto Java ejecutable se realiza mediante la clase integrada jakarta.xml.bind.Unmarshaller(formalmente javax.xml.bind.Unmarshaller). Los métodos de deserialización definidos en la jakarta.xml.bind.Unmarshallerclase están sobrecargados para aceptar XML de diferentes tipos de entrada, como un java.io.File, java.io.FileInputStream, o java.net.URL. [ 13 ] Por ejemplo:
import java.io.File ; import jakarta.xml.bind.JAXBContext ; import jakarta.xml.bind.Unmarshaller ;JAXBContext jcon = JAXBContext.newInstance ( " com.acme.foo" ); Unmarshaller umar = jcon.createUnmarshaller ( ) ; Object obj = umar.unmarshal ( new File ( " input.xml " )) ;Deserializando datos XML
Los métodos de deserialización pueden deserializar un documento XML completo o una pequeña parte del mismo. Cuando el elemento raíz XML se declara globalmente, estos métodos utilizan la jakarta.xml.bind.JAXBContextasignación de elementos raíz XML a clases asignadas por JAXB para iniciar la deserialización. Si las asignaciones no son suficientes y los elementos raíz se declaran localmente, los métodos de deserialización utilizan declaredTypemétodos para el proceso de deserialización. Estos dos enfoques se pueden comprender a continuación. [ 13 ]
Deserializa un elemento raíz XML global.
El método `unmarshal` utiliza jakarta.xml.bind.JAXBContext(anteriormente javax.xml.bind.JAXBContext) para deserializar los datos XML cuando el elemento raíz se declara globalmente. El jakarta.xml.bind.JAXBContextobjeto siempre mantiene una asignación del elemento XML declarado globalmente y su nombre a una clase asignada por JAXB. Si el nombre del elemento XML o su @xsi:typeatributo coincide con la clase asignada por JAXB, el método `unmarshal` transforma los datos XML utilizando la clase asignada por JAXB correspondiente. Sin embargo, si el nombre del elemento XML no coincide, el proceso de deserialización se abortará y generará una excepción jakarta.xml.bind.UnmarshalException(anteriormente javax.xml.bind.UnmarshalException). Esto se puede evitar utilizando los declaredTypemétodos `unmarshal`. [ 14 ]
Deserializar un elemento raíz XML local
Cuando el elemento raíz no se declara globalmente, la aplicación ayuda al deserializador mediante una asignación proporcionada por la aplicación utilizando declaredTypeparámetros. Por orden de precedencia, incluso si el nombre raíz tiene una asignación a una clase JAXB apropiada, se declaredTypeanula dicha asignación. Sin embargo, si el @xsi:typeatributo de los datos XML tiene una asignación a una clase JAXB apropiada, esta tiene precedencia sobre el parámetro declarationType. Los métodos de deserialización por declaredTypeparámetros siempre devuelven una jakarta.xml.bind.JAXBElement<T>instancia. Las propiedades de esta jakarta.xml.bind.JAXBElement<T>instancia se establecen de la siguiente manera: [ 15 ]
Véase también
Referencias
- ↑ Jeffrey Hantin. "¿Cuál es la diferencia entre serialización y empaquetado?" . Stack Exchange Network . Consultado el 23 de julio de 2021 .
- ↑ "marshal — Serialización interna de objetos Python" . Python Software Foundation . Consultado el 4 de noviembre de 2016 .
- ↑ "marshal — Serialización interna de objetos Python" . Python Software Foundation . Consultado el 9 de octubre de 2019 .
- ↑ "Esquema para representar objetos Java en un directorio LDAP" . IETF. Octubre de 1999. Consultado el 4 de noviembre de 2016 .
- ↑ "Cómo enviar un objeto a un servidor remoto por valor usando Visual Basic .NET" . Microsoft. Julio de 2004. Archivado del original el 15 de noviembre de 2004. Consultado el 4 de noviembre de 2016 .
- ↑ "Apartamentos y modelos de subprocesos COM" . Archivado del original el 23 de septiembre de 2015. Consultado el 19 de junio de 2009 .
- ↑ "Función CoInitializeEx (COM)" . Desarrollo de aplicaciones de escritorio para Windows . Consultado el 22 de febrero de 2013 .
- ↑ Descripción general de la interoperabilidad
- ↑ Calidad del código: La perspectiva del código abierto .
- ↑ ¿Qué es un archivo DOCX? https://docs.fileformat.com/word-processing/docx/ Consultado el 13 de octubre de 2020.
- ↑ "Vinculación de esquemas XML: el tutorial de Java EE 5" . docs.oracle.com . Consultado el 14 de septiembre de 2016 .
- ↑ "Uso de la clase XmlSerializer" . msdn.microsoft.com . Consultado el 23 de septiembre de 2016 .
- 1 2 "Unmarshaller (JAXB 2.2.3)" . jaxb.java.net . Archivado del original el 5 de junio de 2012. Recuperado el 14 de septiembre de 2016 .
- ↑ "JAXBContext (JAXB 2.2.3)" . jaxb.java.net . Archivado del original el 27 de septiembre de 2016. Consultado el 23 de septiembre de 2016 .
- ↑ "JAXBElement (JAXB 2.2.3)" . jaxb.java.net . Archivado del original el 16 de febrero de 2013. Consultado el 23 de septiembre de 2016 .
- Persistencia
- Llamada a procedimiento remoto