封装 转换json bean

json转换工具类,现在上网搜下,能找到几个,包括google的 gson。不过转换时,总有一些值并不能按自己需求来转换,特别是用户有订制时。为了达到这个要求,下面是我自己实现的一个类。

 

/**
 * 
 */
package com.cloudsea.sys.utils.commonutils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import com.cloudsea.sys.entity.BaseEntity;
import com.cloudsea.sys.entity.Resource;
import com.cloudsea.sys.entity.Role;
import com.cloudsea.sys.entity.User;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * @author zhangxiaorong
 * 2014-6-29
 */
public class JsonFormatBean<T> {

 

//hashCodeMap属性保存此对象转成json后的值,因为有一些属性值对象会被多次个地方引用,所以只需要转换一次,后面可以直接从这个map中取,而为了保证对象的唯一,用hashCode码做为key

 //map.key:hashCode   map.value:jsonobj
 private Map<Integer, Object> hashCodeMap = new HashMap<Integer, Object>();
 
 //指定转换日期格式
 private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
 //指定一些类型的值,用自定义转换方法,FormateByUser接口指定自指定转换方法,这个是用户自己实现的
 private Map<Class<?>, FormateByUser> formateByUserMap = new HashMap<Class<?>, FormateByUser>();
 
 //哪些属性不转换
 private Map<String, Object> unFormateFields = new HashMap<String, Object>();
 
 
 
 //转换子属性深度,比如像aa.bb.cc.dd结构 
 private int formateDepth = 3;
 
 private int currentDepth = 0;



 public void setFormateDepth(int formateDepth) {
  this.formateDepth = formateDepth;
 }
 public SimpleDateFormat getDateFormat() {
  return dateFormat;
 }
 public void setDateFormat(SimpleDateFormat dateFormat) {
  this.dateFormat = dateFormat;
 }
 public Map<String, Object> getUnFormateFields() {
  return unFormateFields;
 }
 public void setUnFormateFields(Map<String, Object> unFormateFields) {
  this.unFormateFields = unFormateFields;
 }
 public Map<Class<?>, FormateByUser> getFormateByUserMap() {
  return formateByUserMap;
 }
 public void setFormateByUserMap(Map<Class<?>, FormateByUser> formateByUserMap) {
  this.formateByUserMap = formateByUserMap;
 }
 
 
 
 public JSONArray toJSONArray(Collection<T> entityList){
  JSONArray jsonAarry = new JSONArray();
  if (entityList != null && entityList.size() > 0)
   for (T obj : entityList)
    jsonAarry.add(this.toJSON(obj)); 
  return jsonAarry;
 }
 
 
 
 
 public JSONObject toJSON(T t) {
  return toJSON(t, true);
 }

//此方法可重写,默认获取的是对象本身所有的属性值,如果我们还需要取取父对象属性的值,或者无视一些属性值,我们只能自定义这个方法了,比如我后面的例子,用的user对象没有id属性,而是继承了BaseEntity的id。
 public Field[] getDeclaredFields(Object t){
  return t.getClass().getDeclaredFields();
 }
 
