2012-02-28 20 views
13

tengo una respuesta JSON que se parece a lo siguiente:JAXB java.util.Map vinculante

{ 
    "data": [ 
     { 
      "param1": "value1", 
      "param2": "value2", 
        . 
        . 
        . 
      "paramN": "valueN" 
     } 
    ] 
} 

no sé el nombre y el número de los parámetros. Por lo tanto, necesito y quiero vincular todos estos parámetros a un campo java.util.Map que consiste en < "paramX", "valueX"> tuplas. Para hacer esto, probé el siguiente código pero el campo "parametersMap" devuelve null.

@XmlRootElement(name="data") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Parameters { 
    @XmlElement 
    private Map<String,String> parametersMap; 

    // Getter and setter for parametersMap 
} 

¿Cómo puedo lograr un enlace de este tipo con las anotaciones de JAXB?

Gracias de antemano.

+0

De una publicación diferente Acabo de enterarme de que * jersey * (re) usa * JAXB * anotaciones. http://stackoverflow.com/questions/1261593/binding-a-json-to-a-java-class-using-jaxb –

+1

Sí, JAXB es para enlace XML pero también se puede usar para vincular entradas JSON a objetos Java junto con Jersey. – ovunccetin

+0

EclipseLink JAXB (MOXy) también ofrece JSON vinculante aprovechando las anotaciones JAXB: http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html –

Respuesta

7

Básicamente necesita un adaptador xml. Puedes jugar con los nombres en la clase KeyValue para obtener el resultado específico que deseas.

Parameter.java

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
import java.util.Map; 

@XmlRootElement(name = "data") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Parameters { 

    @XmlJavaTypeAdapter(value = Adapter.class) 
    private Map<String, String> parametersMap; 

    // Getter and setter for parametersMap 
} 

Adapter.java

import javax.xml.bind.annotation.adapters.XmlAdapter; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 

public class Adapter extends XmlAdapter<List<KeyValue>, Map<String, String>> { 

    @Override 
    public Map<String, String> unmarshal(List<KeyValue> v) throws Exception { 
     Map<String, String> map = new HashMap<>(v.size()); 
     for (KeyValue keyValue : v) { 
      map.put(keyValue.key, keyValue.value); 
     } 
     return map; 
    } 

    @Override 
    public List<KeyValue> marshal(Map<String, String> v) throws Exception { 
     Set<String> keys = v.keySet(); 
     List<KeyValue> results = new ArrayList<>(v.size()); 
     for (String key : keys) { 
      results.add(new KeyValue(key, v.get(key))); 
     } 
     return results; 
    } 
} 

KeyValue.java mejor poner etiquetas JAXB aquí, obviamente.

import javax.xml.bind.annotation.XmlType; 

@XmlType 
public class KeyValue { 
    public KeyValue() { 
    } 

    public KeyValue(String key, String value) { 
     this.key = key; 
     this.value = value; 
    } 

    //obviously needs setters/getters 
    String key; 
    String value; 
} 
+0

Obtengo 'com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 conteos de IllegalAnnotationExceptions' para' Parameters.java' en la línea donde se declara el 'Map'. – koppor

+1

La respuesta https://www.tomasmalmsten.com/2012/05/unmarshall-marshall-java-maps-xml-jaxb/ ajusta 'List ' en otra clase de ayuda. Esto evita que 'IllegalAnnotationsException'. – koppor