Java----layui動態表單中表頭與數據----JSON串前端發送與後端接收解析

什麼是JSON

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它使得人們很容易的進行閱讀和編寫。同時也方便了機器進行解析和生成。
JSON採用完全獨立於程序語言的文本格式,但是也使用了類C語言的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。
這些特性使JSON成爲理想的數據交換語言。

json簡單說就是javascript中的對象和數組,所以這兩種結構就是對象和數組兩種結構,通過這兩種結構可以表示各種複雜的結構。
在這裏插入圖片描述
在JSON中可以使用的數據類型如上圖所示,JSON簡單來說就是數組與對象相互嵌套形成的一種數據結構。
其中對象是{}括起來的內容,以key-value形式來存儲數據,對應java中的Map。
數組是[]括起來的內容,字段值可以是字符串,數字,數組,對象,對應java中的List。
例:

[{"name":"塞爾達","age":"23"},{"name":"林克","age":"18"}]

這個JSON很明顯,是一個JSON數組,數組的字段值是對象。這個數組的size爲2。

layui動態表單----數據

首先我們來解析layui表單提交的JSON數據。
例:

[
    {
        "addressProvince":"1",
        "overValue":"1",
        "yearOverArea":"1",
        "projectLevel":"1",
        "companyName":"1",
        "createYear":"2020",
        "contractEnd":"2020-04-08",
        "monthOverNumber":"1",
        "yearDoingValue":"1",
        "LAY_TABLE_INDEX":0,
        "type":"",
        "projectStatusName":"停工",
        "layer":"1",
        "addressDetail":"1",
        "endImageProgress":"1",
        "contractName":"1",
        "state":0,
        "subcompanyName":"山西一建集團有限公司",
        "constructionArea":"1",
        "addressCity":"1",
        "formId":"",
        "createMonthName":"1月",
        "branchId":"169254",
        "monthOverArea":"1",
        "yearOverNumber":"1",
        "branchName":"材料科",
        "startDoingValue":"1",
        "createMonth":"1",
        "projectStatus":"1",
        "monthDoingValue":"1",
        "realEnd":"2020-04-10",
        "contractPrice":"1",
        "structureType":"1",
        "createYearName":"2020年",
        "addressDistrict":"1",
        "realStart":"2020-04-09",
        "contractStart":"2020-04-07",
        "contractCode":"1"
    },
    {
        "addressProvince":"1",
        "overValue":"1",
        "yearOverArea":"1",
        "projectLevel":"1",
        "companyName":"1",
        "createYear":"2020",
        "contractEnd":"2020-04-08",
        "monthOverNumber":"1",
        "yearDoingValue":"1",
        "LAY_TABLE_INDEX":1,
        "type":"",
        "projectStatusName":"在施",
        "layer":"1",
        "addressDetail":"1",
        "endImageProgress":"1",
        "contractName":"1",
        "state":0,
        "subcompanyName":"山西一建集團有限公司",
        "constructionArea":"1",
        "addressCity":"1",
        "formId":"",
        "createMonthName":"1月",
        "branchId":"169254",
        "monthOverArea":"1",
        "yearOverNumber":"1",
        "branchName":"材料科",
        "startDoingValue":"1",
        "createMonth":"1",
        "projectStatus":"0",
        "monthDoingValue":"1",
        "realEnd":"2020-04-10",
        "contractPrice":"1",
        "structureType":"1",
        "createYearName":"2020年",
        "addressDistrict":"1",
        "realStart":"2020-04-09",
        "contractStart":"2020-04-07",
        "contractCode":"1"
    }
]

看起來比較長,實際上就是一個簡單的數組內嵌套對象的JSON串,如下圖所示:
在這裏插入圖片描述
先貼出前端傳回這個JSON串的ajax

$.ajax({
	type: 'post',//必須爲post
	url: '/em/ext/api/test/create',
	contentType : 'application/json;charset=utf-8', //設置請求頭信息
	dataType:"json",//數據類型爲json
	data: JSON.stringify(tableData),//通過函數進行轉換,將表單數據轉化爲JSON對象
	success:function(res){
		if(res.code=="M000000"){
			layer.msg("保存成功");
		  }else{
			  layer.msg(res.info);
		  }
	},
	error:function(err){
		console.log(err)
	}
})

