将json转换为混合类型数组的java对象
我的json字符串如下所示:将json转换为混合类型数组的java对象,java,json,Java,Json,我的json字符串如下所示: { "text": ["foo",1,"bar","2",3], "text1": "value1", "ComplexObject": { ..... } } 我的pojo定义如下: class MyPojo { List<String> text; String text1; ComplexObject complexObject; } 类MyPojo{ 列表文本; 字符串text1; ComplexObject C
{
"text": ["foo",1,"bar","2",3],
"text1": "value1",
"ComplexObject": {
.....
}
}
我的pojo定义如下:
class MyPojo {
List<String> text;
String text1;
ComplexObject complexObject;
}
类MyPojo{
列表文本;
字符串text1;
ComplexObject ComplexObject;
}
我使用GoogleGSON,能够正确填充java对象。这里的问题是字段文本是一个混合类型(string和int)的数组。因此,所有的条目都被转换成字符串,我无法确定数组中哪些条目是字符串vs int。我不能使用parseInt,因为原始数组中的条目可能有“2”和“3”
在转换为java对象之后,是否有一种方法可以让我获得数组中字段的正确实例类型
解决方案
因此,我通过使用JsonDeserializer,以循环方式使用gson实现了该解决方案。然后我试着用杰克逊。猜猜jackson通过保留数据类型支持对混合数组类型进行序列化/反序列化
ObjectMapper mapper = new ObjectMapper();
MyPojo gmEntry = mapper.readValue(json, new TypeReference<MyPojo >(){});
ObjectMapper mapper=new ObjectMapper();
MyPojo gmEntry=mapper.readValue(json,新类型引用(){});
我基本上可以获取列表并执行instanceof来检查数据类型
你真可耻,格森 正如您所写-您定义:
列出文本代码>但该列表也包含整数
java是强类型的,请考虑将列表声明为“代码>列表(不太好))或创建仅包含单一类型变量(更优选)的JSON列表。并从中继承两个包装器类:一个用于int类型,另一个用于string类型
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;
}
}
试试这个列表文本
使用Gson API的TypeAdapter
可以实现上述情况
请遵循:通过拥有一个自定义类并添加一个类型适配器,您可以操作字符串(json.toString()返回带“.”引号的字符串,以便查看它是否是字符串
输出:(类似乎正确)
类test.Main$StringPojo pojo{object=foo}
类test.Main$IntPojo pojo{object=1}
类test.Main$StringPojo pojo{object=bar}
类test.Main$StringPojo pojo{object=2}
类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;
}
publicstaticvoidmain(最终字符串[]args){
字符串str=“{\n”+
“\'text\:[\'foo\”,1,\'bar\,\'2\',3],\n”+
“\“text1\”:\“value1\”}”;
GsonBuilder=新的GsonBuilder();
registerTypeAdapter(pojo.class,新的JsonDeserializer()){
@凌驾
公共pojo反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
试一试{
返回新的IntPojo(Integer.parseInt(json.toString());
}捕获(例外e){
返回新的StringPojo(json.getAsString());
}
}
});
MyPojo MyPojo=builder.create().fromJson(str,MyPojo.class);
for(pojo-pojo:myPojo.text){
System.out.println(pojo.getClass()+“”+pojo.object);
}
}
公共静态抽象类pojo{
保护对象;
公共pojo(){
}
@凌驾
公共字符串toString(){
返回“pojo{”+
“object=“+object”+
'}';
}
}
公共静态类StringPojo扩展了pojo{
公共字符串POJO(字符串str){
对象=str;
}
}
公共静态类IntPojo扩展了pojo{
公共IntPojo(int intt){
this.object=intt;
}
}
公共静态类MyPojo{
列表文本;
字符串text1;
}
不确定这是否是您需要的,但这是我用于解析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();
}
}
static public void newsParser(字符串urlString,字符串targetObject)抛出FileNotFoundException,IOException
{
URL=新URL(URL字符串);
JSONParser=新的JSONParser();
BufferedReader br=新的BufferedReader(新的InputStreamReader(url.openStream());
对象对象对象;
尝试
{
obj=parser.parse(br);
//JSONObject JSONObject=(JSONObject)对象;
JSONArray JSONArray=(JSONArray)obj;
迭代器i=jsonArray.Iterator();
while(i.hasNext())
{
幻灯片=(JSONObject)i.next();
newsInfo=(字符串)slide.get(targetObject);
System.out.println(newsInfo);
新闻标题。添加(新闻信息);
}
}
捕获(解析异常)
{
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
棘手的情况。您可能已经尝试过了,但无法单独维护数据,即字符串和数字吗?没错,我无法单独维护数据。gson不知道数据包含整数、字符串和整数的事实。根据列表,它会将所有内容转换为字符串。完成后,如果不获取实际为整数的字符串,似乎无法单独获取整数。在我看来,这是一条死胡同。我不受gson的限制。还有其他库可以提供帮助吗?将其定义为列表的问题是,我无法确定列表中的哪些元素是整数还是字符串。getClass()返回java.lang.Object.Of当然,因为这是列表的类型:)这也是我写这篇文章的原因,它不是最好的方法-你可以这样做,但你必须做一些难看的事情才能让它工作。例如:Object[]a={“a”,1};System.out.println(Integer.valueOf((String.valueOf(a[1]));
然后用try/catch
包围它,以防它不是int
等。正如我在帖子中提到的,我不能使用Integer.valueOf,因为我的json数组可以说是“3”和2,例如。[“3”,2],你可以将json作为字符串,自己解析,寻找每个字符串