package com.norteksoft.product.util; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.CollectionType; import com.fasterxml.jackson.databind.type.MapType; import com.fasterxml.jackson.databind.type.TypeFactory; import com.norteksoft.mms.form.dao.GeneralDao; import com.norteksoft.mms.form.entity.ListColumn; import com.norteksoft.mms.form.entity.ListView; import com.norteksoft.mms.form.enumeration.DataType; import com.norteksoft.mms.form.service.FormHtmlParser; import com.norteksoft.mms.form.service.ListViewManager; import com.norteksoft.product.web.struts2.Struts2Utils; public class JsonParser { private static Log logger = LogFactory.getLog(JsonParser.class); private static final String DATA_FORMART = "yyyy-MM-dd"; private static final String TIME_FORMART = "yyyy-MM-dd HH:mm"; /** * 表单页面中有子表表格时,保存主表单时获得子表格中所有字段值并保存,此处解析字段值 * 只有一个子表时 * 解析字符串例如:[{"id":"52521","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"汤祁中的用车申请"},{"id":"76991","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"76835","useType":"短途","deptCheckResult":"张君正","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"何庆的用车申请"},{"id":"75200","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"76235","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"91716","useType":"短途","deptCheckResult":"","officeCheckResult":"","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"108380","useType":"短途","deptCheckResult":"","officeCheckResult":"","leaderCheckResult":"","isDirectAssign":"是","applicationTheme":"王滨的用车申请"}];aa=[{"a":"1","b":"2"}] * @return List<Map<String,Object>>,List存放实体对象的集合,Map<String,Object>的key为字段名称,value为字段值, */ @SuppressWarnings("unchecked") public static List<Object> getFormTableDatas(Class classObj){ String value=Struts2Utils.getParameter("subTableVals"); // String value="carUseApplication=[{\"id\":\"76235\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"91716\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"108380\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"52521\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"汤祁中的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"76991\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"112366\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"76835\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"张君正\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"何庆的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"75200\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}}]"; List<Object> list=new ArrayList<Object>(); String indexname=value.substring(0, value.indexOf("=")).split(":")[1]; String jsonString=value.substring(value.indexOf("=")+1,value.length()); jsonString=PageUtils.disposeSpecialCharacter(jsonString); if(jsonString!=null&&StringUtils.isNotEmpty(jsonString.toString())){ list= getValue(jsonString,classObj,indexname); } return list; } /** * 表单页面中有子表表格时,保存主表单时获得子表格中所有字段值并保存,此处解析字段值 * 考虑到一个表单页面可能有多个子表,所以有以下解法 * 解析字符串例如:carUseApplication=[{"id":"52521","useType":{"value":"短途","datatype":"STRING"},"deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"汤祁中的用车申请"},{"id":"76991","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"76835","useType":"短途","deptCheckResult":"张君正","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"何庆的用车申请"},{"id":"75200","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"76235","useType":"短途","deptCheckResult":"","officeCheckResult":"王滨","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"91716","useType":"短途","deptCheckResult":"","officeCheckResult":"","leaderCheckResult":"","isDirectAssign":"否","applicationTheme":"王滨的用车申请"},{"id":"108380","useType":"短途","deptCheckResult":"","officeCheckResult":"","leaderCheckResult":"","isDirectAssign":"是","applicationTheme":"王滨的用车申请"}];aa=[{"a":"1","b":"2"}] * @return Map<String,List<Map<String,Object>>> :key 为集合字段名;value为List<Map<String,Object>>,List存放实体对象的集合,Map<String,Object>的key为字段名称,value为字段值, */ @SuppressWarnings("unchecked") public static Map<String,List<Object>> getAllFormTableDatas(Class classObj){ String values=Struts2Utils.getParameter("subTableVals"); // String values="carUseApplication=[{\"id\":\"76235\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"91716\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"108380\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"52521\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"汤祁中的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"76991\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"112366\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"76835\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"张君正\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"何庆的用车申请\",\"datatype\":\"TEXT\"}},{\"id\":\"75200\",\"useType\":{\"value\":\"短途\",\"datatype\":\"TEXT\"},\"deptCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"officeCheckResult\":{\"value\":\"王滨\",\"datatype\":\"TEXT\"},\"leaderCheckResult\":{\"value\":\"\",\"datatype\":\"TEXT\"},\"isDirectAssign\":{\"value\":\"false\",\"datatype\":\"BOOLEAN\"},\"applicationTheme\":{\"value\":\"王滨的用车申请\",\"datatype\":\"TEXT\"}}]"; Map<String,List<Object>> result=new HashMap<String,List<Object>>(); String[] vals=values.split(";"); for(String valStr:vals){ String[] arr=valStr.split("="); String field=arr[0].split(":")[0]; String indexname=arr[0].split(":")[1]; String val=arr[1]; if(val!=null&&StringUtils.isNotEmpty(val.toString())){ List<Object> list=getValue(val,classObj,indexname); result.put(field, list); } } return result; } @SuppressWarnings("unchecked") private static List<Object> getValue(String jsonString,Class classObj,String indexname){ List<Object> list=new ArrayList<Object>(); GeneralDao generalDao = (GeneralDao) ContextUtils.getBean("generalDao"); try{ MapType mt = TypeFactory.defaultInstance().constructMapType( HashMap.class, String.class, ColunmModule.class); CollectionType ct = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, mt); List<Map<String, ColunmModule>> objs = json2Object(ct, jsonString); int index = 0; Object entity=null; for(Map<String, ColunmModule> map : objs){ index++; Object idObj=map.get("id").getValue(); if(idObj==null||StringUtils.isEmpty(idObj.toString())){ entity=classObj.newInstance(); }else{ entity=generalDao.getObject(classObj.getName(), Long.parseLong(idObj.toString())); } Set<String> fields=map.keySet(); for(String field : fields){ ColunmModule mod = map.get(field); if(!"id".equals(field)){ if(shouldSaveValue(map,field)){ Object valObj=getObjectValue(mod.getValue(), mod.getDatatype(), mod.getClassname()); if(valObj!=null){ if("".equals(valObj)){ PropertyUtils.setProperty(entity, field, null); }else{ BeanUtils.copyProperty(entity, field, valObj); } }else{ if(DataType.DATE.toString().equals(mod.getDatatype())||DataType.TIME.toString().equals(mod.getDatatype())){//当是Date类型时copyProperty对应空值null的保存有异常,所以用以下方法 PropertyUtils.setProperty(entity, field, valObj); }else{ BeanUtils.copyProperty(entity, field, valObj); } } } } } //设置显示顺序 if(!indexname.equals("false")){ BeanUtils.copyProperty(entity, indexname, index); } list.add(entity); } }catch (Exception e) { } return list; } /** * 是否需要保存值 * @return true为需要,false为不需要,只有当是“引用类型"的"某个字段"时不需要保存 */ private static boolean shouldSaveValue(Map<String, ColunmModule> map,String fieldName){ if(fieldName.contains(".")){ String field=fieldName.substring(0, fieldName.lastIndexOf("."));//aa.bb.cc.dd,获得aa.bb.cc(该字段需要在字段信息列表中设为引用) Set<String> referenceNames=getReferenceNames(map); if(referenceNames.contains(field)){ return false; } } return true; } private static Set<String> getReferenceNames(Map<String, ColunmModule> map){ Set<String> referenceNames=new HashSet<String>(); Set<String> fields=map.keySet(); for(String field : fields){ ColunmModule mod = map.get(field); if(DataType.REFERENCE.toString().equals(mod.getDatatype())){ referenceNames.add(field); } } return referenceNames; } /** * 获得colModel对应的值 * @param entity * @return */ public static String getRowValue(Object entity){ String listCode=Struts2Utils.getParameter("_list_code"); ListViewManager listViewManager = (ListViewManager) ContextUtils.getBean("listViewManager"); ListView listView=listViewManager.getListViewByCode(listCode); List<ListColumn> columns=listView.getColumns(); FormHtmlParser formHtmlParser = (FormHtmlParser) ContextUtils.getBean("formHtmlParser"); return formHtmlParser.getScriptObject(entity,columns); } public static Object getObjectValue(String value,String datatype,String className){ try { Object valObj=value; if("DATE".equals(datatype)||"TIME".equals(datatype)){ if(StringUtils.isEmpty(value))return null; valObj=getDate(value,datatype); }else if("REFERENCE".equals(datatype)){ if("_temporary".equals(value)){//列表管理/字段信息/对应字段列为“占位符”时的保存 valObj=null; }else{ valObj=getReferenceObject(value, className); } }else if("ENUM".equals(datatype)){ valObj=getEnum(value, className); } return valObj; } catch (Exception e) { } return null; } private static Date getDate(String value,String datatype){ try { if(value!=null){ if(datatype.equals("DATE")){ SimpleDateFormat df = new SimpleDateFormat(DATA_FORMART); return df.parse(value); }else if(datatype.equals("TIME")){ SimpleDateFormat df = new SimpleDateFormat(TIME_FORMART); return df.parse(value); } } } catch (Exception e) { } return null; } public static Object getEnum(String value,String className){ try { if(StringUtils.isNotEmpty(className)){ Object[] objs = Class.forName(className).getEnumConstants(); for(Object obj : objs){ if(obj.toString().equals(value.toString())){ return obj; } } } }catch (Exception e) { } return null; } /** * 获得映射的实体 * @param value * @param className * @return */ private static Object getReferenceObject(String value,String className){ try { if(StringUtils.isNotEmpty(className)){ GeneralDao generalDao = (GeneralDao) ContextUtils.getBean("generalDao"); Object entity=generalDao.getObject(className,Long.parseLong(value)); return entity; } }catch (Exception e) { } return null; } protected final static ObjectMapper defaultMapper;//= new ObjectMapper(); static{ defaultMapper = new ObjectMapper(); defaultMapper.configure(Feature.ALLOW_SINGLE_QUOTES, true); defaultMapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); } /** * 将对象转换为JSON串 * @param obj * @return */ public static String object2Json(Object obj){ defaultMapper.setDateFormat(new SimpleDateFormat(DATA_FORMART)); return write(obj); } public static String object2Json(Object obj, String dataFormart){ defaultMapper.setDateFormat(new SimpleDateFormat(dataFormart)); return write(obj); } /** * 将JSON串转换为Map * @param keyType * @param valueType * @param json * @return */ public static <K,V> Map<K,V> json2Map(Class<K> keyType, Class<V> valueType, String json){ MapType mt = TypeFactory.defaultInstance().constructMapType( HashMap.class, keyType, valueType); try { return defaultMapper.readValue(json, mt); } catch (JsonParseException e) { logger.error(e, e); throw new RuntimeException("JsonParseException", e); } catch (JsonMappingException e) { logger.error(e, e); throw new RuntimeException("JsonMappingException", e); } catch (IOException e) { logger.error(e, e); throw new RuntimeException("IOException", e); } } /** * 将JSON串转换为List * @param elementType List元素类型 * @param json 需转换的JSON * @return */ public static <T> List<T> json2List(Class<T> elementType, String json){ CollectionType ct = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, elementType); return json2Object(ct, json); } public static <T> T json2Object(JavaType valueType, String json){ defaultMapper.setDateFormat(new SimpleDateFormat(DATA_FORMART)); try { return (T)defaultMapper.readValue(json, valueType); } catch (JsonParseException e) { logger.error(e, e); throw new RuntimeException("JsonParseException", e); } catch (JsonMappingException e) { logger.error(e, e); throw new RuntimeException("JsonMappingException", e); } catch (IOException e) { logger.error(e, e); throw new RuntimeException("IOException", e); } } public static <T> T json2Object(Class<T> valueType, String json){ defaultMapper.setDateFormat(new SimpleDateFormat(DATA_FORMART)); try { return defaultMapper.readValue(json, valueType); } catch (JsonParseException e) { logger.error(e, e); throw new RuntimeException("JsonParseException", e); } catch (JsonMappingException e) { logger.error(e, e); throw new RuntimeException("JsonMappingException", e); } catch (IOException e) { logger.error(e, e); throw new RuntimeException("IOException", e); } } private static String write(Object obj){ try { return defaultMapper.writeValueAsString(obj); } catch (JsonGenerationException e) { logger.error(e, e); throw new RuntimeException("JsonGenerationException", e); } catch (JsonMappingException e) { logger.error(e, e); throw new RuntimeException("JsonMappingException", e); } catch (IOException e) { logger.error(e, e); throw new RuntimeException("IOException", e); } } } class ColunmModule{ private String value; private String datatype; private String classname; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getDatatype() { return datatype; } public void setDatatype(String datatype) { this.datatype = datatype; } public String getClassname() { return classname; } public void setClassname(String classname) { this.classname = classname; } @Override public String toString() { return "ColunmModule [classname=" + classname + ", datatype=" + datatype + ", value=" + value + "]"; } }