 private JSONObject toJSON(Object t, boolean isbegin) {
  
  if (isbegin == true)
   hashCodeMap.clear();
  
  if (existObject(t))
   return (JSONObject) hashCodeMap.get(t.hashCode());
  
  JSONObject jsonObj = new JSONObject();
  hashCodeMap.put(t.hashCode(), jsonObj);
  
  try {

   

   if (Map.class.isAssignableFrom(t.getClass())){

    
    Map<Object, Object> map = (Map<Object, Object>) t;
    if (map.size() == 0)
     return jsonObj;
    for (Entry<Object, Object> entry : map.entrySet()){
     Object fieldValue = entry.getValue();
     Object fieldName = entry.getKey();
      
     if (fieldValue == null)
      continue;
     
     Object val = parseVal(fieldValue, fieldValue.getClass());
     jsonObj.put(fieldName, val);
    }
    return jsonObj;
    
   } else{
    
    Field[] fields = getDeclaredFields(t);
    sortFields(fields);
    
    for (int i = 0; i < fields.length; i++){
     
     String fieldName = fields[i].getName();
     fields[i].setAccessible(true);
     Object fieldValue = fields[i].get(t);
     
     if (fieldValue == null)
      continue;
     
     Object val = parseVal(fieldValue, fields[i].getType());
     jsonObj.put(fieldName, val);
    }
   }
    
  } catch (IllegalArgumentException e) {
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return jsonObj;
 }
 
 private Object parseVal(Object fieldValue, Class<?> type) throws Exception {
  
  for (Entry<Class<?>, FormateByUser> entry : formateByUserMap.entrySet())
   if (entry.getKey() == type)
    return entry.getValue().formate(fieldValue);
  
  if (isBaseType(type))
   return fieldValue;
  
  else if (isTimestampType(type))
   return dateFormat.format(((Timestamp)fieldValue).getTime());
  
  else if (isDateType(type))
   return dateFormat.format(fieldValue);
  
  else if (Collection.class.isAssignableFrom(type)){
   
   if (existObject(fieldValue))
    return hashCodeMap.get(fieldValue.hashCode());
   
   Collection<?> col = (Collection<?>) fieldValue;
   
   if (col.size() == 0)
    return null;
    
   else {
    JSONArray jsonAarry = new JSONArray();
    
    Iterator<?> it = col.iterator();
    element:
     while (it.hasNext()){
      
      Object entity = it.next();
      if (existObject(entity)){
       jsonAarry.add(hashCodeMap.get(entity.hashCode()));
       continue element;
      }
      
      JSONObject obj = null;
      if (currentDepth < formateDepth){
       currentDepth++;
       obj = this.toJSON(entity, false);
      }
      jsonAarry.add(obj);
      hashCodeMap.put(entity.hashCode(), obj);
     }
    
    hashCodeMap.put(col.hashCode(), jsonAarry);
    return jsonAarry;
   }
  }
  
  else {
   if (!existObject(fieldValue)){
    JSONObject obj = null;
    if (currentDepth < formateDepth){
     currentDepth++;
     obj = this.toJSON(fieldValue, false);
    }
    hashCodeMap.put(fieldValue.hashCode(), obj);
    return obj;
   } else{
    return hashCodeMap.get(fieldValue.hashCode());
   }
  }
 }
 
 /**
  * 把集合放在后面,把非集合属性放前面
  * hashcodelist 是用来判断,不让整个Bean中的属性和子属性中,有重复的对象存入。
  * 这样各层的属性值如果是同样的对象,就可以先执行放到上层属性中,而不会放到下层的集合中
  */
 private static void sortFields(Field[] fields) {
  if (fields.length == 0)
   return;
  
  for (int i = 0; i < fields.length - 1; i++){
   if (Collection.class.isAssignableFrom(fields[i].getType())){
    Field temp = fields[i];
    for (int j = i + 1; j < fields.length; j++)
     fields[j-1] = fields[j];
    fields[fields.length-1] = temp;
   }
  }
 }

private boolean existObject(Object obj) {
  
  if (obj == null)
   return true;
  for (Integer val :hashCodeMap.keySet())
   if (val.hashCode() == obj.hashCode())
    return true;
  return false;
 }

private static boolean isDateType(Class<?> claz) {
  
  if(claz == null)
   return false;

if (claz.getName().equals(java.sql.Date.class.getName()))
   return true;

if (claz.getName().equals(java.util.Date.class.getName()))
   return true;
  
  return false;
 }
 
 private static boolean isTimestampType(Class<?> claz) {
  if(claz == null)
   return false;

if (claz.getName().equals(java.sql.Timestamp.class.getName()))
   return true;
  
  return false;
 }



 private static boolean isBaseType(Class<?> o) {
  
  if(o == null)
   return true;
  
  String className = o.getName();
  if (className == null)
   return false;
  if (o.isPrimitive())
   return true;
  if (o == Byte.class)
   return true;
  if (o == Character.class)
   return true;
  if (o == Short.class)
   return true;
  if (o == Integer.class)
   return true;
  if (o == Long.class)
   return true;
  if (o == Float.class)
   return true;
  if (o == Double.class)
   return true;
  if (o == Boolean.class)
   return true;
  if (o == String.class)
   return true;
  if (o == StringBuffer.class)
   return true;
  if (o == StringBuilder.class)
   return true;
  if (o == BigInteger.class)
   return true;
  if (o == BigDecimal.class)
   return true;
  return false;
 }
 

 

 

//这里是测试代码,测试代码需要一些实体类,在下面我帖出来
 public static void main(String[] args) {
  System.out.println("start JsonFormatBean");
  
  Resource res = new Resource();
  res.setResourceNo("setResourceNo");
  Resource resource = new Resource();
  resource.setId(3424l);
  resource.setParent(res);
  
  Set<Resource> resources = new HashSet<Resource>();
  resources.add(resource);
  
  Role role = new Role();
  role.setId(22l);
  role.setResources(resources);
  
  Set<Role> roles = new HashSet<Role>();
  roles.add(role);
  
  User u = new User();
  u.setLoginName("setLoginName");
  u.setCreateTime(new Date());
  u.setId(11l);
  u.setRoles(roles);
  u.setRoles(roles);
  
  JsonFormatBean<BaseEntity> f = new JsonFormatBean<BaseEntity>(){
   public Field[] getDeclaredFields(Object t) {
    Field[] fs = super.getDeclaredFields(t);
    try {
     Field f = t.getClass().getSuperclass().getDeclaredField("id");
     System.arraycopy(new Field[]{f}, 0, fs, 0, 1);
    } catch (Exception e) {
     e.printStackTrace();
    } 
    return fs;
   }
  };
  f.getFormateByUserMap().put(String.class, new FormateByUser(){
   public Object formate(Object obj) {
    return "FormateByUser:" + obj;
   }
  });
  f.getFormateByUserMap().put(Date.class, new FormateByUser(){
   public Object formate(Object obj) {
    return "2000-01-01";
   }
  });

f.setFormateDepth(5);
  JSONObject jobj = f.toJSON(u);
  System.out.println(jobj);
  //运行打印结果str+shift+F,效果如下图


 }
 
 public interface FormateByUser{
  Object formate(Object obj) throws Exception;
 }
 
}



/测试需要的实体类在这里帖出来,注解和不用的类可以删了//

package com.cloudsea.sys.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.MappedSuperclass;
import javax.persistence.SequenceGenerator;

/**
 * 所有实体对象的基类
 * 如果数据库表没有主键,可以用实体类中所有的属性做成组合主键
 */
@MappedSuperclass
public class BaseEntity implements Serializable{

