簡單易懂的JSON框架

JuneZero發表於2024-06-12

  分享一個由本人編寫的JSON框架。

  JSON反序列化使用遞迴方式來解析JSON字串,不使用任何第三方JAR包,只使用JAVA的反射來建立物件(必須要有無參構造器),賦值,編寫反射快取來提升效能。支援複雜的泛型型別,陣列型別等所有型別。(不支援高版本JDK1.8以上的日期型別,如LocalDate,LocalDateTime,需要你修改原始碼JsonString類來支援)

  你可以改造原始碼,讓其支援註解序列化和反序列化。擴充套件一些功能,如JsonPath路徑方式解析。當然前提是你感興趣和有一定的封裝能力的話。。。

  下面是使用案例:

package test;

import java.io.IOException;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import june.zero.generic.TypeBuilder;
import june.zero.json.JSON;
import june.zero.json.reader.JsonString;
import june.zero.json.reader.element.impl.JsonArray;
import june.zero.json.reader.element.impl.JsonObject;
import june.zero.json.reader.parser.impl.JsonElementParser;
import june.zero.json.writer.JsonWriter;

public class Main {

    public static class User {
        public String name;
        public int age;
        public java.util.Date date;
        public int[] hobbys;
        public String jsonObjectData;
        public String jsonArrayData;
        public boolean flag;
        @Override
        public String toString() {
            return "User [age=" + age + ", date=" + date + ", flag=" + flag
                    + ", hobbys=" + Arrays.toString(hobbys)
                    + ", jsonArrayData=" + jsonArrayData + ", jsonObjectData="
                    + jsonObjectData + ", name=" + name + "]";
        }
    }
    
    public static class Response<T> {
        public int code;
        public String message;
        public T data;
        @Override
        public String toString() {
            return "Response [code=" + code + ", data=" + data + ", message="
                    + message + "]";
        }
    }
    
    public static void main(String[] args) {
        testJsonFormat();
        testDate();
        testInsideJson();
        testGenericType();
        testCustom();
        testJsonWrite();
        testInOut();
    }
    
    public static void testJsonFormat(){
        System.out.println("=====testJsonFormat=====");
        
        //標準JSON格式
        String json1 = "{\"name\":\"張三\",\"age\":33}";
        User user1 = JSON.fromJSON(json1, User.class);
        System.out.println(user1.name);//張三
        
        //單引號格式
        String json2 = "{'name':'張三','age':33,'date':'2024-06-06 12:12:12','hobbys':[1,2,3]}";
        User user2 = JSON.fromJSON(json2, User.class);
        System.out.println(user2.date);//2024-06-06 12:12:12.0
        
        //沒有引號格式,不建議使用
        String json3 = "{name:張三,age:33,flag:true}";
        User user3 = JSON.fromJSON(json3, User.class);
        System.out.println(user3.flag);//true
    }
    
    public static void testDate(){
        System.out.println("=====testDate=====");
        
        // java.util.Date日期格式 yyyy-MM-dd hh:mm:ss.SSS,yyyy-MM-dd hh:mm:ss,yyyy-MM-dd hh:mm,yyyy-MM-dd hh,yyyy-MM-dd,yyyy-MM,yyyy
        String dataString = "'2024-06-06 12:12'";
        java.util.Date d0 = JSON.fromJSON(dataString, java.util.Date.class);
        System.out.println(d0);//2024-06-06 12:12:00.0
        java.util.Calendar d1 = JSON.fromJSON(dataString, java.util.Calendar.class);
        System.out.println(d1);
        java.sql.Timestamp d11 = JSON.fromJSON(dataString, java.sql.Timestamp.class);
        System.out.println(d11);
        
        //java.sql.Date日期格式 yyyy-MM-dd,yyyy-MM,yyyy
        String dataString2 = "'2024-06'";
        java.sql.Date d2 = JSON.fromJSON(dataString2, java.sql.Date.class);
        System.out.println(d2);
        
        //java.sql.Time日期格式 hh:mm:ss,hh:mm,hh
        String dataString3 = "'12:12'";
        java.sql.Time d3 = JSON.fromJSON(dataString3, java.sql.Time.class);
        System.out.println(d3);
    }
    
    public static void testInsideJson(){
        System.out.println("=====testInsideJson=====");
        
        //JsonArray轉String
        String json1 = "{'jsonArrayData':[1,2,3]}";
        User user1 = JSON.fromJSON(json1, User.class);
        System.out.println(user1.jsonArrayData);//[1,2,3]
        
        //JsonObject轉String
        String json2 = "{'jsonObjectData':{name:張三}}";
        User user2 = JSON.fromJSON(json2, User.class);
        System.out.println(user2.jsonObjectData);//{name:張三}
        
        //內部JSON字串轉物件
        Type listMapType = new TypeBuilder<Response<List<Map<String,Object>>>>() {}.getGenericType();
        String json3 = "{'code':1,'message':'查詢成功','data':'[{name:李四,age:44},{name:王五,age:55}]'}";
        Response<List<Map<String,Object>>> response4 = JSON.fromJSON(json3, listMapType);
        System.out.println(response4.data);//[{age=44, name=李四}, {age=55, name=王五}]
    }
    
