Este podría ser un duplicado. Pero no puedo encontrar una solución a mi problema.
Tengo una clase
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Eclipse genera los getters y setters.
En otra clase, establezco el valor en verdadero y lo escribo como una cadena JSON.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
En JSON, la clave viene como {"success": true}
.
Quiero la llave como isSuccess
ella misma. ¿Está Jackson usando el método setter durante la serialización? ¿Cómo hacer que la clave sea el nombre del campo?
isSuccess
,isIsSuccess
creo que el nombre del método debe serSetSuccess
porque lo genera Eclipse. (Siguiendo un estándar)Respuestas:
Esta es una respuesta un poco tardía, pero puede ser útil para cualquier otra persona que acceda a esta página.
Una solución simple para cambiar el nombre que Jackson usará al serializar a JSON es usar la anotación @JsonProperty , por lo que su ejemplo sería:
public class MyResponse implements Serializable { private boolean isSuccess; @JsonProperty(value="isSuccess") public boolean isSuccess() { return isSuccess; } public void setSuccess(boolean isSuccess) { this.isSuccess = isSuccess; } }
Esto luego se serializaría en JSON como
{"isSuccess":true}
, pero tiene la ventaja de no tener que modificar el nombre del método getter.Tenga en cuenta que en este caso también puede escribir la anotación,
@JsonProperty("isSuccess")
ya que solo tiene unvalue
elementofuente
Recientemente me encontré con este problema y esto es lo que encontré. Jackson inspeccionará cualquier clase que le pase en busca de getters y setters, y utilizará esos métodos para la serialización y deserialización. Lo que sigue a "get", "is" y "set" en esos métodos se utilizará como clave para el campo JSON ("isValid" para getIsValid y setIsValid).
public class JacksonExample { private boolean isValid = false; public boolean getIsValid() { return isValid; } public void setIsValid(boolean isValid) { this.isValid = isValid; } }
De manera similar, "isSuccess" se convertirá en "success", a menos que se cambie el nombre a "isIsSuccess" o "getIsSuccess"
Lea más aquí: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
fuente
El uso de ambas anotaciones a continuación obliga al JSON de salida a incluir
is_xxx
:@get:JsonProperty("is_something") @param:JsonProperty("is_something")
fuente
Puede configurar su de la
ObjectMapper
siguiente manera: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); } });
fuente
Cuando usa Kotlin y clases de datos:
data class Dto( @get:JsonProperty("isSuccess") val isSuccess: Boolean )
Es posible que deba agregar
@param:JsonProperty("isSuccess")
si también va a deserializar JSON.fuente
Sobre la base de la respuesta de Utkarsh.
Los nombres de getter menos get / is se utilizan como nombre JSON.
public class Example{ private String radcliffe; public getHarryPotter(){ return radcliffe; } }
se almacena como {"harryPotter": "lo que sea que tengas aquí"}
Para deserialización, Jackson verifica tanto el colocador como el nombre del campo. Para la cadena Json {"word1": "example"} , ambos siguientes son válidos.
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 pregunta más interesante es qué orden considera Jackson para la deserialización. Si intento deserializar {"word1": "myName"} con
public class Example3{ private String word1; private String word2; public setWord1( String parameter){ this.word2 = parameter ; } }
No probé el caso anterior, pero sería interesante ver los valores de word1 y word2 ...
Nota: Utilicé nombres drásticamente diferentes para enfatizar qué campos deben ser iguales.
fuente
hay otro método para este problema.
simplemente defina una nueva subclase extiende PropertyNamingStrategy y pásala a la instancia de ObjectMapper.
aquí hay un fragmento de código que puede ser más útil:
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; } });
fuente
No quería meterme con algunas estrategias de nomenclatura personalizadas, ni volver a crear algunos accesos.
Cuanto menos código, más feliz soy.
Esto nos sirvió:
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; }
fuente
La respuesta aceptada no funcionará para mi caso.
En mi caso, la clase no me pertenece. La clase problemática proviene de dependencias de terceros, por lo que no puedo simplemente agregar una
@JsonProperty
anotación en ella.Para resolverlo, inspirado en la respuesta de @burak anterior, creé una personalizada de la
PropertyNamingStrategy
siguiente manera: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); } });
Básicamente, lo que hace es, antes de serializar y deserializar, verifica en la clase de destino / fuente qué nombre de propiedad está presente en la clase, si es
isEnabled
oenabled
propiedad.En base a eso, el asignador serializará y deserializará el nombre de propiedad que existe.
fuente
Puede cambiar el booleano primitivo a java.lang.Boolean (+ usar
@JsonPropery
)@JsonProperty("isA") private Boolean isA = false; public Boolean getA() { return this.isA; } public void setA(Boolean a) { this.isA = a; }
Funcionó excelente para mí.
fuente