 private static final long serialVersionUID = 743946443592736083L;

 private Long id;
//
// private Date createTime;//
// 
// private Date lastModifyTime;//

 private String description;// 

 private String enable;//

 
 @Id
 
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// @GenericGenerator(name = "id_increment", strategy = "increment")
 
 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ")
 @SequenceGenerator(name = "SEQ", sequenceName = "SEQ_SYS_BASE")
 
 @Column(name = "ID", unique = true, nullable = false, length = 20)  
 public Long getId() {
  return id;
 }
 public void setId(Long id) {
  this.id = id;
 }
 
//    @Column(name = "CREATE_TIME", nullable = true, length = 30)
//    public Date getCreateTime() {
//  return createTime;
// }
// public void setCreateTime(Date createTime) {
//  this.createTime = createTime;
// }
//
//    @Column(name = "Last_Modify_TIME", nullable = true, length = 30)
// public Date getLastModifyTime() {
//  return lastModifyTime;
// }
// public void setLastModifyTime(Date lastModifyTime) {
//  this.lastModifyTime = lastModifyTime;
// }

    @Column(name = "Description", nullable = true, length = 100)
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 } 
 
    @Column(name = "ENABLE", nullable = true, length = 1)
 public String getEnable() {
  return enable;
 }
 public void setEnable(String enable) {
  this.enable = enable;
 }

}



package com.cloudsea.sys.entity;



import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;



/**
 * 
 * @author zhangxiaorong
 * @date 2014-8-15
 */
@Entity
@Table(name="SM_RESOURCE") 
public class Resource extends BaseEntity {

