使用 fastjson 解析 一段 json 代码

sjack 发布于 2013/11/25 20:39
阅读 15K+
收藏 3

【华为云1024程序员节·向云而生】预约直播 抽14件华为电子产品礼包!>>>

@wenshao 你好,想跟你请教个问题:


{
    "videoshow": {
        "video_num": 18, 
        "videos": [
            {
                "title": "超凡双生", 
                "id": "39136", 
                "url": "http://v.baidu.com/movie/39136.htm?frp=browse", 
                "imgh_url": "http://t3.baidu.com/it/u=527612535,1157759507&fm=20", 
                "imgv_url": "http://t1.baidu.com/it/u=2058947437,659833583&fm=20", 
                "intro": "超能力悬疑题材,好棒,会成为继暴雨后的又一个类型神作。", 
                "rating": "93", 
                "date": "2013", 
                "duration": "0", 
                "s_intro": "超能力悬疑题材,好棒,会成为继暴雨后的又一个类型神作。", 
                "source": "0", 
                "hot": "5529", 
                "extRd": [
                    {
                        "name": "艾伦·佩吉"
                    }
                ], 
                "actor": [
                    {
                        "name": "艾伦·佩吉", 
                        "nameEnc": "%B0%AC%C2%D7%A1%A4%C5%E5%BC%AA"
                    }, 
                    {
                        "name": "卡丹·哈迪森", 
                        "nameEnc": "%BF%A8%B5%A4%A1%A4%B9%FE%B5%CF%C9%AD"
                    }, 
                    {
                        "name": "Alex Martin", 
                        "nameEnc": "Alex+Martin"
                    }
                ], 
                "area": [
                    {
                        "name": "法国"
                    }
                ], 
                "type": [
                    {
                        "name": "剧情"
                    }, 
                    {
                        "name": "动作"
                    }
                ], 
                "site": [ ]
            } ]
    }, 
    "condition_order_list": {
        "condition_list": [
            {
                "name": "类型", 
                "field": "type", 
                "value": [
                    "全部", 
                    "喜剧", 
                    "恐怖", 
                    "爱情", 
                    "动作", 
                    "伦理", 
                    "科幻", 
                    "战争", 
                    "犯罪", 
                    "惊悚", 
                    "动画", 
                    "剧情", 
                    "古装", 
                    "奇幻", 
                    "武侠", 
                    "冒险", 
                    "悬疑", 
                    "传记", 
                    "运动", 
                    "音乐"
                ], 
                "combine_field": "type,complete,rating,start,area"
            }
        ], 
        "order_list": [
            {
                "name": "按热门", 
                "field": "hot", 
                "value": "按热门"
            }
        ]
    }, 
    "total_num": 38859
}


敢问下, 怎么才能最少代码, 最轻松的解析 ? @红薯



加载中
0
SilenceSu
SilenceSu

最简单就是   Object t=JSON.parse("jsonStr");

如果你要生成模型就

TModel tModel=new TModel();

  tModel=JSON.parseObject("jsonstr", TModel.class);


SilenceSu
SilenceSu
貌似不可以
sjack
sjack
有没有生成这些 Model 或者 bean 的呢
0
Timco
Timco
今天也看了看fastjson,官方的文档少的可怜,尤其是反序列化,api也没看到,感觉有点反人类,不近人情-.-简单的话,用json-lib吧
0x0001
0x0001
回复 @Timco : 可以这个注解使用来自定义@JSONField(name = "uid"),就是对应bean是别人定义的,自己不能修改的情况我也没找到好方法
Timco
Timco
回复 @0x0001 :谢了。 又看了一遍,序列化的例子还挺多;从json反序列化为JavaBean除了最简单的那个例子,还有说明吗?难道是我眼拙了-。-主要是如何解决反序列化时怎么处json对象名和bean的属性名不一致的情况
0x0001
0x0001
fastjson可以用json-lib的方式使用,你说没有文档的话,看看这里能不能满足你的需求http://code.alibabatech.com/wiki/display/FastJSON/Tutorial 左边菜单有更多例子,fastjson是我用过最好用的json解析方案了,不过还是有些地方不爽,例如非默认构造器的反序列化(只能注解,但是有些业务是不能修改对方的bean的)
13123123
13123123
fastjson 是一个高效的解析json格式~
0
sjack
sjack
package movie;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import movie.db.DBConfig;
import movie.ut.UTool;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

