2011-03-21 7 views

Respuesta

15

Inicialice XStream como se muestra a continuación para ignorar los campos que no están definidos en su bean.

XStream xstream = new XStream() { 
    @Override 
    protected MapperWrapper wrapMapper(MapperWrapper next) { 
     return new MapperWrapper(next) { 
      @Override 
      public boolean shouldSerializeMember(Class definedIn, String fieldName) { 
       if (definedIn == Object.class) { 
        return false; 
       } 
       return super.shouldSerializeMember(definedIn, fieldName); 
      } 
     }; 
    } 
}; 
+2

Esto no funciona para mí cuando utilizo la anotación @XStreamImplicit en colecciones. ¿Algunas ideas? –

+0

Use @ com.thoughtworks.xstream.annotations.XStreamOmitField – timomeinen

+0

XStreamOmitField no funcionó para mí. Ni el transitorio como se sugiere en los documentos de XStream. – endless

5

He estado trabajando mi camino en torno a este problema hoy en día y lo que he descubierto es que usando return this.realClass(fieldName) != null; no es (siempre) una solución de trabajo sin embargo en realidad hay un camino para xstream para saltar sin asignar etiquetas Y trabajo con colecciones implícitas al mismo tiempo.

Por qué realClass(fieldName) cosa no va a funcionar

De hecho truco con el uso de

try { 
    return this.realClass(fieldName) != null; 
} catch (Throwable t) { 
    return false; 
} 

obras. Lo que hace es intentar adivinar el tipo por el nombre de la etiqueta, ver si tiene éxito y si no, devuelve falso. Así que va a saltar a la perfección etiquetas como

<someUnknownTag>someContent</someUnknownTag> 

pero funcionará sólo hasta el momento (!) cuando alguna manera alguna "no necesita" etiqueta pasará a tener un nombre significativo para los que realClass(fieldName) será realidad puede devolver algo que no sea igual a null y esa etiqueta no será miembro de ninguna colección implícita suya. En ese caso, sabiendo que la clase para un elemento xml podría definirse y que no existe ese campo mapeado en los usuarios, el tipo XStream decidirá que "tal vez este elemento sea de una colección implícita". Y fallará muy pronto si no hay tal colección ni un campo en su clase. En mi caso la pieza problemática de XML fue así:

<url>http://somewhere.com</url> 

y, por supuesto, no había ni Url url; ni @XStreamImplicit List<Url> url en mi clase. El resultado de tener un XML tal y usar "realClass" cosa es la siguiente:

com.thoughtworks.xstream.converters.ConversionException: Element url of type java.net.URL is not defined as field in type org.sample.xstream.SomeBean 

la manera correcta

La forma correcta sería volver llanura false de shouldSerializeMember en caso de que definedIn == Object.class (sin utilizar realClass(fieldName) cosas).

Pero solo usar return false solo no es suficiente. En esta forma, hará que XStream deje colecciones implícitas vacías.

El truco aquí es asegurarse de que uno usa @XStreamImplicit(itemFieldName = "something") en lugar de usar @XStreamImplicit sin parámetros, incluso en los casos en que el nombre de la etiqueta y el tipo de parámetro genérico de la colección tienen el mismo nombre.

Así que el código correcto se verá así:

xstream = new XStream() { 
     @Override 
     protected MapperWrapper wrapMapper(MapperWrapper next) { 
      return new MapperWrapper(next) { 
       @Override 
       public boolean shouldSerializeMember(Class definedIn, String fieldName) { 
        if (definedIn == Object.class) { 
         //This is not compatible with implicit collections where item name is not defined 
         return false; 
        } else { 
         return super.shouldSerializeMember(definedIn, fieldName); 
        } 
       } 
      }; 
     } 
    }; 
    xsteam.processAnnotations(SomeRootEntry.class); 

y hay que estar seguros de que en sus clases de sus colecciones implícitos están marcados como esto:

@XStreamImplicit(itemFieldName = "something") 
private List <Something> somethingList; 

en cuenta que itemFieldName es explícitamente especificado aunque el parámetro de tipo genérico de List tiene el mismo nombre. Esto es crucial.

En este caso al encontrar <something>, la etiqueta XStream ni siquiera visitará su shouldSerializeMember con ese fieldName. Simplemente sabrá de antemano que el elemento proviene de colecciones implícitas.

Cuando va visite su método al encontrar <url>http://somewhere.com</url> nuevamente. Pero aquí estamos seguros ya que acabamos de devolver false.

¡Trabaja para mí! Darle una oportunidad.

11

XStream 1.4.5 hace que sea fácil tratar con etiquetas desconocidas. Use ignoreUnknownElements() para las etiquetas que aún no se han implementado o que se han eliminado y está tratando con xml anterior. También puede especificar qué etiqueta particular le gustaría ignorar.


8

Desde xstream 1.4.5 durring declaración marshaller Es suficiente para utilizar ignoreEnknownElements() Método:

XStreamMarshaller marshaller = new XStreamMarshaller(); 
marshaller.getXStream().ignoreUnknownElements(); 
... 

para ignorar los elementos innecesarios.

Cuestiones relacionadas