 private static final long serialVersionUID = 8825386206796892840L;
 
 private String resourceNo;//
 
 private String resourceName;// 
 
 private int resourceType;// 可分菜单,按钮等
 
 private String URL;// 
 
 private Resource parent;// 
   
 private Set<Resource> children = new HashSet<Resource>();//
 
 private Set<Role> roles = new HashSet<Role>(); //
 
 private Set<Group> groups = new HashSet<Group>();//

 private Set<Region> regions = new HashSet<Region>();//
 
 
    @Column(name = "RESOURCE_NO", nullable = true, length = 20, unique = true)
 public String getResourceNo() {
  return resourceNo;
 }
 public void setResourceNo(String resourceNo) {
  this.resourceNo = resourceNo;
 }
 
    @Column(name = "RESOURCE_NAME", nullable = false, length = 50)
 public String getResourceName() {
  return resourceName;
 }
 public void setResourceName(String resourceName) {
  this.resourceName = resourceName;
 }
 
    @Column(name = "RESOURCE_TYPE", nullable = false, length = 10)
 public int getResourceType() {
  return resourceType;
 }
 public void setResourceType(int resourceType) {
  this.resourceType = resourceType;
 }
 
    @Column(name = "URL", nullable = true, length = 80)
 public String getURL() {
  return URL;
 }
 public void setURL(String uRL) {
  URL = uRL;
 }
 
 @ManyToOne(fetch=FetchType.LAZY, optional=true)
 @JoinColumn (name = "PARENT_ID" )//
 public Resource getParent() {
  return parent;
 }
 public void setParent(Resource parent) {
  this.parent = parent;
 }
 
 @ManyToMany(targetEntity=Role.class, mappedBy="resources",  fetch = FetchType.LAZY)
 public Set<Role> getRoles() {
  return roles;
 }
 public void setRoles(Set<Role> roles) {
  this.roles = roles;
 }
 
 @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
 @OrderBy(value="id ASC")
 public Set<Resource> getChildren() {
  return children;
 }
 public void setChildren(Set<Resource> children) {
  this.children = children;
 }

 @ManyToMany(targetEntity=Group.class, mappedBy="resources",  fetch = FetchType.LAZY)
 public Set<Group> getGroups() {
  return groups;
 }
 public void setGroups(Set<Group> groups) {
  this.groups = groups;
 }
 
 @ManyToMany(targetEntity=Region.class, mappedBy="resources",  fetch = FetchType.LAZY)
 public Set<Region> getRegions() {
  return regions;
 }
 public void setRegions(Set<Region> regions) {
  this.regions = regions;
 }

}

 

 

package com.cloudsea.sys.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;



/**
 * 
 * @author zhangxiaorong
 * @date 2014-8-15
 */
@Entity
@Table(name="SM_ROLE") 
public class Role extends BaseEntity {
 
 private static final long serialVersionUID = -2975972272254401790L;
 
 private String roleNo; //
 
 private String roleName;// 
 
 private String roleType;
   
 private Set<User> users = new HashSet<User>();//
 
 private Set<Resource> resources = new HashSet<Resource>();//
 

    @Column(name = "ROLE_NO", nullable = false, length = 20, unique = true)
    public String getRoleNo() {
  return roleNo;
 }
 public void setRoleNo(String roleNo) {
  this.roleNo = roleNo;
 }
 
    @Column(name = "ROLE_NAME", nullable = false, length = 50, unique = true)
 public String getRoleName() {
  return roleName;
 }
 public void setRoleName(String roleName) {
  this.roleName = roleName;
 }
 
    @Column(name = "ROLE_Type", nullable = true, length = 30, unique = false)
 public String getRoleType() {
  return roleType;
 }
 public void setRoleType(String roleType) {
  this.roleType = roleType;
 }
 
 @ManyToMany(targetEntity=User.class, mappedBy="roles",  fetch = FetchType.LAZY)
 public Set<User> getUsers() {
  return users;
 }
 public void setUsers(Set<User> users) {
  this.users = users;
 }
 