後臺Controller的參數:

public Map<String, Object> approval(@RequestBody String jsonStr){
	
}

注意這裏一定要加@RequestBody纔可接收json數據。

註解@RequestBody接收的參數是來自requestBody中,即請求體。因此前端的ajax方式必須爲post,get請求是沒有請求體的,因此該註解不適用。

這裏因爲是動態表單,所以是用的字符串來接收。若是非動態表單,可以使用實體類來接收數據。如果傳來的數據是對象類型,可以使用@RequestBody User user 來直接接收。如果傳來的對象是數組,數組內的元素是對象,則可使用@RequestBody List<User> user 來接收。
這裏我們解析動態表單,所以實體類內的元素是不確定的,因此用String來接收,之後再進行處理。

具體解析代碼如下:

public static List<String> parseJsonArray(String jsonStr){
		JSONArray jArray = JSON.parseArray(jsonStr);
		List<String> res = new ArrayList<>();
		for(int i=0;i<jArray.size();i++){
			JSONObject jsonObject = jArray.getJSONObject(i);
			res.add(jsonObject.toString());
		}
		return res;
	}

這個方法我們將json串中的多個對象拆分,存入List<String>中。
首先第一步,我們通過JSON.parseArray(jsonStr);這個函數,將json字符串轉化爲JSONArray對象。
在這裏插入圖片描述
查看源碼我們可以看到,JSONArray類實現了List<Object>接口,因此他實現了List接口的方法。我們可以通過for循環進行遍歷,拿到他的具體某一個元素,這裏的元素是對象類型的json,因此我們調用它的getJSONObject(i);方法,獲取它的JSON對象,最後再轉化爲字符串存入List中。後續如果需要操作,再通過JSON.parseObject(jsonStr);方法將String類型的json解析成對象即可。
這裏我們再看一下JSONObject這個JSON對象。
在這裏插入圖片描述
可以看到它實現了Map<String,Object>接口,因此Map接口定義的方法,在JSONObject中均有實現。
由此我們可以印證之前所說,JSON中的數組就是Java中的LIst,JSON中的對象就是Java中的map。

layui動態表單----表頭

首先我們貼出layui動態表單渲染所需要的json串。