public class ZyCatch {

	/**
	 * 抓取电影
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		int endPg = 112;
		for(int i=0; i < endPg; i++) {
			String u = "http://v.baidu.com/commonapi/tvplay2level/?callback=jQuery19101345447443422504_1385384941197&filter=false&type=&area=&actor=&start=&complete=&order=hot&pn="+ 
					i +"&rating=&prop=&_=1385384941199";
			String ht = UTool.getHtml(u).trim();
			ht = ht.substring(0, ht.length() - 1); // 去掉尾部的 ')'
			ht = UTool.replace(ht, "jQuery\\d+\\_\\d+\\(", ""); // 去掉开头的 jQ 调用

			JSONObject jp = JSON.parseObject(ht);
			Integer total_num = jp.getInteger("total_num");
			JSONArray videos = jp.getJSONObject("videoshow").getJSONArray("videos");
			for (int idx= 0; idx < videos.size(); idx++) {
				save(videos.getJSONObject(idx));
			}
		}
	}

	static String tn = "zy";
	/**
	 * @param mv
	 */
	private static void save(JSONObject mv) {
		Record rc;
		rc = getRecord(mv);
		
//		Map<String, Object> kvs = rc.getColumns();
//		Set<Entry<String, Object>> ent = kvs.entrySet();
//		for (Entry<String, Object> e : ent) {
//			System.out.println(e.getKey() +" =>"+ e.getValue());
//		}
//		System.out.println("\n\n\n\n\n");
		
		Db.save(DBConfig.ds, tn, "id", rc);
	}
	private static Record getRecord(JSONObject mv) {
		Record rc = new Record();
		// new
		rc.set("finish", getFin(mv));
		rc.set("season", getSea(mv));
		rc.set("season_num", getSeaN(mv));
		rc.set("season_type", getSeaT(mv));
		rc.set("update", getUpd(mv));
		rc.set("works_id", getWid(mv));
		
		rc.set("actor", getAc(mv));
		rc.set("area", getAr(mv));
		rc.set("date", getDate(mv));
//		rc.set("duration", getDur(mv));
		rc.set("extRd", getExt(mv));
//		rc.set("hot", getHot(mv));
		rc.set("m_id", getId(mv)); // 原名是 id
		rc.set("imgh_url", getImghUrl(mv));
		rc.set("imgv_url", getImgvUrl(mv));
		rc.set("intro", getIntro(mv));
//		rc.set("rating", getRat(mv));
		rc.set("s_intro", getSin(mv));
		rc.set("site", getSit(mv));
//		rc.set("source", getSou(mv));
		rc.set("title", getTit(mv));
		rc.set("type", getTyp(mv));
		rc.set("url", getUr(mv));
		
		return rc;
	}
	
