I have the following problem: I export my user object as usual with the jackson.databind.ObjectMapper
and that works fine: ({"address":{"village":"NY"},"prename":"Joe"})
.
Now I have to get the key (for address
and prename
) with Java reflection.
If the field has the annotation @JsonProperty
, there is no problem to get this key. But this annotation isn't pressent on all fields (for example the m_address
field).
At How does the Jackson mapper know what field in each Json object to assign to a class object? I read that the ObjectMapper
tries to call the getter or so.
But I have no clue how I can find the right getter to my field.
I know that this isn't probably the most beautiful way to solve my problem, but I haven't found any method on the ObjectMapper
like: mapper.getJSONKeyByName(field)
.
If something like that exist even better. :)
Is there a way to find the right getter to a field and does something like mapper.getJSONKeyByName(field)
exist on the ObjectMapper
?
Main.java
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// Object to JSON as usual
mapper.writeValue(System.out, new User("Joe", new Address("NY")));
// {"address":{"village":"NY"},"prename":"Joe"}
// Lookup with reflection
for (Field field : User.class.getDeclaredFields()) {
field.setAccessible(true);
try {
if (field.isAnnotationPresent(JsonProperty.class)) {
System.out.println("JSON-Key with annotation: " +
field.getAnnotation(JsonProperty.class).value());
// JSON-Key with annotation: prename
} else {
//TODO do something to get "JSON-Key without annotation: address
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
User.java
public class User implements Serializable {
@JsonProperty(value="prename")
@Validationinfo(name="prename", required=true, maxlenght=20)
private String m_name;
private Address m_address;
public User(String name, Address a) {
m_name = name;
m_address = a;
}
@JsonIgnore
public String getName() {
return m_name;
}
public void setName(String name) {
m_name = name;
}
public Address getAddress() {
return m_address;
}
public void setAddress(Address address) {
m_address = address;
}
}
Address.java
public class Address implements Serializable {
@JsonProperty(value="village")
@Validationinfo(name="village", required=false, maxlenght=10)
private String m_village;
public Address(String village) {
m_village = village;
}
public String getVillage() {
return m_village;
}
public void setVillage(String village) {
m_village = village;
}
}
EDIT:
The code is simplified. I have a REST service which does the writeValue
part. The reflection part is done in a static recursive method on the User
.
The thing is I have a custom Validationinfo
annotation (with things like required, maxlength and so on) on my fields and also a name parameter. This name is the same as it is on the @JsonProperty
annotation.
On an JavaScript application I want merge the value of the user fields with the ValidationInfos
. For that I have to ensure that every validationInfos->name
is unique. So I have to prefix the annotated Vaditioninfo->name
whith the JSON serialized name/key of its parent (see in the REST respons "address.village").
The rest response I am locking for:
{
"user": {
"prename": "Joe",
"address" : {
"village": "NY"
}
}, "validationInfos": [{
"name": "prename",
"required": true,
"maxlenght": 10
}, {
"name": "address.village",
"required": false,
"maxlenght": 20
}]
}
In JavaScript I planning to do something like:
for (var i = 0; i < data.validationInfos.length;; i++) {
var element = data.validationInfos;
element.value = eval ("data.user." + element.name);
}
You should use jackson introspection instead of pure java reflection. It will allow you to discover json properties mapped to java fields/methods according to your serialization config.
JavaType userType = mapper.getTypeFactory().constructType(User.class);
BeanDescription introspection =
mapper.getSerializationConfig().introspect(userType);
List<BeanPropertyDefinition> properties = introspection.findProperties();
// do some processing over properties...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With