[
    [
        {
            "field":"id",
            "title":"建築業企業建築施工板塊完成情況月報",
            "colspan":35
        }
    ],
    [
        {
            "field":"subcompanyName",
            "title":"子集團名稱",
            "rowspan":2
        },
        {
            "field":"branchName",
            "title":"分公司名稱",
            "templet":"#branch",
            "rowspan":2
        },
        {
            "field":"companyName",
            "edit":"text",
            "title":"建設單位及單位工程名稱",
            "rowspan":2
        },
        {
            "field":"createYear",
            "templet":"#year",
            "title":"創建年份",
            "rowspan":2
        },
        {
            "field":"createMonth",
            "templet":"#month",
            "title":"創建月份",
            "rowspan":2
        },
        {
            "field":"contractName",
            "edit":"text",
            "title":"合同工程名稱",
            "rowspan":2
        },
        {
            "field":"contractCode",
            "edit":"text",
            "title":"合同編號",
            "rowspan":2
        },
        {
            "field":"contractPrice",
            "edit":"text",
            "title":"合同價(萬元)",
            "rowspan":2
        },
        {
            "title":"建設地址",
            "colspan":4
        },
        {
            "title":"合同工期",
            "colspan":2
        },
        {
            "title":"實際工期",
            "colspan":2
        },
        {
            "field":"structureType",
            "edit":"text",
            "title":"結構類型",
            "rowspan":2
        },
        {
            "field":"layer",
            "edit":"text",
            "title":"層數",
            "rowspan":2
        },
        {
            "field":"constructionArea",
            "edit":"text",
            "title":"施工面積(m²)",
            "rowspan":2
        },
        {
            "field":"projectLevel",
            "edit":"text",
            "title":"項目級別",
            "rowspan":2
        },
        {
            "field":"projectStatus",
            "templet":"#projectStatus",
            "title":"項目狀態",
            "rowspan":2
        },
        {
            "title":"竣工面積及竣工產值",
            "colspan":5
        },
        {
            "title":"施工產值(萬元)",
            "colspan":3
        },
        {
            "field":"endImageProgress",
            "edit":"text",
            "title":"期末形象進度",
            "rowspan":2,
            "width":100
        },
        {
            "title":"操作",
            "width":200,
            "toolbar":"#toolbar",
            "rowspan":2
        }
    ],
    [
        {
            "field":"addressProvince",
            "edit":"text",
            "title":"省"
        },
        {
            "field":"addressCity",
            "edit":"text",
            "title":"市"
        },
        {
            "field":"addressDistrict",
            "edit":"text",
            "title":"區/縣"
        },
        {
            "field":"addressDetail",
            "edit":"text",
            "title":"詳細地址"
        },
        {
            "field":"contractStart",
            "templet":"#contractStart",
            "title":"開工日期",
            "rowspan":2
        },
        {
            "field":"contractEnd",
            "templet":"#contractEnd",
            "title":"竣工日期",
            "rowspan":2
        },
        {
            "field":"realStart",
            "templet":"#realStart",
            "title":"開工日期",
            "rowspan":2
        },
        {
            "field":"realEnd",
            "templet":"#realEnd",
            "title":"竣工日期",
            "rowspan":2
        },
        {
            "field":"yearOverArea",
            "edit":"text",
            "title":"自年初累計_竣工面積(m2)"
        },
        {
            "field":"yearOverNumber",
            "edit":"text",
            "title":"個數"
        },
        {
            "field":"monthOverArea",
            "edit":"text",
            "title":"本月_竣工面積(m2)"
        },
        {
            "field":"monthOverNumber",
            "edit":"text",
            "title":"個數"
        },
        {
            "field":"overValue",
            "edit":"text",
            "title":"竣工產值(萬元)"
        },
        {
            "field":"startDoingValue",
            "edit":"text",
            "title":"自開工累計"
        },
        {
            "field":"yearDoingValue",
            "edit":"text",
            "title":"自年初累計完成"
        },
        {
            "field":"monthDoingValue",
            "edit":"text",
            "title":"本月"
        }
    ]
]

因爲這是一個三級表單的表頭,所以看上去很長,但實際上結構非常清晰。這個表頭實際頁面裏是這樣的。
在這裏插入圖片描述
整理後我們發現,JSON結構如下圖所示:
在這裏插入圖片描述
最外層是一個List,因爲表頭是三級,所以List內有3個元素,均爲List,我們繼續看內層List內部的結構:
在這裏插入圖片描述
如圖所示,內部是一個對象。也就是說,表頭的JSON結構要稍微複雜一些,嵌套關係是 外數組–內數組–對象。
這裏我們要做的是,找出表頭內所有含有field屬性的對象。因爲表單是動態的,所以我們拿到這些field也就相當於拿到了Map的Key,可以去表單數據的JSON串中獲取相應的數據。
代碼如下:

	public static List<String> parseJsonHead(String jsonHead){
		JSONArray jArray = JSON.parseArray(jsonHead);//將字符串轉化爲JSONArray對象,這裏是外層數組
		List<Map<String, Object>> list = new ArrayList<>();
		List<String> res = new ArrayList<>();
		for(int i=0;i<jArray.size();i++){//循環,對外層數組進一步拆分
			JSONArray jArr = jArray.getJSONArray(i);//得到內層數組對象
			for(int j=0;j<jArr.size();j++){
				JSONObject jsonObject = jArr.getJSONObject(j);//得到具體的每個對象,存入list
				list.add(jsonObject);
			}
		}
		list.forEach(v -> {//這裏我們遍歷得到的list,若field不爲空,則存入結果數組,最終我們得到存有字段名的數組List<String>
			String field = (String)v.get("field");
			if(field!=null){
				res.add(field);
			}
		});
		return res;
	}

具體步驟見註釋。值得注意的是,由外層數組獲取內層數組的部分jArray.getJSONArray(i); 我們可以看到JSONArray類型也是可以調用getJSONArray這個api的,這正好與我們的理解相符,數組內部既可以是數組,也可以是對象。

Over~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章