	//
	private static String getWid(JSONObject mv) {
		return mv.getString("works_id").trim();
	}
	private static String getUpd(JSONObject mv) {
		return mv.getString("update").trim();
	}
	private static String getSeaT(JSONObject mv) {
		return mv.getString("season_type").trim();
	}
	private static String getSeaN(JSONObject mv) {
		return mv.getString("season_num").trim();
	}
	private static String getSea(JSONObject mv) {
		return mv.getString("season").trim();
	}
	private static String getFin(JSONObject mv) {
		return mv.getString("finish").trim();
	}
	//
	private static String getUr(JSONObject mv) {
		return mv.getString("url").trim();
	}
	private static String getTyp(JSONObject mv) {
		StringBuffer s = new StringBuffer();
		if (mv.getString("type").length() > 0) {
			JSONArray tp = mv.getJSONArray("type");
			for(int idx=0; idx < tp.size(); idx++) {
				JSONObject o = tp.getJSONObject(idx);
				s.append(o.getString("name") + " ");
			}
		}
		return s.toString().trim();
	}
	private static String getTit(JSONObject mv) {
		return mv.getString("title").trim();
	}
	private static String getSou(JSONObject mv) {
		return mv.getString("source").trim();
	}
	private static String getSit(JSONObject mv) {
		return mv.getString("site").trim();
	}
	private static String getSin(JSONObject mv) {
		return mv.getString("s_intro").trim();
	}
	private static String getRat(JSONObject mv) {
		return mv.getString("rating").trim();
	}
	private static String getIntro(JSONObject mv) {
		return mv.getString("intro").trim();
	}
	private static String getImgvUrl(JSONObject mv) {
		return mv.getString("imgv_url").trim();
	}
	private static String getImghUrl(JSONObject mv) {
		return mv.getString("imgh_url").trim();
	}
	private static String getId(JSONObject mv) {
		return mv.getString("id").trim();
	}
	private static String getHot(JSONObject mv) {
		return mv.getString("hot").trim();
	}
	private static String getExt(JSONObject mv) {
		StringBuffer s = new StringBuffer();
		try {
			if (mv.getString("extRd") != null
					&& mv.getString("extRd").length() > 0) {
				JSONArray ext = mv.getJSONArray("extRd");
				for(int idx=0; idx < ext.size(); idx++) {
					JSONObject o = ext.getJSONObject(idx);
					s.append(o.getString("name") + " ");
				}
			}
		} catch(Exception e) {
			System.out.println(mv);
		}
		return s.toString().trim();
	}
	private static String getDur(JSONObject mv) {
		return mv.getString("duration").trim();
	}
	private static String getDate(JSONObject mv) {
		return mv.getString("date").trim();
	}
	private static String getAr(JSONObject mv) {
		StringBuffer s = new StringBuffer();
		JSONArray ar = mv.getJSONArray("area");
		for(int idx=0; idx < ar.size(); idx++) {
			JSONObject o = ar.getJSONObject(idx);
			s.append(o.getString("name") + " ");
		}
		return s.toString().trim();
	}
	private static String getAc(JSONObject mv) {
		StringBuffer s = new StringBuffer();
		try{
			if (mv.getString("actor").length() > 0) {
				JSONArray ac = mv.getJSONArray("actor");
				if (ac.size() > 0)
					for(int idx=0; idx < ac.size(); idx++) {
						JSONObject o = ac.getJSONObject(idx);
						s.append(o.getString("name") + " ");
					}
			}
		} catch(Exception e) {
			System.out.println(mv);
		}
		return s.toString().trim();
	}

}



sjack
sjack
回复 @Timco : 这样用, 挻好用的 ,
Timco
Timco
你想表达什么?
13123123
13123123
?
0
叶汉城
叶汉城
对于  getJSONArray 后得到的值,貌似没有一个现成的函数可以将成解析成Bean,要自己手动将其组装;这是不是设计上有缺陷还是我自己用错了?
JSONObject obj = JSON.parseObject(response2.getMsg());
		JSONArray jsonArray = obj.getJSONObject("jingdong_ware_basebook_get_responce").getJSONArray("BookEntity");
		for(int i = 0 ;i<jsonArray.size();i++) {
			BookEntity bookEntity = jsonArray.getJSONObject(i).getObject("book_info",BookEntity.class);
			System.out.println(jsonArray.getJSONObject(i).getJSONObject("book_info").get("bar_code"));
			System.out.println(bookEntity.getBookInfo().getBarCode());
		}
{
    "jingdong_ware_basebook_get_responce": {
        "code": "0",
        "BookEntity": [
            {
                "book_info": {
                    "bar_code": "9787508644172",
                    "batch_no": "1",
                    "china_catalog": "G131.3",
                    "editer": "苏静",
                    "format": "16开",
                    "isbn": "9787508644172",
                    "language": "中文",
                    "pack_num": "0",
                    "packages": "平装",
                    "pages": "188",
                    "papers": "轻型纸",
                    "print_no": "1",
                    "print_time": "2014-02-01",
                    "publish_time": "2014-02-01",
                    "publishers": "中信出版社"
                },
                "sku_id": 11408042
            }
        ]
    }
}


得到的bookEntity是空的





0
叶汉城
叶汉城
JSONObject jsonObject  = jsonArray.getJSONObject(i).getJSONObject("book_info");
			BookInfo bookInfo = JSON.parseObject(jsonObject.toJSONString(), BookInfo.class);

后续尝试发现,如果jsonObject是精简的Bean(不包含其它的Bean),则可以直接将其转换成JavaBean。因此我的想法是,如果想完成一个嵌套Bean的转换工作,则只能从最底层开始实现,然后将其Set到最顶层的Bean中。



sjack
sjack
是的,精简的是可以直接转的,我上面这样的也可以解析,优点是相对更灵活
返回顶部
顶部