2013-06-04 7 views
5

mi hanno sotto JSON:Jackson parser JSON setter di prendere valore come array di stringhe

"[{\"movieName\":\"A\",\"Leadactor\":\"\",\"leadActress\":\"\",\"movieTitle\":\"\",\"hero\":\"\",\"heroine\":\"\",\"source\":\"IMDB\"}," + 
    "{\"movieName\":\"\",\"Leadactor\":\"\",\"leadActress\":\"\",\"movieTitle\":\"B\",\"hero\":\"B1\",\"heroine\":\"B2\",\"source\":\"Netflix\"}," + 
    "{\"movieName\":\"C\",\"Leadactor\":\"C1\",\"leadActress\":\"C2\",\"movieTitle\":\"\",\"hero\":\"\",\"heroine\":\"\",\"source\":\"IMDB\"}," + 
    "{\"movieName\":\"D\",\"Leadactor\":\"D1\",\"leadActress\":\"D2\",\"movieTitle\":\"\",\"hero\":\"\",\"heroine\":\"\",\"source\":\"IMDB\"}," + 
    "{\"movieName\":\"\",\"Leadactor\":\"\",\"leadActress\":\"\",\"movieTitle\":\"E\",\"hero\":\"E1\",\"heroine\":\"E2\",\"source\":\"Netflix\"}]"; 

Sto usando Jackson parser per mappare a una classe:

voglio nomedelfilm e MovieTitle per mappare in Nome proprietà nella classe java. Così ho scritto la classe di seguito:

public static class MovieData { 
    @JsonProperty("Name") 
    private String name; 

    @JsonSetter({"movieName"}) 
    private void setMovieName(final String name) { 
      if((name != null) && (! name.equals(""))) { 
        setNameInternal(name); 
      } 
    } 

    @JsonSetter("movieTitle") 
    private void setMovieTitle(final String name) { 
      if((name != null) && (! name.equals(""))) { 
        setNameInternal(name); 
      } 
    } 

    private void setNameInternal(final String name) { 
      this.name = name; 
    } 

}

Nella mia vera JSON ci sono tanti campi come nomedelfilm, MovieTitle cui voglio per normalizzare in un nome comune.

C'è qualche sintassi semplice come il sottostante che può ridurre la duplicazione del codice:

public static class MovieData { 
    @JsonProperty("Name") 
    private String name; 

@JsonSetter(value = { "movieName", "movieTitle" }) 
private void setName(final String name) { 
     if((name != null) && (! name.equals(""))) { 
       this.name=name; 
     } 
} 
    } 

Il codice di cui sopra mi ha dato errore jsonSetter:

Type mismatch: cannot convert from String[] to String. 

EDIT

Se Jackson non lo supporta, può GSON supportare questa operazione.

Grazie

+1

La tua domanda non è molto chiara ... vuoi una lista di oggetti 'Film' con un attributo' nome', che contiene il valore di '" movieName "' o '" movieTitle "'? E se, diciamo, "movieName" 'ha un valore,' "movieTitle" 'sarà sempre emtpty? – MikO

+1

Hai provato ad aggiungere più annotazioni a setName, uno per movieName e uno per movieTitle?Altrimenti funzionerà la soluzione seguente con @JsonAnySetter. – Sumit

+0

@MikO si voglio un elenco di oggetti Movie con un nome di attributo, che contiene il valore del nome del film o del titolo del film. Sì, se il nome del film ha un titolo, il titolo del film è vuoto. – javaMan

risposta

5

È possibile utilizzare @JsonAnySetter, quello che è significa che si può trovare sulla Jackson Core (Data-Binding) Annotations pagina.

ho creato semplice chicco che è legato al tuo esempio:

class MovieData { 

    private static List<String> NAME_PROPERTIES = Arrays.asList("movieName", "movieTitle"); 

    private String name; 

    public void setName(String name) { 
     this.name = name; 
    } 

    @JsonAnySetter 
    private void parseUnknownProperties(String propertyName, String propertyValue) { 
     if (NAME_PROPERTIES.contains(propertyName) && !propertyValue.isEmpty()) { 
      this.name = propertyValue; 
     } 
    } 

    @Override 
    public String toString() { 
     return name; 
    } 
} 

Ora, quando ho deserializzare tuo JSON in questo modo:

ObjectMapper objectMapper = new ObjectMapper(); 
System.out.println(Arrays.toString(objectMapper.readValue(json, MovieData[].class))); 

Come risultato posso vedere:

[A, B, C, D, E] 
3

Non fare così tanto. è molto semplice, con GSON

creare classe per il record di singolo insieme come

class Movie{ 
    private String movieName; 
    private String Leadactor; 
    private String leadActress; 

    //put getter and setter for your fields 
} 

in main file 
Type type = new TypeToken<List<Movie>>(){}.getType(); 
List<Movie> data = new Gson().fromJson(json_string,type); 
+0

So di gson. il problema riguarda la normalizzazione. Voglio anche movieTitle mappare in movieName; – javaMan

+0

Si prega di astenersi dal chiedere alle persone di votare/accettare le risposte. [Vedi questo meta post per maggiori informazioni] (http://meta.stackexchange.com/q/167155/152134). Grazie! –

0

Si dichiara il campo come @JsonProperty String[] data

e utilizzare

new ObjectMapper() 
     .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) 
     .readValue(json, YOUT_TYPE.class) 

Quindi questa opzione fanno parte di Jackson sia "foo": "bar" e "foo": [ "a", "b", "c"].

Tutto ciò che devi fare è unire nuovamente l'array di stringhe nella stringa con separatori di riga a destra. Lo faccio via Guava data == null ? null : Jointer.on("\n").join(data)

+0

Qual è la variabile "json" che si passa a readValue()? – Charlires

Problemi correlati