当POJO / Bean中嵌入了参数时,我是新手并且正在努力解决用例。
要求 -
使用Jackson(最新版本可以)为JAVA Bean / POJO类生成JSON模式,这样它可以正确地包含嵌套对象的结构,并且还希望向嵌套pojos添加自定义属性(在我的情况下,想要为每个嵌套的POJO参数添加完全分类的classname属性。)
使用案例 -
说,我有一个Person类,如下所示。我正在使用此Person作为我的一些操作的参数.-
public class Person {
private String name;
private String id;
private int i;
private Person2 p;
private List<String> strList;
private HashMap<String, String> strMap;
private Person3[] p3;
public void setName(String name){
this.name = name;
}
public void setId(String id){
this.id = id;
}
public void setI(int i){
this.i = i;
}
public void setP(Person2 p){
this.p = p;
}
public String getName(){
return this.name;
}
public String getId(){
return this.id;
}
public int getI(){
return this.i;
}
public Person2 getP(){
return this.p;
}
public void setStrList(List<String> strList){
this.strList = strList;
}
public List<String> getStrList(){
return this.strList;
}
public void setStrMap(HashMap<String, String> strMap){
this.strMap = strMap;
}
public HashMap<String, String> getStrMap(){
return this.strMap;
}
public void setP3(Person3[] p3){
this.p3 = p3;
}
public Person3[] getP3(){
return this.p3;
}
}
例如目前,当上面的Person类用作参数 -
时,它会生成以下JSON模式{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
},
"i": {
"type": "integer"
},
"p": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
},
"i": {
"type": "integer"
},
"p1": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
},
"i": {
"type": "integer"
}
}
}
}
}
},
"strList": {
"type": "array",
"items": {
"type": "string"
}
},
"strMap": {
"type": "object"
},
"p3": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
},
"i": {
"type": "integer"
}
}
}
}
},
"classname": "com.agent.Person"
}
Person类有一些多值数据结构,如 MAP , ARRAYs ,也可以嵌套 POJOs 。所以我不想为这些类型的 BEAN / POJO 类生成JSON模式,并且还希望为每个嵌套的 POJO /设置“classname”节点BEAN ,拥有完全分类的类名。
我为此经历了很多事情,但是我无法找到使用杰克逊的这种情况的短手。
此处需要注意的要点是在嵌套的POJO属性架构中放置“classname”属性。
这个问题肯定与此相关 - How to traverse generated json schema using jackson and put custom attribute in json schema
答案 0 :(得分:0)
这可以是上述问题的方法之一,可以如下 -
这是我将类名放在生成的模式中的代码。此代码处理提供数组或非数组参数时的情况。即Person.class和Person [] .class可以成功处理。此代码无法处理仍在Jackson - https://github.com/FasterXML/jackson-databind/issues/339
上打开的自引用问题下面的代码可以实例化如下 -
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Class<?> cls = Person[].class;
if(cls.isArray()){
cls = cls.getComponentType();
}
String s = "{\"rootNode\":{\"classname\":\"" + cls.getName() + "\"},"
+ getAttributeClassnames(cls) + "}";
s = s.replace("\",}", "\"}").replace("},}", "}}");
System.out.println(s);
s = mapper.generateJsonSchema(cls).getSchemaNode().put("type", "array")
.put("classnames", s).toString();
s = s.replace("\\", "").replace("\"{", "{").replace("}\"", "}");
System.out.println(s);
}
static String getAttributeClassnames(Class<?> cls) {
String s = "";
Field[] field = cls.getDeclaredFields();
int i = 0;
while (i < field.length) {
if (!(field[i].getType() == Boolean.class)
&& !(field[i].getType() == Integer.class)
&& !(field[i].getType() == Character.class)
&& !(field[i].getType() == Byte.class)
&& !(field[i].getType() == Short.class)
&& !(field[i].getType() == Long.class)
&& !(field[i].getType() == Float.class)
&& !(field[i].getType() == Double.class)
&& !(field[i].getType().isPrimitive())
&& !(field[i].getType() == String.class)
&& !(Collection.class.isAssignableFrom(field[i]
.getType()))
&& !(Map.class.isAssignableFrom(field[i].getType()))
&& !(Arrays.class.isAssignableFrom(field[i].getType()))) {
if(field[i].getType() == cls){
if (i == field.length - 1) {
Class<?> name = null;
if(field[i].getType().isArray()){
name = field[i].getType().getComponentType();
}else{
name = field[i].getType();
}
s = s + "\"" + field[i].getName() + "\""
+ ":{\"classname\":\""
+ name.getName() + "\","
+"}";
} else {
Class<?> name = null;
if(field[i].getType().isArray()){
name = field[i].getType().getComponentType();
}else{
name = field[i].getType();
}
s = s + "\"" + field[i].getName() + "\""
+ ":{\"classname\":\""
+ name.getName() + "\","
+ "}" + ",";
}
}else{
if (i == field.length - 1) {
Class<?> name = null;
if(field[i].getType().isArray()){
name = field[i].getType().getComponentType();
}else{
name = field[i].getType();
}
s = s + "\"" + field[i].getName() + "\""
+ ":{\"classname\":\""
+ name.getName() + "\","
+ getAttributeClassnames(name)
+ "}";
} else {
Class<?> name = null;
if(field[i].getType().isArray()){
name = field[i].getType().getComponentType();
}else{
name = field[i].getType();
}
s = s + "\"" + field[i].getName() + "\""
+ ":{\"classname\":\""
+ name.getName() + "\","
+ getAttributeClassnames(name)
+ "}" + ",";
}
}
}
i++;
}
return s;
}
其他方法可以是维护Jackson生成的模式的类名图。
e.g。
"classnames":{
"<attribute_name>":{
"classname":"<classname>"
}
}