EN · DE · RU · FR · ES

#754: XmlField.java

projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlField.java Anotación Java — anotación central a nivel de campo del framework XmlStream. 92 líneas. @Target(FIELD), @Retention(RUNTIME). Fuente: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlField.java 92 líneas · 17 código · 63 comentarios · 12 en blanco
Propósito: La anotación central del framework XmlStream — equivalente a @XmlElement, @XmlAttribute de JAXB, @XStreamAlias y @XStreamAsAttribute de XStream, todo combinado en una sola anotación. Marca un campo Java como serializable a XML y controla exactamente cómo se escribe. Se aplica a nivel de campo (@Target(FIELD)) y está disponible en tiempo de ejecución mediante reflexión (@Retention(RUNTIME)) — así es como XmlObjectWriter y XmlObjectReader descubren los campos serializables.

8 Atributos de la anotación

alias() — Nombre del elemento/atributo XML

Anula el nombre del campo durante la serialización. Sin alias: private String firstName → etiqueta <firstName>. Con alias: @XmlField(alias="first-name") → etiqueta <first-name>. Útil cuando el formato XML debe ajustarse a un esquema externo o cuando un nombre de campo Java entra en conflicto con una palabra reservada de XML.

asAttribute() y asElement() — Atributo vs. elemento

Controla si el valor se serializa como un atributo XML (compacto) o como un elemento (estructurado):

<!-- Como atributo: -->
<user id="42" name="John"/>

<!-- Como elemento: -->
<user><id>42</id><name>John</name></user>

Matiz crítico del Javadoc: "asAttribute=false no tiene efecto (use asElement=true en su lugar)" y viceversa. Esto significa que false no es una negación — es "dejar por defecto", que puede ser anulado por configuraciones globales en XmlObjectWriter.asAttributeAsDefault(). Para garantizar la serialización como atributo, use asAttribute=true. Para garantizar elemento, use asElement=true.

defaultDoubleValue / defaultIntValue / defaultStringValue / defaultBooleanValue — Compresión XML

Si el valor del campo es igual al valor predeterminado declarado, NO se serializa a XML. Este es un mecanismo de compresión: los valores predeterminados típicos no ocupan espacio en la salida. Durante la deserialización, las etiquetas ausentes reciben el valor predeterminado. Los números mágicos de XmlConstants (#751) sirven como el centinela "no establecido" para los valores predeterminados int y string. Para boolean, el valor predeterminado es false (el valor más común). Para double, el valor predeterminado es NaN ("no establecido").

asCDATA() — Protección de caracteres especiales

Si es true, el valor de cadena se envuelve en un bloque XML <![CDATA[...]]>. Necesario para campos que pueden contener caracteres <, >, & — por ejemplo, HTML en campos de descripción o SQL en registros. Sin CDATA, estos caracteres necesitarían escaparse como &lt;, &gt;, &amp;, haciendo que el XML sea ilegible.

Consumo en tiempo de ejecución

  1. XmlObjectWriter itera todos los campos de un objeto mediante reflexión durante la serialización
  2. Para cada campo, verifica la presencia de @XmlField (y la ausencia de @XmlOmitField)
  3. Si está presente, lee los parámetros: alias (nombre de etiqueta), asAttribute (formato), default* (lógica de omisión), asCDATA (formato)
  4. Llama al Converter apropiado para transformar el valor del campo a una cadena
  5. XmlObjectReader hace lo inverso: lee la etiqueta/atributo del XML, encuentra el campo correspondiente por nombre o alias, llama al Converter para la transformación inversa

Comparación con XStream y JAXB

CapacidadXmlFieldXStreamJAXB
Alias de campoalias="nombre"@XStreamAlias("nombre")@XmlElement(name="nombre")
Atributo vs elementoasAttribute=true@XStreamAsAttribute@XmlAttribute
Exclusión de campo@XmlOmitField@XStreamOmitField@XmlTransient
Valor predeterminadodefaultIntValue=0❌ ninguno❌ ninguno
CDATAasCDATA=true❌ ninguno❌ ninguno
Versionado de formato✅ vía XmlObject❌ ninguno❌ ninguno
XmlField + XmlStream proporcionan más control sobre el formato XML que XStream, pero requieren anotación manual. XStream "simplemente funciona" sin anotaciones pero genera XML menos controlado. La elección de XmlStream para la exportación de datos fue impulsada específicamente por la necesidad de control de formato y versionado.

Historial de Git

868d6abb7 2025 → 2026 (actualización de año de copyright)
63081666f Encabezados de archivos fuente: 2024→2025
b6092df09 Copyright 2023 → 2024
ab45d51fa Copyright 2001-2022 → 2001-2023
5f7ef41b8 Copyright 2021 → 2022
cd27dd997 paquete xstream → xmlstream (renombrado para evitar confusión con la librería XStream)
ceb63e8a1 Encabezado de código fuente: (C) 2001-2021
7c79f1922 Copyright del encabezado fuente → 2020
32f634b88 Optimizar importaciones
dd5ca38ac Copyright de todos los encabezados de archivos java actualizado o creado
9ebb88522 Commit inicial
Los atributos de la anotación se han mantenido estables desde el commit inicial. Solo los encabezados de copyright, la optimización de importaciones (32f634b88) y el cambio de nombre del paquete afectaron a este archivo. El atributo implementationClass() comentado sugiere que el autor consideró el mapeo de interfaz a implementación a nivel de campo, pero optó por manejarlo en XmlObjectReader.addImplementationMapping() en su lugar.