2015-08-28 10 views
23

Questo potrebbe essere duplicato. Ma non trovo una soluzione.Jackson rinomina il campo booleano primitivo rimuovendo 'is'

Ho una classe

public class MyResponse implements Serializable { 

    private boolean isSuccess; 

    public boolean isSuccess() { 
     return isSuccess; 
    } 

    public void setSuccess(boolean isSuccess) { 
     this.isSuccess = isSuccess; 
    } 
} 

getter e setter sono generati da Eclipse.

In un'altra classe, imposto il valore su true e lo scrivo come stringa JSON.

System.out.println(new ObjectMapper().writeValueAsString(myResponse)); 

In JSON, la chiave è in arrivo come {"success": true}.

Voglio la chiave come isSuccess stesso. Jackson usa il metodo setter durante la serializzazione? Come rendere la chiave come il nome del campo stesso?

+0

se il tuo nome proprietà è liek 'metodo isSuccess'you il nome deve essere 'isIsSuccess' penso – Jens

+0

Capisco. Ho pensato che fosse meglio "SetSuccess" dato che è stato generato da Eclipse. (Seguendo uno standard) – iCode

risposta

28

Questa è una risposta un po 'in ritardo, ma può essere utile per chiunque altro venga a questa pagina.

Una soluzione semplice per cambiare il nome che Jackson utilizzerà per quando la serializzazione a JSON è quello di utilizzare il @JsonProperty annotazione, così il vostro esempio potrebbe diventare:

public class MyResponse implements Serializable { 

    private boolean isSuccess; 

    @JsonProperty(value="isSuccess")   
    public boolean isSuccess() { 
     return isSuccess; 
    } 

    public void setSuccess(boolean isSuccess) { 
     this.isSuccess = isSuccess; 
    } 
} 

Questo sarebbe poi essere serializzato a JSON come {"isSuccess":true}, ma ha il vantaggio di non dover modificare il nome del metodo getter.

Si noti che in questo caso si potrebbe anche scrivere l'annotazione come @JsonProperty("isSuccess") come ha solo il singolo value elemento

9

Recentemente mi sono imbattuto in questo problema e questo è quello che ho trovato. Jackson ispezionerà qualsiasi classe che tu gli passi per getter e setter e userà questi metodi per la serializzazione e la deserializzazione. Quello che segue "get", "is" e "set" in quei metodi verrà utilizzato come chiave per il campo JSON ("isValid" per getIsValid e setIsValid).

public class JacksonExample { 

    private boolean isValid = false; 

    public boolean getIsValid() { 
     return isValid; 
    } 

    public void setIsValid(boolean isValid) { 
     this.isValid = isValid; 
    } 
} 

Allo stesso modo "isSuccess" diventerà "successo", a meno che non rinominato in "isIsSuccess" o "getIsSuccess"

Read more here: http://www.citrine.io/blog/2015/5/20/jackson-json-processor

+3

isValid non è la convenzione di denominazione corretta per il tipo di dati booleani in java. dovrebbe essere valido e isValid(), setValid() – vels4j

+0

ma non dovrebbe essere esattamente questo? Una convenzione? Se esiste, potresti collegarti al riferimento di Jackson che dice che usa i nomi getter come campi JSON? O pensi che sia una cattiva scelta di design? –

+0

Vorrei che ci fosse un avvertimento per questo – RyPope

1

Basandosi sulle risposta di Utkarsh ..

nomi Getter meno ottengono/è viene usato come il nome JSON.

public class Example{ 
    private String radcliffe; 

    public getHarryPotter(){ 
     return radcliffe; 
    } 
} 

è memorizzato come { "HarryPotter": "whateverYouGaveHere"}


Per deserializzazione, Jackson controlli sia contro il setter e il nome del campo. Per la stringa JSON {"word1": "example"}, entrambi i seguenti sono validi.

public class Example{ 
    private String word1; 

    public setword2(String pqr){ 
     this.word1 = pqr; 
    } 
} 

public class Example2{ 
    private String word2; 

    public setWord1(String pqr){ 
     this.word2 = pqr ; 
    } 
} 

Una domanda più interessante è che ordinare Jackson considera per la deserializzazione.Se provo a deserializzare { "parola1": "myName"} con

public class Example3{ 
    private String word1; 
    private String word2; 

    public setWord1(String parameter){ 
     this.word2 = parameter ; 
    } 
} 

non ho la prova il caso di cui sopra, ma sarebbe interessante vedere i valori di parola1 & parola2. ..

Nota: ho usato nomi drasticamente diversi per enfatizzare quali campi devono essere uguali.

1

c'è un altro metodo per questo problema.

solo definire una nuova sottoclasse estende PropertyNamingStrategy e passarlo all'istanza di ObjectMapper.

: ecco un frammento di codice può essere d'aiuto più:

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() { 
     @Override 
     public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { 
      String input = defaultName; 
      if(method.getName().startsWith("is")){ 
       input = method.getName(); 
      } 

      //copy from LowerCaseWithUnderscoresStrategy 
      if (input == null) return input; // garbage in, garbage out 
      int length = input.length(); 
      StringBuilder result = new StringBuilder(length * 2); 
      int resultLength = 0; 
      boolean wasPrevTranslated = false; 
      for (int i = 0; i < length; i++) 
      { 
       char c = input.charAt(i); 
       if (i > 0 || c != '_') // skip first starting underscore 
       { 
        if (Character.isUpperCase(c)) 
        { 
         if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_') 
         { 
          result.append('_'); 
          resultLength++; 
         } 
         c = Character.toLowerCase(c); 
         wasPrevTranslated = true; 
        } 
        else 
        { 
         wasPrevTranslated = false; 
        } 
        result.append(c); 
        resultLength++; 
       } 
      } 
      return resultLength > 0 ? result.toString() : input; 
     } 
    }); 
0

Si dovrebbe aggiungere configurazione per l'oggetto mapper Jakson per esempio:

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 
converter.getObjectMapper().disable(MapperFeature.AUTO_DETECT_IS_GETTERS); 
Problemi correlati