webentwicklung-frage-antwort-db.com.de

Jackson benennt primitives boolesches Feld um, indem er 'is' entfernt

Dies kann ein Duplikat sein. Aber ich kann keine Lösung für mein Problem finden.

Ich habe ein klasse

public class MyResponse implements Serializable {

    private boolean isSuccess;

    public boolean isSuccess() {
        return isSuccess;
    }

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

Getter und Setter werden von Eclipse generiert.

In einer anderen Klasse setze ich den Wert auf true und schreibe ihn als JSON-String.

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

In JSON kommt der Schlüssel als {"success": true}.

Ich möchte den Schlüssel als isSuccess selbst. Verwendet Jackson die Setter-Methode während der Serialisierung? Wie kann man den Schlüssel selbst zum Feldnamen machen?

40
iCode

Dies ist eine etwas verspätete Antwort, kann aber für alle anderen Personen nützlich sein, die auf diese Seite kommen.

Eine einfache Lösung zum Ändern des Namens, den Jackson bei der Serialisierung zu JSON verwenden wird, ist die Verwendung der Annotation @JsonProperty , sodass Ihr Beispiel folgendermaßen aussehen würde:

public class MyResponse implements Serializable {

    private boolean isSuccess;

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

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

Dies würde dann als {"isSuccess":true} in JSON serialisiert, hat jedoch den Vorteil, dass der Name der Getter-Methode nicht geändert werden muss.

Beachten Sie, dass Sie in diesem Fall die Annotation auch als @JsonProperty("isSuccess") schreiben können, da sie nur das einzige value-Element enthält

60
Scott

Ich bin kürzlich auf dieses Thema gestoßen und habe es gefunden. Jackson wird jede Klasse, die Sie durchgehen, auf Getter und Setter überprüfen und diese Methoden für die Serialisierung und Deserialisierung verwenden. Was in diesen Methoden "get", "is" und "set" lautet, wird als Schlüssel für das JSON-Feld verwendet ("isValid" für getIsValid und setIsValid).

public class JacksonExample {   

    private boolean isValid = false;

    public boolean getIsValid() {
        return isValid;
    }

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

In ähnlicher Weise wird "isSuccess" zu "Erfolg", sofern nicht in "isIsSuccess" oder "getIsSuccess" umbenannt wird.

Lesen Sie hier mehr: http://www.citrine.io/blog/2015/5/20/jackson-json-prozessor

14
Utkarsha Padhye

Sie sollten dem Jackson Object Mapper beispielsweise Konfiguration hinzufügen:

MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.getObjectMapper().disable(MapperFeature.AUTO_DETECT_IS_GETTERS);
3
borino

Aufbauend auf der Antwort von Utkarsh ..

Getter-Namen minus get/is wird als JSON-Name verwendet.

public class Example{
    private String radcliffe; 

    public getHarryPotter(){
        return radcliffe; 
    }
}

wird gespeichert als {"harryPotter": "whateverYouGaveHere"}  


Bei der Deserialisierung prüft Jackson sowohl den Setter als auch den Feldnamen . Für den Json-String {"Word1": "example"} sind beide der folgenden Werte gültig.

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 ; 
    }
}

Eine interessantere Frage ist, welche Reihenfolge Jackson für die Deserialisierung in Betracht zieht. Wenn ich versuche, {"Word1": "myName"} mit zu deserialisieren

public class Example3{
    private String Word1;
    private String Word2; 

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

Ich habe den obigen Fall nicht getestet, aber es wäre interessant, die Werte von Word1 & Word2 zu sehen.

Hinweis: Ich habe drastisch unterschiedliche Namen verwendet, um hervorzuheben, welche Felder gleich sein müssen.

1
Abhinav Vishak

Sie können Ihre ObjectMapper wie folgt konfigurieren:

mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
            @Override
            public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
            {
                if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
                        && method.getName().startsWith("is")) {
                    return method.getName();
                }
                return super.nameForGetterMethod(config, method, defaultName);
            }
        });
1
burak emre

es gibt eine andere Methode für dieses Problem.

definieren Sie einfach eine neue Unterklasse, die PropertyNamingStrategy erweitert, und übergeben Sie sie an die ObjectMapper-Instanz.

hier ist ein Code-Snippet, der mehr helfen kann:

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;
        }
    });
1
eric

Wenn Sie die beiden folgenden Anmerkungen verwenden, wird die Ausgabe-JSON gezwungen, is_xxx einzuschließen:

@get:JsonProperty("is_something")
@param:JsonProperty("is_something")
0
Fabio