/*
* 文件名称: JsonParser.java
* 版权信息: Copyright 2013-2014 chunchen technology Co., LTD. All right reserved.
* ----------------------------------------------------------------------------------------------
* 修改历史:
* ----------------------------------------------------------------------------------------------
* 修改原因: 新增
* 修改人员: zhangyz
* 修改日期: 2014-3-8
* 修改内容:
*/
package com.mfh.comn.net;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.util.TypeUtils;
import com.mfh.comn.bean.EntityWrapper;
import com.mfh.comn.code.bean.ParentChildItem;
import com.mfh.comn.net.data.IResponseData;
import com.mfh.comn.net.data.RspCodeDomain;
import com.mfh.comn.net.data.RspListBean;
import com.mfh.comn.net.data.RspQueryResult;
import com.mfh.comn.net.data.RspBean;
import com.mfh.comn.net.data.RspMap;
import com.mfh.comn.net.data.RspValue;
/**
* 负责对json格式的通讯数据包进行解析
* @author zhangyz created on 2014-3-8
*/
public class JsonParser extends BaseParser{
public final static String TAG_JSONSTR = "jsonStr";
public static SimpleDateFormat shortFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
public static SimpleDateFormat normalFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static SimpleDateFormat defaultFormat = shortFormat;
/**
* 把字符串解析成简单类型
* @param rawString
* @param beanClass
* @return
* @author zhangyz created on 2014-3-11
*/
private <T> RspValue<T> genSimpValue(String rawString, Class<T> beanClass) {
T value = TypeUtils.castToJavaBean(rawString, beanClass);
return new RspValue<T>(value);
/*if (beanClass.equals(String.class))
return (RspValue<T>) new RspValue<String>(rawString);
else if (beanClass.equals(Integer.class))
return (RspValue<T>) new RspValue<Integer>(Integer.parseInt(rawString));
else if (beanClass.equals(Long.class))
return (RspValue<T>) new RspValue<Long>(Long.parseLong(rawString));
else if (beanClass.equals(Date.class)) {
SimpleDateFormat format = new java.text.SimpleDateFormat(this.dataFormat);
try {
return (RspValue<T>) new RspValue<Date>(format.parse(rawString));
}
catch (ParseException e) {
throw new RuntimeException("不支持的日期字串:" + rawString);
}
}
else if (beanClass.equals(Short.class)) {
return (RspValue<T>) new RspValue<Short>(Short.parseShort(rawString));
}
else if (beanClass.equals(Double.class)) {
return (RspValue<T>) new RspValue<Double>(Double.parseDouble(rawString));
}
else if (beanClass.equals(Float.class)) {
return (RspValue<T>) new RspValue<Float>(Float.parseFloat(rawString));
}
else if (beanClass.equals(Timestamp.class)) {
return (RspValue<T>) new RspValue<Timestamp>(Timestamp.valueOf(rawString));
}
else
throw new RuntimeException("不支持的简单类型:" + beanClass.getName());*/
}
@Override
public <T> ResponseBody parser(String rawString, Class<T> beanClass, DateFormat dataFormat) {
if (dataFormat != null)//补丁
DefaultJSONParser.dateFormatPatternThread.set(dataFormat);
try {
ResponseBody ret = new ResponseBody();
System.out.print(String.format("Mfh: parser:%s", rawString));
JSONObject jsonObj = (JSONObject)JSON.parse(rawString);
//jsonObj = (JSONObject)jsonObj.get(TAG_MAINRESULT);//result部分直接为一级了。
//String head = jsonObj.getString(TAG_MAINHEADER);
if (jsonObj == null){
return ret;
}
Integer returnCode = jsonObj.getInteger(TAG_RESULTCODE);
if (returnCode != null)
ret.setRetCode(returnCode);
String returnInfo = jsonObj.getString(TAG_RESULTINFO);
ret.setReturnInfo(returnInfo);
//返回版本
Integer returnVersion = jsonObj.getInteger(TAG_VERSION);
if (returnVersion != null) {
ret.setVersion(returnVersion);
if (returnVersion.intValue() == 1) {
//补丁:更改响应中的日期格式
defaultFormat = normalFormat;
}
}
Object obj = jsonObj.get(TAG_MAINDATA);
if (obj != null) {
if (obj instanceof JSONObject){
System.out.print(String.format("Mfh: parser.data(JSONObject):%s", JSONObject.toJSONString(obj)));
JSONObject jsonData = (JSONObject)obj;//(JSONObject)jsonObj.getJSONObject(TAG_MAINDATA);
ret.setData(parseData(jsonData, beanClass));
}
else if (obj instanceof JSONArray) {
System.out.print(String.format("Mfh: parser.data(JSONArray):%s", JSONObject.toJSONString(obj)));
JSONArray array = (JSONArray)obj;
ret.setData(parseData(array, beanClass));
}
else {
System.out.print(String.format("Mfh: parser.data(JSONObject):%s", JSONObject.toJSONString(obj)));
ret.setData(genSimpValue(obj.toString(), beanClass));
}
}
return ret;
}
catch(Throwable ex) {
throw new RuntimeException("服务器返回数据格式出现错误:" + ex.getMessage(), ex);
}
}
@Override
public <T> ResponseBody parser(String rawString, Class<T> beanClass, String strDataFormat) {
return parser(rawString, beanClass, new SimpleDateFormat(strDataFormat));
}
@Override
public <T> ResponseBody parser(String rawString, Class<T> beanClass) {
DateFormat format = null;
return parser(rawString, beanClass, format);
}
@Override
public ResponseBody parser(String rawString) {
DateFormat format = null;
return parser(rawString, null, format);
}
private <T> IResponseData parseData(JSONArray array, Class<T> beanClass) {
RspListBean<T> beanList = new RspListBean<T>();
for (int ii = 0; ii < array.size(); ii++) {
JSONObject jsonData = array.getJSONObject(ii);
T bean = JSONObject.toJavaObject(jsonData, beanClass);
beanList.addBean(bean);
}
return beanList;
}
/**
* 解析具体的数据部分,data标签里面的:
* 第一种:{total:12,rows:[{....}]},其中total和rows都是关键字,查询结果集
* 第二种:{props:{key1:value1,key2:value2....},其中props是关键字,map类型
* 第三种:{prop1:value1,prop2:value2...},单值,纯bean
* 第四种:{val:.......},纯字符
* 第五种:{bean:{...},caption:{...}}
* 若混合存在还是比较难以分辨的
* @param jsonData
* @return 返回的结果数据
* @author zhangyz created on 2014-3-8
*/
private <T> IResponseData parseData(JSONObject jsonData, Class<T> beanClass) {
IResponseData responseData = null;
System.out.print(String.format("Mfh: parseData", JSONObject.toJSONString(jsonData)));
if (jsonData.containsKey(TAG_ROWS) && jsonData.containsKey(TAG_TOTAL)){//结果集
responseData = parseQueryResult(jsonData, beanClass);
}
else if (jsonData.containsKey(TAG_DATAPROPS)) {//hashMap
JSONObject jsonProps = (JSONObject)jsonData.get(TAG_DATAPROPS);
responseData = parsePorps(jsonProps);
}
else if (jsonData.containsKey(TAG_VAL)) {//单独值
responseData = genSimpValue(jsonData.getString(TAG_VAL), beanClass);
}
else if (jsonData.containsKey(TAG_BEAN) && jsonData.containsKey(TAG_CAPTION)) {//单独bean,但是属于EntityWrapper
//JSONObject wrapperJson = jsonData.getJSONObject(TAG_BEAN);
EntityWrapper<T> wrapper = parserEntityWrapper(jsonData, beanClass);
responseData = wrapper;
}
/*else if (jsonData.containsKey(TAG_DEEP_TYPE) && jsonData.containsKey(TAG_LEVEL_NUM)) {//编码
responseData = parentCodeDomain(jsonData, beanClass);
}*/
else if (beanClass == null){
//按map解析
responseData = parsePorps(jsonData);
}
else {
RspBean<T> bean = new RspBean<T>(JSONObject.toJavaObject(jsonData, beanClass));
System.out.print(String.format("Mfh: parseData(RspBean):%s", JSONObject.toJSONString(bean)));
responseData = bean;
}
return responseData;
/*RspMixData mixData = null;
int partSize = jsonData.size();
if (partSize > 1)
mixData = new RspMixData();
Iterator<String> iter = jsonData.keySet().iterator();
String key;
while (iter.hasNext()) {
key = iter.next();
if (key.equals(TAG_QUERYRESULT)) {
JSONObject jsonResult = (JSONObject)jsonData.get(key);
QueryResult<?> result = parseQueryResult(jsonResult, beanClass);
if (mixData != null)
mixData.setDataQueryResult(result);
responseData = result;
}
else if (key.equals(TAG_DATAPROPS)) {
JSONObject jsonProps = (JSONObject)jsonData.get(key);
RspMap rspMap = parsePorps(jsonProps);
if (mixData != null)
mixData.setDataKeyValue(rspMap);
responseData = rspMap;
}
}
if (mixData != null)
return mixData;
else
return responseData;*/
}
/**
* 解析Data里的属性参数
* @param jsonProps
* @param jsonProps
* @author zhangyz created on 2013-5-14
*/
private RspMap parsePorps(JSONObject jsonProps) {
RspMap ret = new RspMap();
Iterator<String> iter = jsonProps.keySet().iterator();
String key,value;
while (iter.hasNext()) {
key = iter.next();
value = jsonProps.getString(key);
ret.addDataParam(key, value);
}
return ret;
}
/**
* 解析查询输出部分
* @param jsonResult
* @author zhangyz created on 2013-5-14
*/
private <T> RspQueryResult<T> parseQueryResult(JSONObject jsonResult, Class<T> beanClass) {
RspQueryResult<T> result = new RspQueryResult<T>();
Long total = jsonResult.getLong(TAG_TOTAL);
if (total != null)
result.setTotalNum(total);
JSONArray dataArray = jsonResult.getJSONArray(TAG_ROWS);
JSONArray fieldArray = jsonResult.getJSONArray("head");
if (fieldArray != null) {//字段名和类型单独拿出来定义,如果存在的话
List<QfiledBase> fields = parseResultField(fieldArray);
result.setRowFields(fields);
}
result.setRowDatas(parseResultRows(dataArray, beanClass));
return result;
}
/**
*
* @param jsonRow
* @param beanClass
* @param <T>
* @return
*/
private <T> RspCodeDomain<T> parentCodeDomain(JSONObject jsonRow, Class<T> beanClass) {
RspCodeDomain<T> result = new RspCodeDomain<T>();
//Long total = jsonRow.getLong(TAG_JSONSTR)
JSONArray fieldArray = jsonRow.getJSONArray("head");
JSONArray dataArray = jsonRow.getJSONArray("options");
if (fieldArray != null) {
List<QfiledBase> fields = parseResultField(dataArray);
result.setRowFields(fields);
}
result.setRowDatas(parentChildItems(dataArray, beanClass));
return result;
}
/**
* 解析字段列表
* @param fieldArray
* @return
* @author zhangyz created on 2013-5-14
*/
private List<QfiledBase> parseResultField(JSONArray fieldArray) {
List<QfiledBase> fields = new ArrayList<QfiledBase> ();
JSONObject jsonObj;
QfiledBase field;
for (int ii = 0; ii < fieldArray.size(); ii++ ){
field = new QfiledBase();
jsonObj = fieldArray.getJSONObject(ii);
jsonObj = jsonObj.getJSONObject("field");
field.setName(jsonObj.getString("name"));
field.setCaption(jsonObj.getString("caption"));
fields.add(field);
}
return fields;
}
/**
* 解析出一个wrapperObject对象
* @param jsonRow
* @param beanClass
* @return
* @author zhangyz created on 2014-3-10
*/
@SuppressWarnings("unchecked")
private <T> EntityWrapper<T> parserEntityWrapper(JSONObject jsonRow, Class<T> beanClass) {
JSONObject jsonBean, jsonCaption;
T entity = null;
Map<String, String> map = null;
jsonBean = jsonRow.getJSONObject(TAG_BEAN);
jsonCaption = jsonRow.getJSONObject(TAG_CAPTION);
if (jsonBean == null) {
if (beanClass.equals(JSONObject.class))
entity = (T)jsonRow;//直接返回json对象
else
entity = JSONObject.toJavaObject(jsonRow, beanClass);//认为直接就是bean了,兼容老格式。
}
else {
if (beanClass.equals(JSONObject.class))
entity = (T)jsonRow;//直接返回json对象
else {
entity = JSONObject.toJavaObject(jsonBean, beanClass);
map = JSONObject.toJavaObject(jsonCaption, Map.class);
}
}
EntityWrapper<T> wrapper = new EntityWrapper<T>(entity, map);
return wrapper;
}
private <T> ParentChildItem<T> parserChildItem(JSONObject jsonRow, Class<T> beanClass) {
T entity = null;
entity = JSONObject.toJavaObject(jsonRow, beanClass);
ParentChildItem<T> childItem = new ParentChildItem<T>(entity);
return childItem;
}
/**
* 解析查询数据集--新版
* @param dataArray
* @param beanClass
* @return
* @author zhangyz created on 2014-3-8
*/
private <T> List<EntityWrapper<T>> parseResultRows(JSONArray dataArray, Class<T> beanClass){
List<EntityWrapper<T>> rows = new ArrayList<EntityWrapper<T>>();
try {
JSONObject jsonRow;
for (int ii = 0; ii < dataArray.size(); ii++) {
jsonRow = dataArray.getJSONObject(ii);
EntityWrapper<T> wrapper = parserEntityWrapper(jsonRow, beanClass);
rows.add(wrapper);
/*//第二种
entity = JSONObject.toJavaObject(jsonRow, beanClass);
rows.add(entity);*/
}
}
catch(Exception ex) {
throw new RuntimeException("解析数据失败:" + ex.getMessage(), ex);
}
return rows;
}
private <T> List<ParentChildItem<T>> parentChildItems(JSONArray dataArray, Class<T> beanClass) {
List<ParentChildItem<T>> rows = new ArrayList<ParentChildItem<T>>();
JSONObject jsonRow;
for (int ii = 0;ii < dataArray.size(); ii++) {
jsonRow = dataArray.getJSONObject(ii);
ParentChildItem<T> childItem = parserChildItem(jsonRow, beanClass);
rows.add(childItem);
}
return rows;
}
}