 @ManyToMany(targetEntity = Resource.class, fetch = FetchType.LAZY)
 @JoinTable (name = "SM_ROLE_RESOURCE", 
             joinColumns = @JoinColumn (name = "ROLE_ID" ),//
    inverseJoinColumns = @JoinColumn (name = "RESOURCE_ID" ))//
 public Set<Resource> getResources() {
  return resources;
 }
 public void setResources(Set<Resource> resources) {
  this.resources = resources;
 }

}



 

package com.cloudsea.sys.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.JoinColumn;



/**
 * 
 * @author zhangxiaorong
 * @date 2014-8-15
 */
@Entity
@Table(name="SM_USER") 
public class User extends BaseEntity{
 
 private static final long serialVersionUID = -5976474144608010507L;

 private String userNo; //
 
 private String loginName;//
 
 private String password;//
 
 private String userName;//

 private Date createTime;//
 
 private Date lastModifyTime;// 
 
 private Date expireTime;// 
  
 private Set<Group> groups = new HashSet<Group>();//

 private Set<Region> regions = new HashSet<Region>();//
 
 private Set<Role> roles = new HashSet<Role>();//
 
 
 @Override  
 public int hashCode() {  
     return loginName.hashCode();  
 }  
 @Override  
 public boolean equals(Object obj) {  
     User user = (User)obj;  
     return this.loginName.equals(user.getLoginName());  
 } 
 
 
    @Column(name = "USER_NO", nullable = false, length = 15, unique = true)
 public String getUserNo() {
  return userNo;
 }
 public void setUserNo(String userNo) {
  this.userNo = userNo;
 }

    @Column(name = "LOGIN_NAME", nullable = false, length = 50, unique = true)
    public String getLoginName() {
  return loginName;
 }
 public void setLoginName(String loginName) {
  this.loginName = loginName;
 }

    @Column(name = "PASSWORD", nullable = false, length = 80)
    public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 
    @Column(name = "USER_NAME", nullable = false, length = 50)
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 
    @Column(name = "CREATE_TIME", nullable = true, length = 30)
    public Date getCreateTime() {
  return createTime;
 }
 public void setCreateTime(Date createTime) {
  this.createTime = createTime;
 }

    @Column(name = "Last_Modify_TIME", nullable = true, length = 30)
 public Date getLastModifyTime() {
  return lastModifyTime;
 }
 public void setLastModifyTime(Date lastModifyTime) {
  this.lastModifyTime = lastModifyTime;
 }
 
    @Column(name = "expire_Time", nullable = true, length = 30)
 public Date getExpireTime() {
  return expireTime;
 }
 public void setExpireTime(Date expireTime) {
  this.expireTime = expireTime;
 }
 
 @ManyToMany(targetEntity = Region.class, fetch = FetchType.EAGER)
 @JoinTable (name = "SM_USER_REGION", 
             joinColumns = @JoinColumn (name = "USER_ID" ),//
    inverseJoinColumns = @JoinColumn (name = "REGION_ID" ))//
 public Set<Region> getRegions() {
  return regions;
 }
 public void setRegions(Set<Region> regions) {
  this.regions = regions;
 }
 
 @ManyToMany(targetEntity = Role.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
 @JoinTable (name = "SM_USER_ROLE", 
             joinColumns = @JoinColumn (name = "USER_ID" ),//
    inverseJoinColumns = @JoinColumn (name = "ROLE_ID" ))//
 public Set<Role> getRoles() {
  return roles;
 }

 public void setRoles(Set<Role> roles) {
  this.roles = roles;
 }
 
 @ManyToMany(targetEntity = Group.class, fetch = FetchType.EAGER)
 @JoinTable (name = "SM_USER_Group", 
             joinColumns = @JoinColumn (name = "USER_ID" ),//
    inverseJoinColumns = @JoinColumn (name = "Group_ID" ))//
 public Set<Group> getGroups() {
  return groups;
 }
 public void setGroups(Set<Group> groups) {
  this.groups = groups;
 }
 
 @Transient
 public Role getRole() {
  if (roles != null && roles.size() > 0)
   return  roles.iterator().next();
  return null;
 }

}



 

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值