近期在项目中,有一些需要列转行操作的业务,界面侧呢,又需要做成无限动态的列扩展业务。基于此,前后端定义了统一规则,给到对应前端的json格式实现动态生成,字段名称全都统一规则column1到columnN;同理,前端向后端传递column1到columnN的json格式数据,后端通知指定得转换实体类,实体集合数据,做业务操作。所以编写了下面的实体类集合转json的列转行工具类和json转换指定实体类集合行转列工具类(主要应用了java的反射机制,期间参考了很多帖子学习后的实现的,如有摘录还望见谅,的确记不得是哪个帖子看到的了)。
一、依赖引入内容:
pom.xml中添加的依赖
<!-- add for json2column start -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- 功能更强大一些 -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ezmorph/ezmorph -->
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<!-- add for json2column end -->
二、辅助测试实体类:
Student.java(测试实体类)
import java.math.BigDecimal;
public class Student extends BaseEntry {
private String studentId;
private String studentName;
private BigDecimal studentAge;
private String studentSex;
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public BigDecimal getStudentAge() {
return studentAge;
}
public void setStudentAge(BigDecimal studentAge) {
this.studentAge = studentAge;
}
public String getStudentSex() {
return studentSex;
}
public void setStudentSex(String studentSex) {
this.studentSex = studentSex;
}
}
BaseEntry.java(测试实体类父类)
public class BaseEntry {
private String organizationId;
private String organizationName;
private String departmentId;
private String departmentName;
private String roleId;
private String roleName;
public String getOrganizationId() {
return organizationId;
}
public void setOrganizationId(String organizationId) {
this.organizationId = organizationId;
}
public String getOrganizationName() {
return organizationName;
}
public void setOrganizationName(String organizationName) {
this.organizationName = organizationName;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
三、下面是工具类主内容:
VoToJson.java(实体类集合转json的列转行工具类)
import net.sf.json.JSONObject;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.math.BigDecimal;
import java.util.*;
/**
* @author 龙小白
* @version 1.0
*/
public class VoToJson {
final static String BASE_COLUME = "colume";
public static void main(String[] args) {
Student student = new Student();
student.setStudentId("isID");
student.setStudentName("isName");
student.setStudentAge(new BigDecimal(19));
student.setStudentSex("2222");
student.setDepartmentId("1111");
student.setDepartmentName("isName");
student.setOrganizationId("222222");
student.setOrganizationName("isOrganiName");
Student student1 = new Student();
student1.setStudentId("isID1");
student1.setStudentName("isName1");
student1.setStudentAge(new BigDecimal(191));
student1.setStudentSex("22221");
student1.setDepartmentId("11112");
student1.setDepartmentName("isName1");
student1.setOrganizationId("2222221");
student1.setOrganizationName("isOrganiName1");
List<Student> students = new ArrayList<Student>();
students.add(student);
students.add(student1);
List<Object> obj = convert(students);
try {
List<JSONObject> jsonObjectList = voToJson(obj, false);
System.out.println("jsonObjectList.toString() = " + jsonObjectList.toString());
for(JSONObject jsonObject : jsonObjectList){
Iterator<String> iterator = jsonObject.keys();
while (iterator.hasNext()){
String key = iterator.next();
String value = jsonObject.get(key).toString();
System.out.println("key : " + key + ", value" + value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 转换方法入口
* @param list 要转换的集合
* @param isHaveSuper 是否读取父类的属性
* @return
*/
public static List<JSONObject> getVoToJson(List list, boolean isHaveSuper){
List<Object> obj = convert(list);
List<JSONObject> jsonObjectList = null;
try {
jsonObjectList = voToJson(obj, false);
} catch (Exception e) {
e.printStackTrace();
}
return jsonObjectList;
}
/**
* 将首字符转换成大写
* @param name
* @return
*/
public static String upperCaseFirst(String name){
return name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
}
/**
* 合并数据,生成新格式
* @param objects
* @param isHaveSuper 判断是否要将父类的字段也生成到JSON中
* @param <T>
* @return
* @throws Exception
*/
public static <T>List voToJson(List<T> objects, boolean isHaveSuper) throws Exception {
//判断objects集合是否为空,如果为空,则直接返回null
if(objects == null || objects.size() ==0){
return null;
}
//通过集合的第一个属性,获取基础信息
List<Field> fieldList = getFiledsInfo(objects.get(0).getClass(), isHaveSuper);
//获取集合size
int fieldSize = fieldList.size();
//初始化JSONObject数组对象
List<JSONObject> jsonpObjectList = generatorJsonObject(fieldSize);
//获取要转换的类的个数
int len = objects.size();
for (int x = 0; x < len; x++) {
Object model = objects.get(x);
Class<?> clazz = model.getClass();
List<Field> fields = getFiledsInfo(model.getClass(), isHaveSuper);
String modelName[] = new String[fieldSize];
String modelType[] = new String[fieldSize];
for (int i = 0; i < fieldSize; i++) {
Field field = fields.get(i);
// 获取属性的名字
String name = field.getName();
modelName[i] = name;
// 获取属性类型
String type = field.getGenericType().toString();
modelType[i] = type;
//关键。。。可访问私有变量
field.setAccessible(true);
// 将属性的首字母大写
name = upperCaseFirst(name);
if (type.equals("class java.lang.String")) {
// 如果type是类类型,则前面包含"class ",后面跟类名
Method m = model.getClass().getMethod("get" + name);
// 调用getter方法获取属性值
String value = (String) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
if(type.equals("class java.math.BigDecimal")){
Method m = model.getClass().getMethod("get" + name);
BigDecimal value = (BigDecimal) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
if (type.equals("class java.lang.Integer")) {
Method m = model.getClass().getMethod("get" + name);
Integer value = (Integer) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
if (type.equals("class java.lang.Short")) {
Method m = model.getClass().getMethod("get" + name);
Short value = (Short) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
if (type.equals("class java.lang.Double")) {
Method m = model.getClass().getMethod("get" + name);
Double value = (Double) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
if (type.equals("class java.lang.Boolean")) {
Method m = model.getClass().getMethod("get" + name);
Boolean value = (Boolean) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
if (type.equals("class java.util.Date")) {
Method m = model.getClass().getMethod("get" + name);
Date value = (Date) m.invoke(model);
if (value != null) {
jsonpObjectList.get(i).put(VoToJson.BASE_COLUME + x,value);
}
}
}
}
return jsonpObjectList;
}
public static List<Object> convert(List list) {
return list;
}
/**
* 合并多个数组
* @param first
* @param rest
* @param <T>
* @return
*/
public static <T> T[] concatAll(T[] first, T[]... rest) {
int totalLength = first.length;
for (T[] array : rest) {
totalLength += array.length;
}
T[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (T[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
/**
* 获取method的方法参数的方式1
* @param obj
* @param methodName
* @return
* @throws IllegalArgumentException
*/
public static Class<?>[] getPeremeterClass(Object obj, String methodName)
throws IllegalArgumentException {
Class<?> clazz = obj.getClass();
Method[] method0 = clazz.getDeclaredMethods();
Class<?> superClazz = clazz.getSuperclass();
Method[] method1 = superClazz.getDeclaredMethods();
Method[] method = concatAll(method0,method1);
for (Method m : method) {
System.out.println(m.getName());
/**
* 跳过非指定的方法
*/
if (!m.getName().equals(methodName)) {
continue;
}
// 获取参数类型的数组 里面有参数的个数 和参数的类型
Class<?>[] peremeters = m.getParameterTypes();
return peremeters;
}
return null;
}
/**
* 获取Method方法参数的方式2
* @param clazz
* @param methodName
* @return
*/
public static List<String> getParamterName(Class clazz, String methodName) {
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (methodName.equals(method.getName())) {
//获取到该方法的参数们
String[] params = u.getParameterNames(method);
return Arrays.asList(params);
}
}
return null;
}
/**
* 获取Method方法参数的方式3
* @param clazz
* @param methodName
* @return
*/
public static List<String> getParameterNameJava8(Class clazz, String methodName) {
List<String> paramterList = new ArrayList<>();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (methodName.equals(method.getName())) {
//直接通过method就能拿到所有的参数
Parameter[] params = method.getParameters();
for (Parameter parameter : params) {
paramterList.add(parameter.getName());
}
}
}
return paramterList;
}
/**
* 利用Java反射根据类的名称获取属性信息和父类的属性信息
* @param clazz
* @param isHaveSuper 判断是否将父类字段也生成到JSON那种
* @return
* @throws ClassNotFoundException
*/
public static List<Field> getFiledsInfo(Class<?> clazz, boolean isHaveSuper) throws ClassNotFoundException {
List<Field> list = new ArrayList<>();
Field[] fields = clazz.getDeclaredFields();
list.addAll(Arrays.asList(fields));
if(!isHaveSuper){
return list;
}
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null) {
Field[] superFields = superClazz.getDeclaredFields();
list.addAll(Arrays.asList(superFields));
}
return list;
}
/**
* 创建JSONObject集合
* @param size 创建JsonObject对象的个数
* @return
*/
public static List<JSONObject> generatorJsonObject(int size){
List<JSONObject> jsonObjectList = new ArrayList<JSONObject>();
for(int i = 0; i < size; i++){
jsonObjectList.add(new JSONObject());
}
return jsonObjectList;
}
}
JsonToVo.java(json转换指定实体类集合行转列工具类)
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
/**
* @author 龙小白
* @version 1.0
*/
public class JsonToVo {
public static void main(String[] args) throws Exception{
JSONArray jsonArray = new JSONArray();
List<JSONObject> jsonObjectList = VoToJson.voToJson(getObjectList(),true);
for(JSONObject jsonObject : jsonObjectList){
jsonArray.add(jsonObject);
}
String param = jsonArray.toString();
List<Student> studentList = getModelList("com.test.mybatis.entry.Student", param, true);
for(Student student : studentList){ System.out.println("studentId : " + student.getStudentId() + ", studentName : " + student.getStudentName() + ", studentAge : " + student.getStudentAge() + ", studentSex : " + student.getStudentSex() + ", organizationId : " + student.getOrganizationId() + ", organizationName : " + student.getOrganizationName() + ", departmentId : " + student.getDepartmentId() + ", departmentName : " + student.getDepartmentName() + ", roleId : " + student.getRoleId() + ", roleName : " + student.getRoleName() );
}
}
/**
* 通过json数组字符串生成对象集合
* @param className 要生成的对象类型
* @param jsonArrayStr json数组字符串
* @param isHaveSuper 是否将父类的字段也生成到对象当中
* @param <T>
* @return
* @throws Exception
*/
public static <T>List getModelList(String className, String jsonArrayStr, boolean isHaveSuper) throws Exception{
JSONArray jsonArray = JSONArray.fromObject(jsonArrayStr);
int objectLen = jsonArray.getJSONObject(0).size();
int arrayLen = jsonArray.size();
Class clazz = Class.forName(className);
List<Field> fields = VoToJson.getFiledsInfo(clazz, isHaveSuper);
List<T> result = generatorModelList(clazz, objectLen);
for(int i = 0; i < arrayLen; i++){
Field field = fields.get(i);
int row = 0;
String fieldName = field.getName();
String type = field.getGenericType().toString();
JSONObject jsonObject = jsonArray.getJSONObject(i);
Set<String> stringSet = jsonObject.keySet();
Iterator<String> iterator = stringSet.iterator();
while (iterator.hasNext()){
fieldName = VoToJson.upperCaseFirst(fieldName);
String methodName = "set" + fieldName;
Class<?>[] classes = VoToJson.getPeremeterClass(result.get(row), methodName);
Method method = result.get(row).getClass().getMethod(methodName, classes);
String key = iterator.next();
if (type.equals("class java.lang.String")) {
method.invoke(result.get(row), jsonObject.getString(key));
}
if(type.equals("class java.math.BigDecimal")){
method.invoke(result.get(row), new BigDecimal(jsonObject.getInt(key)));
}
if(type.equals("class java.lang.Integer")){
method.invoke(result.get(row), jsonObject.getInt(key));
}
if (type.equals("class java.lang.Short")) {
method.invoke(result.get(row), Short.parseShort(jsonObject.getString(key)));
}
if (type.equals("class java.lang.Double")) {
method.invoke(result.get(row), Short.parseShort(jsonObject.getString(key)));
}
if (type.equals("class java.lang.Boolean")) {
method.invoke(result.get(row), jsonObject.getBoolean(key));
}
if (type.equals("class java.util.Date")) {
method.invoke(result.get(row), new Date(jsonObject.getString(key)));
}
row ++;
}
}
return result;
}
/**
* 将类初始化实例
* @param clz 要初始化的类
* @param <T> 要初始化类的类型
* @return
*/
public static <T> T createInstance(Class<T> clz){
try {
return clz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* 初始化集合,并且设置初始化的个数
* @param clazz 初始化的类
* @param size 生成集合里的对象个数
* @param <T> 初始化类的类型
* @return
*/
public static <T>List generatorModelList(Class clazz, int size){
List<T> tList = new ArrayList<T>();
for(int i = 0; i < size; i++){
tList.add((T)createInstance(clazz));
}
return tList;
}
/**
* 测试数据获取
* @return
*/
public static List<Object> getObjectList(){
Student student = new Student();
student.setStudentId("isID");
student.setStudentName("isName");
student.setStudentAge(new BigDecimal(19));
student.setStudentSex("2222");
student.setDepartmentId("1111");
student.setDepartmentName("isName");
student.setOrganizationId("222222");
student.setOrganizationName("isOrganiName");
Student student1 = new Student();
student1.setStudentId("isID1");
student1.setStudentName("isName1");
student1.setStudentAge(new BigDecimal(191));
student1.setStudentSex("22221");
student1.setDepartmentId("11112");
student1.setDepartmentName("isName1");
student1.setOrganizationId("2222221");
student1.setOrganizationName("isOrganiName1");
List<Student> students = new ArrayList<Student>();
students.add(student);
students.add(student1);
return convert(students);
}
/**
* 类型转换工具,将所有类型都转换成List<Object>类型
* @param list
* @return
*/
private static List<Object> convert(List list) {
return list;
}
}
以上,欢迎大家评论指出不足,谢谢!