Cela pourrait être un double. Mais je ne trouve pas de solution à mon problème.
j'ai un cours
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Les getters et setters sont générés par Eclipse.
Dans une autre classe, j'ai défini la valeur sur true et je l'écris sous forme de chaîne JSON.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
Dans JSON, la clé arrive en tant que {"success": true}
.
Je veux la clé comme isSuccess
elle-même. Jackson utilise-t-il la méthode setter lors de la sérialisation? Comment faire de la clé le nom du champ lui-même?
isSuccess
, le nom de votre méthode doit êtreisIsSuccess
je penseSetSuccess
car il est généré par Eclipse. (Suivant une norme)Réponses:
C'est une réponse un peu tardive, mais peut être utile pour quiconque accède à cette page.
Une solution simple pour changer le nom que Jackson utilisera lors de la sérialisation en JSON consiste à utiliser l' annotation @JsonProperty , votre exemple deviendrait donc:
public class MyResponse implements Serializable { private boolean isSuccess; @JsonProperty(value="isSuccess") public boolean isSuccess() { return isSuccess; } public void setSuccess(boolean isSuccess) { this.isSuccess = isSuccess; } }
Cela serait alors sérialisé en JSON en tant que
{"isSuccess":true}
, mais présente l'avantage de ne pas avoir à modifier le nom de votre méthode getter.Notez que dans ce cas, vous pouvez également écrire l'annotation
@JsonProperty("isSuccess")
car elle n'a qu'un seulvalue
élémentla source
J'ai récemment rencontré ce problème et c'est ce que j'ai trouvé. Jackson inspectera toute classe que vous lui passerez pour les getters et les setters, et utilisera ces méthodes pour la sérialisation et la désérialisation. Ce qui suit "get", "is" et "set" dans ces méthodes sera utilisé comme clé pour le champ JSON ("isValid" pour getIsValid et setIsValid).
public class JacksonExample { private boolean isValid = false; public boolean getIsValid() { return isValid; } public void setIsValid(boolean isValid) { this.isValid = isValid; } }
De même, "isSuccess" deviendra "success", sauf s'il est renommé "isIsSuccess" ou "getIsSuccess"
En savoir plus ici: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
la source
L'utilisation des deux annotations ci-dessous force le JSON de sortie à inclure
is_xxx
:@get:JsonProperty("is_something") @param:JsonProperty("is_something")
la source
Vous pouvez configurer votre
ObjectMapper
comme suit: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); } });
la source
Lorsque vous utilisez Kotlin et des classes de données:
data class Dto( @get:JsonProperty("isSuccess") val isSuccess: Boolean )
Vous devrez peut-être ajouter
@param:JsonProperty("isSuccess")
si vous envisagez également de désérialiser JSON.la source
S'appuyant sur la réponse d'Utkarsh.
Les noms Getter moins get / is sont utilisés comme nom JSON.
public class Example{ private String radcliffe; public getHarryPotter(){ return radcliffe; } }
est stocké sous le nom {"harryPotter": "whatYouGaveHere"}
Pour la désérialisation, Jackson vérifie à la fois le setter et le nom du champ. Pour la chaîne Json {"word1": "example"} , les deux ci-dessous sont valides.
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 ; } }
Une question plus intéressante est celle de l'ordre que Jackson considère pour la désérialisation. Si j'essaye de désérialiser {"word1": "myName"} avec
public class Example3{ private String word1; private String word2; public setWord1( String parameter){ this.word2 = parameter ; } }
Je n'ai pas testé le cas ci-dessus, mais il serait intéressant de voir les valeurs de word1 & word2 ...
Remarque: j'ai utilisé des noms radicalement différents pour souligner quels champs doivent être identiques.
la source
il existe une autre méthode pour résoudre ce problème.
il suffit de définir une nouvelle sous-classe étend PropertyNamingStrategy et de la transmettre à l'instance ObjectMapper.
voici un extrait de code qui peut être plus utile:
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; } });
la source
Je ne voulais pas jouer avec certaines stratégies de dénomination personnalisées, ni recréer certains accesseurs.
Moins il y a de code, plus je suis heureux.
Cela a fait l'affaire pour nous:
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; }
la source
La réponse acceptée ne fonctionnera pas pour mon cas.
Dans mon cas, la classe ne m'appartient pas. La classe problématique provient de dépendances tierces, je ne peux donc pas simplement y ajouter une
@JsonProperty
annotation.Pour le résoudre, inspiré de la réponse @burak ci-dessus, j'ai créé une personnalisation
PropertyNamingStrategy
comme suit: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); } });
Fondamentalement, cela fait, avant de sérialiser et de désérialiser, il vérifie dans la classe cible / source quel nom de propriété est présent dans la classe, que ce soit
isEnabled
ou uneenabled
propriété.Sur cette base, le mappeur sérialisera et désérialisera le nom de propriété existant.
la source
Vous pouvez changer le booléen primitif en java.lang.Boolean (+ utiliser
@JsonPropery
)@JsonProperty("isA") private Boolean isA = false; public Boolean getA() { return this.isA; } public void setA(Boolean a) { this.isA = a; }
A parfaitement fonctionné pour moi.
la source