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;
}
}
封装 转换json bean
最新推荐文章于 2022-07-19 10:04:36 发布