将json转换为具有混合类型的数组的java对象

时间:2015-07-15 03:49:05

标签: java json

我的json字符串如下所示:

{
  "text": ["foo",1,"bar","2",3],
  "text1": "value1",
  "ComplexObject": {
   .....
   }
}

我有一个像这样定义的pojo:

class MyPojo {
 List<String> text;
 String text1;
 ComplexObject complexObject;
}

我使用google gson并且能够正确填充我的java对象。这里的问题是字段文本是混合类型的数组(字符串和整数)。所以那里的所有条目都转换成了String,我无法弄清楚数组中的哪些条目是字符串vs int。我不能使用parseInt,因为原始数组中的条目可能有&#34; 2&#34;以及3。

在转换为java对象后,有没有办法让我在数组中获得正确的实例类型的字段。

所以我使用gson实现了解决方案使用JsonDeserializer。然后我尝试使用杰克逊。猜猜杰克逊支持通过保留数据类型来序列化/反序列化混合数组类型。

ObjectMapper mapper = new ObjectMapper();
MyPojo gmEntry = mapper.readValue(json, new TypeReference<MyPojo >(){});

我基本上可以获取List&lt; Object&gt;并执行instanceof以检查数据类型。

羞辱你gson !!

5 个答案:

答案 0 :(得分:1)

通过使用自定义类并添加类型适配器,您可以操作字符串(json.toString()返回带有'''引号,因此您可以查看它是否为字符串。

输出:(类似乎正确)

class test.Main $ StringPojo pojo {object = foo}

class test.Main $ IntPojo pojo {object = 1}

class test.Main $ StringPojo pojo {object = bar}

class test.Main $ StringPojo pojo {object = 2}

class test.Main $ IntPojo pojo {object = 3}

public static void main(final String[] args){


    String str = "{\n" +
            "  \"text\": [\"foo\",1,\"bar\",\"2\",3],\n" +
            "  \"text1\": \"value1\" }";

    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(pojo.class, new JsonDeserializer<pojo>() {
        @Override
        public pojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            try {
                return new IntPojo(Integer.parseInt(json.toString()));
            } catch (Exception e) {
                return new StringPojo(json.getAsString());
            }
        }
    });
    MyPojo myPojo = builder.create().fromJson(str, MyPojo.class);
    for (pojo pojo : myPojo.text) {
        System.out.println(pojo.getClass() + " " + pojo.object);
    }
}

public static abstract class  pojo{
    protected Object object;

    public pojo() {
    }

    @Override
    public String toString() {
        return "pojo{" +
                "object=" + object +
                '}';
    }
}

public static class StringPojo extends pojo{
    public StringPojo(String str) {
        object = str;
    }
}

public static class IntPojo extends pojo{

    public IntPojo(int intt) {
        this.object = intt;
    }
}
public static class MyPojo {
    List<pojo> text;
    String text1;
}

答案 1 :(得分:0)

正如您所写 - 您定义了:List<String> text;但该列表也包含整数。

Java是强类型的,请考虑将List声明为List<Object>(不太可取)或创建仅包含单一类型变量的JSON列表(更优选)。

答案 2 :(得分:0)

您可以创建一个抽象类ItemType(用作数组项类型)并从中继承两个包装类:一个用于int类型,另一个用于字符串类型。

abstract class ItemType {
    protected Object value;
}
class IntType extends ItemType {
    IntType(Integer value){
        this.value = value;
    }
}
class StringType extends ItemType {
    IntType(String value){
        this.value = value;
    }
}

试试这个List<ItemType> text;

答案 3 :(得分:0)

答案 4 :(得分:0)

不确定这是否是您所需要的,但这是我用于解析JSON的代码。

static public void newsParser(String urlString, String targetObject) throws FileNotFoundException, IOException
    {

        URL url = new URL(urlString);

        JSONParser parser=new JSONParser();


           BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));



           Object obj;
        try 
        {
            obj = parser.parse(br);         
            //JSONObject jsonObject = (JSONObject) obj;
            JSONArray jsonArray = (JSONArray) obj;

            Iterator<?> i = jsonArray.iterator();

            while (i.hasNext())
            {
                slide = (JSONObject) i.next();
                newsInfo = (String)slide.get(targetObject);   
                System.out.println(newsInfo);
                newsTitles.add(newsInfo);


            }
        } 
        catch (ParseException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }