2015-05-13 6 views
13

Używam Wiosna 4 MVC z Jackson 2 dla mojej służby. Na jednej z operacji Mam obiektu żądania, który posiada atrybut gdzie wiodącym przypadek wielbłąd słowo to tylko jedna litera długości:Dlaczego Jackson 2 nie rozpoznaje pierwszą literę, jeśli prowadzący przypadek wielbłąd słowo jest tylko jeden list długo?

private String aLogId; 

Ta klasa ma odpowiednio nazwany pobierające i ustawiające:

public String getALogId() { return aLogId; } 
public void setALogId(String aLogId) { this.aLogId = aLogId; } 

jednak gdy próbuję napisać prośbę do tej usługi za pomocą odpowiedniej właściwości JSON:

{"aLogId":"This is a log id"} 

ja dostaję 500 odpowiedź ramach wiosennego mówiąc pole nie jest rozpoznawana i moja klasa kontroler nie nazywa się:

Nie można odczytać JSON: pole Nierozpoznany „aLogId” (klasa

Jednak, kiedy zmienić „L” na małe litery, wniosek jest rozszeregować jak oczekiwano, a moja klasa kontrolera jest trafiony:

{"alogId":"This is a log id"} 

Dlaczego Jackson oczekiwać „L”, aby być niższa przypadku, gdy jest to oczywiście drugie słowo w konwencji case wielbłąd atrybutu i przeznaczone do być wielkimi literami? Czy to dlatego, że pierwsze słowo ma tylko jedną literę?

Istnieją inne atrybuty w obiekcie żądania gdzie pierwsze słowo jest więcej niż jedna litera a te przypisywane nie spotykają ten sam problem z niedopasowaniem w sprawie.

+0

który byłby interesującym błędem. a co z jednoliterowym wyrazem w środku, jak "logAId" - czy też zawodzi? – ZhongYu

+2

Ten problem znika, jeśli zmienisz nazwę gettera i setera na 'setaLogId' i' getaLogId'. To jednak leci w obliczu konwencji. Zdecydowanie jest coś "zapluskwionego", gdy masz słowa jednoliterowe. – Leon

Odpowiedz

20

Problem widzisz to ze względu na fakt, że Jackson używa Java Bean konwencje nazewnictwa, aby zrozumieć to właściwości JSON w klasie Java.

Oto reference konkretnego problemu, który widzisz, zalecenie nie oznacza żadnej z pierwszych dwóch liter w polu. Jeśli używasz IDE jak IntelliJ lub Eclipse i niech IDE wygenerować ustawiające dla Ciebie, można zauważyć takie samo „zachowanie” występuje, można skończyć z następujących metod:

public void setaLogId(String aLogId) { 
    this.aLogId = aLogId; 
} 

public String getaLogId() { 
    return aLogId; 
} 

Stąd po zmianie "L" na małe litery Jackson był w stanie rozgryźć to pole, które chciałeś zmapować.

Powiedziawszy powyżej, nadal masz alternatywę do używania nazwy pola "aLogId" i sprawisz, że Jackson będzie pracował, wszystko co musisz zrobić, to użyć adnotacji @JsonProperty z aLogId.

@JsonProperty("aLogId") 
private String aLogId; 

Poniższy kod test ma pokazać, jak to będzie działać:

import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class Test { 

    @JsonProperty("aLogId") 
    private String aLogId; 

    public void setaLogId(String aLogId) { 
     this.aLogId = aLogId; 
    } 

    public String getaLogId() { 
     return aLogId; 
    } 

    public static void main(String[] args) { 

     ObjectMapper objectMapper = new ObjectMapper(); 

     Test test = new Test(); 

     test.setaLogId("anId"); 

     try { 
      System.out.println("Serialization test: " + objectMapper.writeValueAsString(test)); 


      String json = "{\"aLogId\":\"anotherId\"}"; 

      Test anotherTest = objectMapper.readValue(json, Test.class); 

      System.out.println("Deserialization test: " +anotherTest.getaLogId()); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 

Wyjście z testu jest:

Serialization test: {"aLogId":"anId"}

Deserialization test: anotherId

+1

To pomaga. Co ciekawe, w specyfikacji 8-11 Java Bean wspominają, że jeśli dwie pierwsze litery są wielkimi literami, pozostawiają je w spokoju, więc wydaje się, że Jackson powinien wybrać to jako ALOGId zamiast alogid. Więc Jackson odchodzi od specyfikacji Java Bean? Tak czy inaczej, jest to świetna odpowiedź i wskazał mi właściwy kierunek. Dziękuję i akceptuję. – Hazok

+0

Używam Jackson 2.8.8 i mam ten sam problem. Ale gdy próbuję swoje rozwiązanie (anotating z @JsonProperty ("aLogId") w "aLogId" field), otrzymuję dwa pola JSON: { \t "aLogId": "Anid", \t "alogId": "Anid" } Tak więc pole jest duplikowane, co nie jest poprawne! Ktoś w tej samej sytuacji? – Alberthoven

+0

Niesamowite rozwiązanie. Wielkie dzięki – Murwa

0

Moje rozumienie jest że Jackson domyślnie używa swojego własnego konwencji nazewnictwa n, który jest bardzo blisko, ale nie do końca taki sam, do konwencji nazewnictwa Java Bean. Opcja MapperFeature, MapperFeature.USE_STD_BEAN_NAMING, została dodana w Jackson 2.5.0, aby powiedzieć Jacksonowi, aby używał konwencji nazewnictwa Java Bean - patrz Jackson Issue 653. W celu zapewnienia kompatybilności wstecz domyślną wartością parametru MapperFeature.USE_STD_BEAN_NAMING jest fałsz.

1

To zadziałało dla mnie; @JsonProperty adnotacja na temat pobierających!

import com.fasterxml.jackson.annotation.JsonProperty; 

public class PaytmRequestJson { 
    private String ORDERID; 
    private String MID; 
    private String CHECKSUMHASH; 

    @JsonProperty("ORDERID") 
    public String getORDERID() { 
     return ORDERID; 
    } 

    public void setORDERID(String ORDERID) { 
     this.ORDERID = ORDERID; 
    } 

    @JsonProperty("MID") 
    public String getMID() { 
     return MID; 
    } 

    public void setMID(String MID) { 
     this.MID = MID; 
    } 

    @JsonProperty("CHECKSUMHASH") 
    public String getCHECKSUMHASH() { 
     return CHECKSUMHASH; 
    } 

    public void setCHECKSUMHASH(String CHECKSUMHASH) { 
     this.CHECKSUMHASH = CHECKSUMHASH; 
    } 
} 
Powiązane problemy