    public static void testGenericType(){
        System.out.println("=====testGenericType=====");
        
        String json = "{'code':1,'message':'查詢成功','data':[{'name':'李四','age':44},{'name':'王五','age':55}]}";
        
        System.out.println("=====型別1======");
        Type listUserType = new TypeBuilder<Response<List<User>>>() {}.getGenericType();
        System.out.println(listUserType);//test.Main.test.Main$Response<java.util.List<test.Main$User>>
        Response<List<User>> response1 = JSON.fromJSON(json, listUserType);
        System.out.println(response1.data.get(1).name);//王五
        
        System.out.println("=====型別2======");
        Type listMapType = new TypeBuilder<Response<List<Map<String,Object>>>>() {}.getGenericType();
        System.out.println(listMapType);//test.Main.test.Main$Response<java.util.List<java.util.Map<java.lang.String, java.lang.Object>>>
        Response<List<Map<String,Object>>> response2 = JSON.fromJSON(json, listMapType);
        System.out.println(response2.data.get(1).get("name"));//王五
        
        System.out.println("=====型別3======");
        Type stringType = new TypeBuilder<Response<String>>() {}.getGenericType();
        System.out.println(stringType);//test.Main.test.Main$Response<java.lang.String>
        Response<String> response3 = JSON.fromJSON(json, stringType);
        System.out.println(response3.data);//[{'name':'李四','age':44},{'name':'王五','age':55}]
        
    }
    
    @SuppressWarnings("unchecked")
    public static void testCustom(){
        System.out.println("=====testCustom=====");
        
        //自定義處理
        String json = "{'code':1,'message':'查詢成功','data':[{'name':'李四','age':15},{'name':'王五','age':20}]}";
        Type listUserType = new TypeBuilder<Response<List<User>>>() {}.getGenericType();
        JsonElementParser parser = new JsonElementParser(){
            @Override
            protected JsonArray getJsonArray() {
                return new JsonArray(){
                    @Override
                    public boolean add(Object e) {
                        if(e instanceof User){
                            User u = (User)e;
                            if(u.age<18){//過濾掉不滿18歲的資料
                                return false;
                            }
                        }
                        return super.add(e);
                    }
                };
            }
        };
        Response<List<User>> response = (Response<List<User>>)parser.parse(json, listUserType);
        System.out.println(response.data);
        
        //對已有物件進行賦值解析
        String json2 = "{'code':0,'data':null}";
        Type listUserType2 = new TypeBuilder<Response<List<User>>>() {}.getGenericType();
        final Response<List<User>> response2 = new Response<List<User>>(){};
        response2.code = 1;
        response2.message = "查詢失敗";
        JsonElementParser parser2 = new JsonElementParser(){
            @Override
            protected JsonObject getJsonObject() {
                return new JsonObject(){
                    @Override
                    public void setType(Type genericType) {
                        super.setType(genericType);
                        if(this.type == Response.class){
                            this.elementValue = response2;
                        }
                    }
                };
            }
        };
        parser2.parse(json2, listUserType2);
        System.out.println(response2);
        
        //功能擴充套件
        String json3 = "'Thu Jun 12 12:12:12 CST 2024'";
        JsonElementParser parser3 = new JsonElementParser(){
            @Override
            protected JsonString getJsonString() {
                return new JsonString(){
                    @SuppressWarnings("deprecation")
                    @Override
                    public Object getElementValue() throws ParseException {
                        //擴充套件更多日期解析方式
                        if(this.genericType==java.util.Date.class){
                            try {
                                //嘗試使用java.util.Date自帶的方法進行解析
                                return new java.util.Date(java.util.Date.parse(this.toString()));
                            } catch (Exception e) {
                                //格式錯誤
                            }
                        }
                        return super.getElementValue();
                    }
                };
            }
        };
        Object o = parser3.parse(json3,java.util.Date.class);
        System.out.println(o);
    }
    
    public static void testJsonWrite(){
        System.out.println("=====testJsonWrite=====");
        User obj = new User();
        obj.name="張三";
        System.out.println(JSON.toJSON(obj));
        
        //自定義輸出
        JsonWriter writer = new JsonWriter(){
            @Override
            protected void writeObject(Object obj) throws IOException {
                if(obj instanceof User){
                    User u = (User)obj;
                    JsonObjectWriter jsonObjectWriter = getJsonObjectWriter();
                    jsonObjectWriter.start();
                    jsonObjectWriter.write("name1", u.name);
                    jsonObjectWriter.end();
                    return;
                }
                super.writeObject(obj);
            }
        };
        StringBuilder json = new StringBuilder();
        //FileWriter json = new FileWriter("xxxxxx");
        writer.write(obj, json);
        System.out.println(json);
    }
    
    @SuppressWarnings("unchecked")
    public static void testInOut(){
        System.out.println("=====testInOut=====");
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("content", "<script>alert(1)</script>");
        
        //普通轉義輸出
        StringBuilder out = new StringBuilder();
        JsonWriter writer = new JsonWriter();
        writer.write(data, out);
        System.out.println(out);
        
        //HTML安全轉義輸出
        StringBuilder out2 = new StringBuilder();
        JsonWriter writer2 = new JsonWriter();
        writer2.ofHtmlSafeReplace(true);
        writer2.write(data, out2);
        System.out.println(out2);
        
        //支援普通轉義解析
        String json2 = "{'content':'\u003cscript\u003ealert(2)\u003c/script\u003e'}";
        Map<Object,Object> map = JSON.fromJSON(json2, Map.class);
        System.out.println(map.get("content"));
    }
    
}

開源不易,需要鼓勵。轉載請標明該來源。https://www.cnblogs.com/JuneZero/p/18237283

因為可能長時間不會更新JAR包,所以我不建議你使用到真實開發環境。程式碼易懂,你可以自己維護和擴充套件功能。測試環境使用的是JDK1.7.0_80

原始碼:https://files.cnblogs.com/files/blogs/824473/Zjson-source.zip?t=1718154818&download=true

jar包:https://files.cnblogs.com/files/blogs/824473/ZJson.zip?t=1718154823&download=true

相關文章