我遇到以下问题:我像往常一样使用jackson.databind.ObjectMapper
导出我的用户对象,并且工作正常:({"address":{"village":"NY"},"prename":"Joe"})
。
现在我必须使用Java反射获取密钥(对于address
和prename
)。
如果该字段具有注释@JsonProperty
,则获取此密钥没有问题。但是这个注释并不适用于所有字段(例如m_address
字段)。
在How does the Jackson mapper know what field in each Json object to assign to a class object?我看到ObjectMapper
试图调用getter左右。
但我不知道如何才能找到适合自己领域的人。
我知道这不是解决我问题的最佳方式,但我还没有找到ObjectMapper
上的任何方法:mapper.getJSONKeyByName(field)
。
如果这样的事情存在甚至更好。 :)
有没有办法在字段中找到合适的getter并在mapper.getJSONKeyByName(field)
上存在类似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;
}
}
编辑:
代码简化了。我有一个REST服务,它执行writeValue
部分。反射部分是在User
上的静态递归方法中完成的。
问题是我在我的字段上有一个自定义Validationinfo
注释(包含required,maxlength等内容),还有一个名称参数。此名称与@JsonProperty
注释中的名称相同。
在JavaScript应用程序上,我希望将用户字段的值与ValidationInfos
合并。为此,我必须确保每个validationInfos->name
都是唯一的。因此,我必须在带注释的Vaditioninfo->name
前缀中添加其父级的JSON序列化名称/密钥(请参阅REST响应" address.village")。
我要锁定的其余回复:
{
"user": {
"prename": "Joe",
"address" : {
"village": "NY"
}
}, "validationInfos": [{
"name": "prename",
"required": true,
"maxlenght": 10
}, {
"name": "address.village",
"required": false,
"maxlenght": 20
}]
}
在JavaScript中我计划做类似的事情:
for (var i = 0; i < data.validationInfos.length;; i++) {
var element = data.validationInfos;
element.value = eval ("data.user." + element.name);
}
答案 0 :(得分:5)
你应该使用jackson内省而不是纯java反射。它将允许您根据序列化配置发现映射到java字段/方法的json属性。
JavaType userType = mapper.getTypeFactory().constructType(User.class);
BeanDescription introspection =
mapper.getSerializationConfig().introspect(userType);
List<BeanPropertyDefinition> properties = introspection.findProperties();
// do some processing over properties...