Java Jackson:使用点表示法将JSON属性转换为嵌套对象
我有一个类似这样的JSONJava Jackson:使用点表示法将JSON属性转换为嵌套对象,java,json,spring,jackson,Java,Json,Spring,Jackson,我有一个类似这样的JSON { "id":1, "name":"Jack", "parent.id":2 } 注意“parent.id”属性上的点 是否可以将这些JSON映射到以下类 class Child { private int id; private String name; private Parent parent; //getter and setter methods } class Parent { private int id;
{ "id":1, "name":"Jack", "parent.id":2 }
注意“parent.id”属性上的点
是否可以将这些JSON映射到以下类
class Child {
private int id;
private String name;
private Parent parent;
//getter and setter methods
}
class Parent {
private int id;
private String name;
//getter and setter methods
}
因此,映射结果将类似于以下语句:
Parent parent = new Parent();
parent.setId(2);
Child child = new Child();
child.setId(1);
child.setName("Jack");
child.setParent(parent); // Here is the result
你可以转换这个
{“id”:1,“name”:“Jack”,“parent.id”:2}
进入这个
{“id”:1,“name”:“Jack”,“parent”:{“id”:2}
用这个
//我在这里使用jQuery
$.fn.serializeObject=函数(){
var arrayData,objectData;
arrayData=this.serializeArray();
objectData={};
$.each(数组数据,函数(){
var值;
如果(this.value!=null){
value=this.value;
}否则{
值=“”;
}
//搜索类似“parent.id”的属性
if(this.name.indexOf('.')!=-1){
var attrs=this.name.split('.');
var tx=对象数据;
对于(变量i=0;i
然后可以使用JSON.serialize()
对代码进行序列化
如果您使用的是Jackson,则可以通过执行以下任一操作来反序列化JSON请求字符串:
1。创建自定义Jackson反序列化模块
2。自己解析JSON
public子进程(字符串jsonRequest){
//我们需要什么
对象映射器映射器;
JsonNode根,parentNode;
//你的模型
儿童;
父母;
//分配
映射器=新的ObjectMapper();
root=mapper.readTree(jsonRequest);//将JSON反序列化为树
parentNode=root.get(“parent”);//获取“parent”分支
//分配(再次)
child=mapper.readValue(根,child.class);
parent=mapper.readValue(parentNode,parent.class);
setParent(家长);
返回儿童;
}
这种方法的缺点是您必须使用嵌套对象解析每个单独的JsonRequest,当存在复杂的嵌套结构时,这种方法会很混乱。如果这是一个问题,我建议你做#3
3。创建自定义Jackson ObjectMapper类以自动化此过程
其想法是为#2构建通用流程,以便它能够处理任何嵌套请求
public class CustomObjectMapper extends ObjectMapper {
// here's the method you need
@Override
public <T> T readValue(String src, Class<T> type)
throws IOException, JsonParseException, JsonMappingException {
JsonNode root = this.readTree(src);
try {
return readNestedValue(root, type);
} catch (InstantiationException | IllegalAccessException | IOException
| IllegalArgumentException | InvocationTargetException e) {
return super.readValue(src, type);
}
}
// if you're using Spring, I suggest you implement this method as well
// since Spring's MappingJacksonHttpMessageConverter class will call
// this method.
@Override
public <T> T readValue(InputStream src, JavaType type)
throws IOException, JsonParseException, JsonMappingException {
JsonNode root = this.readTree(src);
try {
return readNestedValue(root, (Class<T>) type.getRawClass());
} catch (InstantiationException | IllegalAccessException | IOException
| IllegalArgumentException | InvocationTargetException e) {
return super.readValue(src, type);
}
}
// we need this to recursively scan the tree node
protected <T> T readNestedValue(JsonNode root, Class<T> type)
throws InstantiationException, IllegalAccessException, IOException,
IllegalArgumentException, InvocationTargetException {
// initialize the object use ObjectMapper's readValue
T obj = super.readValue(root, type);
Iterator it = root.getFieldNames();
while (it.hasNext()) {
String name = (String) it.next();
String camelCaseName = name.substring(0, 1).toUpperCase() + name.substring(1);
JsonNode node = root.get(name);
Field f;
try {
f = type.getDeclaredField(name);
} catch (NoSuchFieldException e) {
f = findFieldInSuperClass(name, type.getSuperclass());
}
// if no field found then ignore
if (f == null) continue;
Method getter, setter;
try {
getter = type.getMethod("get" + camelCaseName);
} catch (NoSuchMethodException e) {
getter = findGetterInSuperClass("get" + camelCaseName, type.getSuperclass());
}
// if no getter found or it has been assigned then ignore
if (getter == null || getter.invoke(obj) != null) continue;
try {
setter = type.getMethod("set" + camelCaseName);
} catch (NoSuchMethodException ex) {
setter = findSetterInSuperClass("set" + camelCaseName, type.getSuperclass(), f.getType());
}
// if no setter found then ignore
if (setter == null) continue;
setter.invoke(obj, readNestedValue(node, f.getType()));
}
return obj;
}
// we need this to search for field in super class
// since type.getDeclaredField() will only return fields that in the class
// but not super class
protected Field findFieldInSuperClass(String name, Class sClass) {
if (sClass == null) return null;
try {
Field f = sClass.getDeclaredField(name);
return f;
} catch (NoSuchFieldException e) {
return findFieldInSuperClass(name, sClass.getSuperclass());
}
}
protected Method findGetterInSuperClass(String name, Class sClass) {
if (sClass == null) return null;
try {
Method m = sClass.getMethod(name);
return m;
} catch (NoSuchMethodException e) {
return findGetterInSuperClass(name, sClass.getSuperclass());
}
}
protected Method findSetterInSuperClass(String name, Class sClass, Class type) {
if (sClass == null) return null;
try {
Method m = sClass.getMethod(name, type);
return m;
} catch (NoSuchMethodException e) {
return findSetterInSuperClass(name, sClass.getSuperclass(), type);
}
}
}
希望这有帮助:)您可以通过定义自己的MessageBodyReader来做到这一点,但我必须问一下。。。为什么?因为我使用的是ExtJS,它发送的JSON格式如上所述。我们所有的解决方案中都有Ext.js客户端。让GUI开发人员修复他们的模型。
@RequestMapping("/saveChild.json")
@ResponseBody
public Child saveChild(@RequestBody Child child) {
// do something with child
return child;
}