使用可以映射或数组的键将JSON绑定到bean

时间:2018-02-18 15:07:31

标签: java json javabeans

我有一个动态传入的JSON,如下所示:

  1. 第一种可能性

    {
    "key1":"value1",
    "key2":"value2",
    "key3":{
           "inKey1":"inValue1",
           "inKey2":"inValue2"
           }
    }
    
  2. 第二种可能性

    { "key1":"value1", "key2":"value2", "key3":[{
           "inKey1":"inValue1",
            "inKey2":"inValue2"
            },{
            "inKey1":"inValue3",
            "inKey2":"inValue4"
       }] }
    

    key3的值通常是地图。但有时它也可以作为一个数组出现。我必须将此JSON绑定到Bean,然后继续。我打算写两个bean,一个用key3作为映射,另一个用key3作为数组。我将检查key3的值是否是map或数组的实例,然后绑定到相应的bean。是否有任何最佳方法可以使用单个bean完成此任务?请指导我。

  3. Beans(我还没写过)会是这样的:

    public class Bean1{
    
    private String key1;
    private String key2;
    private Map<String, String> key3 = new HashMap<String, String>();
    
    }
    
    public class Bean2{
    
    private String key1;
    private String key2;
    private Map<String, String> key3[];
    
    }
    

2 个答案:

答案 0 :(得分:1)

具有共同属性的不同json输入的反序列化可以通过泛化(继承)来完成。

定义父bean:定义具有公共属性的父bean

public class ParentBean {

    protected String key1;
    protected String key2;

    public ParentBean(String key1, String key2) {
        super();
        this.key1 = key1;
        this.key2 = key2;
    }
    // Setters and Getters
}

定义子bean:定义具有特殊属性的子bean

<强> Bean1

public class Bean1 extends ParentBean {

    private Map<String, String> key3;

    public Bean1(String key1, String key2, Map<String, String> key3) {
        super(key1, key2);
        this.key3 = key3;
    }
    // Setters and Getters
}

<强> Bean2

public class Bean2 extends ParentBean {

    private Map<String, String> key3[];

    public Bean2(String key1, String key2, Map<String, String>[] key3) {
        super(key1, key2);
        this.key3 = key3;
    }
    // Setters and Getters
}

设计一个反序列化程序:由于没有指定框架,我冒昧地使用了jackson framwork。使用jackson可以按如下方式设计解串器:

public class ParentBeanDeserializer extends StdDeserializer<ParentBean>{

    public ParentBeanDeserializer() { 
        this(null); 
    } 

    public ParentBeanDeserializer(Class<?> c) { 
        super(c); 
    }   

    @Override
    public ParentBean deserialize(JsonParser jp, DeserializationContext ctxt) 
        throws IOException, JsonProcessingException{

        ParentBean pb;
        JsonNode node = jp.getCodec().readTree(jp);
        String value1 = node.findValue("key1").asText();
        String value2 = node.findValue("key2").asText();
        JsonNode node3 = node.findValue("key3");
        ObjectMapper mapper = new ObjectMapper();

        if(node3.isArray()){
            String json3 = node3.toString();
            Map<String, String>[] map = mapper.readValue(json3, Map[].class);
            pb = new Bean2(value1,value2,map);
        }
        else{
            String json3 = node3.toString();
            Map<String, String> map = mapper.readValue(json3, Map.class);
            pb = new Bean1(value1,value2,map);
        }

        return pb;
    }

}

用法:上面提到的Beans / Classes可以按如下方式使用:

     String json = getJasonResponseAsText();
     ObjectMapper om = new ObjectMapper();
     SimpleModule mod = new SimpleModule();
     mod.addDeserializer(ParentBean.class, new ParentBeanDeserializer());
     om.registerModule(mod);
     ParentBean pb = om.readValue(json, ParentBean.class);
     if (pb instanceof Bean1) {
           Bean1 b1 = (Bean1)pb;
           //Perform Bean1 related activites
     } 
     else if (pb instanceof Bean2) {
           Bean2 b2 = (Bean2)pb;
           //Perform Bean2 related activites
     } 

答案 1 :(得分:0)

我正在使用org.json,主要是检查密钥是否为instanceof对象或数组。当你了解钥匙的种类时。你可以很容易地把你的逻辑。

在第一种情况下,你有对象然后我只需要转换为对象并获取值。

在第二种情况下,您拥有数组,因此我将其转换为JSONArary并使用简单的for循环来收集元素。

代码:

package jsontest;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
/**
 *
 * @author Sahil
 */
class Model1{
    String key1;
    String key2;
    List<Model2> key3;
    Model1(){
        key3 = new ArrayList<>();
    }

    @Override
    public String toString() {  
        String s = "key1=" + key1 + ", key2=" + key2;
        for(Model2 m: key3){
            s+="\n"+"inKey1="+m.key1+", inkey2="+m.key2;
        }  
        return s;
    }

}
class Model2{
   String key1;
   String key2;
}



public class JSONTest {


    static Model1 parse(String s){
         JSONObject object = new JSONObject(s);
        Model1 model = new Model1();
        model.key1 = object.getString("key1");
        model.key2 = object.getString("key2");

        if (object.get("key3") instanceof JSONObject){
            JSONObject key3 = object.getJSONObject("key3");
            Model2 model2 = new Model2();
            model2.key1 = key3.getString("inKey1");
            model2.key2 = key3.getString("inKey2");
            model.key3.add(model2);

        }else{
            JSONArray array = object.getJSONArray("key3");
            for(int i=0;i<array.length();i++){
                JSONObject row = array.getJSONObject(i);
                Model2 model2 = new Model2();
                model2.key1 = row.getString("inKey1");
                model2.key2 = row.getString("inKey2");
                model.key3.add(model2);
            }
        }
        return model;
    }


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        String firstCase = "{\r\n\"key1\":\"value1\",\r\n\"key2\":\"value2\",\r\n\"key3\":{\r\n       \"inKey1\":\"inValue1\",\r\n       \"inKey2\":\"inValue2\"\r\n       }\r\n}";
        String secondCase = "{ \"key1\":\"value1\", \"key2\":\"value2\", \"key3\":[{\r\n       \"inKey1\":\"inValue1\",\r\n        \"inKey2\":\"inValue2\"\r\n        },{\r\n        \"inKey1\":\"inValue3\",\r\n        \"inKey2\":\"inValue4\"\r\n   }] }";
        System.out.println(parse(firstCase));
        System.out.println("---------");
        System.out.println(parse(secondCase));

    }

}

结果:

key1=value1, key2=value2
inKey1=inValue1, inkey2=inValue2
---------
key1=value1, key2=value2
inKey1=inValue1, inkey2=inValue2
inKey1=inValue3, inkey2=inValue4
相关问题