Dies könnte 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-Zeichenfolge.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
In JSON kommt der Schlüssel als {"success": true}
.
Ich möchte den Schlüssel als sich isSuccess
selbst. Verwendet Jackson während der Serialisierung die Setter-Methode? Wie mache ich den Schlüssel zum Feldnamen selbst?
isSuccess
ist, muss Ihr MethodennameisIsSuccess
ich denkeSetSuccess
da es von Eclipse generiert wird. (Nach einem Standard)Antworten:
Dies ist eine etwas späte Antwort, kann aber für alle anderen nützlich sein, die auf diese Seite kommen.
Eine einfache Lösung zum Ändern des Namens, für den Jackson bei der Serialisierung in JSON verwendet wird, ist die Verwendung der Annotation @JsonProperty. Ihr Beispiel lautet also:
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 in JSON als serialisiert
{"isSuccess":true}
, hat jedoch den Vorteil, dass Sie den Namen Ihrer Getter-Methode nicht ändern müssen.Beachten Sie, dass Sie in diesem Fall auch die Anmerkung schreiben können,
@JsonProperty("isSuccess")
da sie nur das einzelnevalue
Element enthältquelle
Ich bin kürzlich auf dieses Problem gestoßen und habe es gefunden. Jackson überprüft jede Klasse, die Sie an sie übergeben, auf Getter und Setter und verwendet diese Methoden für die Serialisierung und Deserialisierung. Was in diesen Methoden auf "get", "is" und "set" folgt, 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-processor
quelle
Wenn Sie beide unten stehenden Anmerkungen verwenden, wird der Ausgabe-JSON gezwungen, Folgendes einzuschließen
is_xxx
:@get:JsonProperty("is_something") @param:JsonProperty("is_something")
quelle
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); } });
quelle
Wenn Sie Kotlin und Datenklassen verwenden:
data class Dto( @get:JsonProperty("isSuccess") val isSuccess: Boolean )
Möglicherweise müssen Sie hinzufügen,
@param:JsonProperty("isSuccess")
wenn Sie JSON ebenfalls deserialisieren möchten.quelle
Aufbauend auf Utkarshs Antwort.
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"} gelten beide folgenden Punkte .
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 Wort1 und Wort2 zu sehen ...
Hinweis: Ich habe drastisch unterschiedliche Namen verwendet, um hervorzuheben, welche Felder identisch sein müssen.
quelle
Es gibt eine andere Methode für dieses Problem.
Definieren Sie einfach eine neue Unterklasse, erweitern Sie PropertyNamingStrategy und übergeben Sie sie an die ObjectMapper-Instanz.
Hier ist ein Code-Snippet kann mehr helfen:
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; } });
quelle
Ich wollte mich nicht mit benutzerdefinierten Benennungsstrategien herumschlagen oder einige Accessoren neu erstellen.
Je weniger Code, desto glücklicher bin ich.
Das hat uns geholfen:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates public class MyResponse { private String id; private @JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name private @JsonProperty("isDeleted") boolean isDeleted; }
quelle
Die akzeptierte Antwort funktioniert in meinem Fall nicht.
In meinem Fall gehört die Klasse nicht mir. Die problematische Klasse stammt aus Abhängigkeiten von Drittanbietern, daher kann ich nicht einfach
@JsonProperty
Anmerkungen hinzufügen .Um das Problem zu lösen, habe ich, inspiriert von der obigen Antwort von @burak, einen benutzerdefinierten Code
PropertyNamingStrategy
wie folgt erstellt:mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() { @Override public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if (method.getParameterCount() == 1 && (method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) && method.getName().startsWith("set")) { Class<?> containingClass = method.getDeclaringClass(); String potentialFieldName = "is" + method.getName().substring(3); try { containingClass.getDeclaredField(potentialFieldName); return potentialFieldName; } catch (NoSuchFieldException e) { // do nothing and fall through } } return super.nameForSetterMethod(config, method, defaultName); } @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")) { Class<?> containingClass = method.getDeclaringClass(); String potentialFieldName = method.getName(); try { containingClass.getDeclaredField(potentialFieldName); return potentialFieldName; } catch (NoSuchFieldException e) { // do nothing and fall through } } return super.nameForGetterMethod(config, method, defaultName); } });
Grundsätzlich wird vor dem Serialisieren und Deserialisieren in der Ziel- / Quellklasse überprüft, welcher Eigenschaftsname in der Klasse vorhanden ist, ob es sich um einen handelt
isEnabled
oder nichtenabled
Eigenschaft .Basierend darauf serialisiert und deserialisiert der Mapper den vorhandenen Eigenschaftsnamen.
quelle
Sie können den primitiven Booleschen Wert in java.lang.Boolean ändern (+ verwenden
@JsonPropery
)@JsonProperty("isA") private Boolean isA = false; public Boolean getA() { return this.isA; } public void setA(Boolean a) { this.isA = a; }
Hat hervorragend für mich funktioniert.
quelle