json轉物件(沒有什麼實際意義)

起名字很難發表於2018-05-28

這篇文章不是自己寫的,是參考別人的程式碼寫出來的。


不說什麼,把程式碼貼上進自己的工程,斷點看下就知道具體是怎麼寫的了。


package com.zrobots.domain;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.junit.Test;

import javax.tools.*;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Iterator;


/**
 * @Description:
 * @Package: com.zrobots.domain
 * @Date: Created in 2018/5/22 16:04
 * @author: weizhaoli
 */
public class BeanUtils {

    private String jsonStr = "{\"name\": \"jack\",\"age\": 10.0}";
    private String className = "User";
    private String packageName = "com.zrbots.domain";

    @Test
    public void test() throws Exception{
        Class aClass = createBean(jsonStr, packageName, className);
        Object o = aClass.newInstance();
        Field[] fields = aClass.getFields();
        for (Field field : fields){
            System.out.println(field.getName());
        }
        System.out.println(o);
        Field field = aClass.getField("name");
//        System.out.println(field.getName());

    }




    /**
     * 由JSON字串生成Class物件
     *
     * @param jsonStr
     * @param className 待生成Bean物件的名稱
     */
    public static Class createBean(String jsonStr, String packageName,String className) {
        try {
            JSONObject job = JSONObject.fromObject(jsonStr);
            String beanStr = createObject(job, packageName, className, 0);
            return compile(packageName + "." + className, beanStr);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 由JSONObject生成Bean物件字串
     *
     * @param job
     * @param className 待生成Bean物件的名稱
     * @param outCount 外部類的個數
     * @return LinkedList<String>: 生成的Bean物件的字串
     */
    private static String createObject(JSONObject job, String packageName, String className, int outCount) {
        final StringBuilder sb = new StringBuilder();
        String separator = System.getProperty("line.separator");

        // 生成的Bean類前部的縮排空間
        String classFrontSpace = "";
        // 生成的Bean類欄位前部的縮排空間
        String fieldFrontSpace = "    ";
        for (int i = 0; i < outCount; i++) {
            classFrontSpace += "    ";
            fieldFrontSpace += "    ";
        }

        if (outCount == 0){
            sb.append(classFrontSpace + "package " + packageName + ";");
            sb.append(classFrontSpace + "import java.util.List;");
            sb.append(classFrontSpace + "public class " + className + " {");
        }else {
            sb.append(classFrontSpace + "class " + className + " {");
        }


        Iterator<?> it = job.keys();
        while (it.hasNext()) {
            String key = (String) it.next();
            try {
                Object obj = job.get(key);
                if(obj instanceof JSONArray) {
                    // 判斷類是否為基本資料型別,如果為自定義類則欄位型別取將key的首字母大寫作為內部類名稱
                    String fieldType = ((JSONArray)obj).get(0) instanceof JSONObject ?
                            "" : ((JSONArray)obj).get(0).getClass().getSimpleName();
                    if(fieldType == "") {
                        fieldType = String.valueOf(Character.isUpperCase(key.charAt(0)) ?
                                key.charAt(0) : Character.toUpperCase(key.charAt(0))) + key.substring(1);
                    }
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "public List<" + fieldType + "> " + key + ";");

                    // 如果欄位型別為自定義類型別,則取JSONArray中第一個JSONObject生成Bean
                    if(((JSONArray)obj).get(0) instanceof JSONObject) {
                        sb.append(separator);
                        sb.append(separator);
                        sb.append(fieldFrontSpace + "/** "+ fieldType +" is the inner class of "+ className +" */");
                        sb.append(separator);
                        sb.append(createObject((JSONObject)((JSONArray)obj).get(0), packageName, fieldType, outCount+1));
                    }
                } else if(obj instanceof JSONObject) {
                    String fieldType = String.valueOf(Character.isUpperCase(key.charAt(0)) ?
                            key.charAt(0) : Character.toUpperCase(key.charAt(0))) + key.substring(1);
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "public List<" + fieldType + "> " + key + ";");
                    sb.append(separator);
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "/** "+ fieldType +" is the inner class of "+ className +" */");
                    sb.append(separator);
                    sb.append(createObject((JSONObject)obj, packageName, fieldType, outCount+1));
                } else {
                    String type = obj.getClass().getSimpleName();
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "public " + type + " " + key + ";");
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "public " + type + " get" + key.substring(0, 1).toUpperCase() + key.substring(1) +"() {");
                    sb.append(separator);
                    sb.append(fieldFrontSpace + fieldFrontSpace + "return this." + key + ";");
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "}");
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "public void set" +  key.substring(0, 1).toUpperCase() + key.substring(1) + "(" + type + " " +key + ") {");
                    sb.append(separator);
                    sb.append(fieldFrontSpace + fieldFrontSpace + "this." + key + " = " + key + ";");
                    sb.append(separator);
                    sb.append(fieldFrontSpace + "}");
                    sb.append(separator);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        sb.append(separator);
        sb.append(classFrontSpace + "}");
        sb.append(separator);

        return sb.toString();
    }

    private final static Class<?> compile(String name, String content) {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        StrSrcJavaObject srcObject = new StrSrcJavaObject(name, content);
        Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(srcObject);
        String flag = "-d";
        String outDir = "";
        try {
            File classPath = new File(Thread.currentThread().getContextClassLoader().getResource("").toURI());
            outDir = classPath.getAbsolutePath() + File.separator;
        } catch (URISyntaxException e1) {
            e1.printStackTrace();
        }
        Iterable<String> options = Arrays.asList(flag, outDir);
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, fileObjects);
        boolean result = task.call();
        if (result == true) {
            System.out.println("Compile it successfully.");
            try {
                return Class.forName(name);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    private static class StrSrcJavaObject extends SimpleJavaFileObject {
        private String content;
        public StrSrcJavaObject(String name, String content) {
            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.content = content;
        }
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return content;
        }
    }


}

相關文章