Jboot V3.7.3 增強了和前端的 JSON 互動能力,可能是全網最為優雅、簡單的接收方式。
1、接收 Java Bean。在 Controller 中接收 Java Bean 可能是最為常見的方式,在 SpringMVC 中也內建了支援。
比如,前端傳入的是:
{ "id":"abc", "age":17, "amount":123 }
我們可以定義一個如下的 Java Bean 來接收。
public class MyBean { private String id; private int age; private BigInteger amount; //getter setter}
在 Jboot(JFinal)的 Controller 中,我們如下的程式碼可以正常的接收。
public void bean(@JsonBody() MyBean bean) { System.out.println("bean--->" + bean); renderText("ok");}
但是,如果我們需要接收的資料,是放在 JSON 的實體內部,比如:
{ "aaa":{ "bbb":{ "id":"abc", "age":17, "amount":123 } } }
在 Controller 中,我們依然可以透過如下的方法進行接收:
public void bean(@JsonBody("aaa.bbb") MyBean bean) { System.out.println("bean--->" + bean); renderText("ok");}
沒錯,值需要給 @JsonBody 新增 ”aaa.bbb“ 字首。
2、接收 Java Map在 Controller 中,我們接收 Map 的場景也是非常常見的,接收 Map 和 接收 Java Bean 對我們來說,學習成本是 0。在如上的程式碼中,我們只需要把 MyBean 的引數快取 Map 就可以了。
比如前端傳入的是:
{ "id":"abc", "age":17, "amount":123 }
Controller 後端透過如下的方式接收:
public void action(@JsonBody() Map map) { System.out.println("map--->" + map); renderText("ok");}
而且,這裡支援了更多的功能,在 Map 中我們可以給 Map 指定泛型來進行接收,比如:
public void action(@JsonBody() Map<String,String> map) { System.out.println("map--->" + map); renderText("ok");}
那麼,所有的 value 都會自動轉換為 String 型別存放在 Map 裡。而且,此處的 Map,你可以換成 HashMap、ConcurrentHashMap 都是沒問題的。如果前端傳入的 JSON 如下:
{ "aaa":{ "bbb":{ "id":"abc", "age":17, "amount":123 } } }
和接收 Bean 一樣。我們只需要在 Controller 給 @JsonBody 新增字首即可:
public void action(@JsonBody("aaa.bbb") Map map) { System.out.println("map--->" + map); renderText("ok");}
3、接收陣列和集合(List、Set、Queue、Vector、Stack、Deque )
和接收 Bean、Map 一樣,當前端傳入的是一個Json 陣列的時候,我們一樣輕鬆接收。比如,前端傳入的 Json 內容如下:
[1,2,3]
我們可以輕鬆的把前端轉換成為一個 int[] 陣列:
//透過 int[] 陣列來接收public void method1(@JsonBody() int[] beans) { System.out.println("beans--->" + beans); renderText("ok");}
當然,透過 List、Set 等集合來接收都是沒問題的:
//透過 List 來接收public void method3(@JsonBody() List beans) { System.out.println("beans--->" + beans); renderText("ok");} //透過 Set 來接收public void method4(@JsonBody() Set beans) { System.out.println("beans--->" + beans); renderText("ok");} //透過 List 指定泛型 Integer 來接收public void method5(@JsonBody() List<Integer> beans) { System.out.println("beans--->" + beans); renderText("ok");} //透過 Set 指定泛型 Integer 來接收public void method6(@JsonBody() Set<Integer> beans) { System.out.println("beans--->" + beans); renderText("ok");}
不僅僅可以透過 int 型別來接收,透過 long、float、double、bigInteger 甚至 String 都是沒問題的,比如:
//透過 List 指定泛型 String 來接收public void method7(@JsonBody() List<String> beans) { System.out.println("beans--->" + beans); renderText("ok");} //透過 Set 指定泛型 String 來接收public void method8(@JsonBody() Set<String> beans) { System.out.println("beans--->" + beans); renderText("ok");}
除此之外、我們還可以把集合中的 List、Set 修改為 Queue、Vector、Stack、Deque 等其他資料型別,一樣優雅完美。
前端傳入的是一個數組的 Java Bean:
[ { "id":"abc", "age":17, "amount":123 }, { "id":"abc", "age":17, "amount":123 } ]
拍拍屁股就知道如何在 Controller 寫程式碼接收了:
public void array(@JsonBody() MyBean[] beans) { System.out.println("array--->" + beans); renderText("ok");}
或者:
public void list(@JsonBody() List<MyBean> list) { System.out.println("list--->" + list); renderText("ok"); }
如果 Java Bean 的陣列放在 Json 多層的實體裡:
{ "aaa":{ "bbb":[ { "id":"abc", "age":17, "amount":123 }, { "id":"abc", "age":17, "amount":123 } ] }}
我們只需要在 @JsonBody 新增引數即可:
public void list(@JsonBody("aaa.bbb") List<MyBean> list) { System.out.println("list--->" + list); renderText("ok"); }
4、接收基本資料
在上述例子中,已經能接收 Java Bean、Map、陣列和集合、接收基本資料自然不在話下。
例如,前端傳入的內容如下:
{ "aaa":{ "bbb":{ "id":"abc", "age":17, "amount":123 } } }
此時,如果我們想獲取 age 的值,程式碼如下:
public void age(@JsonBody("aaa.bbb.age") int age) { System.out.println("age--->" + age); renderText("ok"); }
當然,這個 age 在方法裡定義的是 int 型別,我們可以隨便定義成 Integer/long/float/double/BigInteger/String 等等都沒問題。
5、自動拆裝如果 Jboot 以上的能力讓你拍手叫好,那麼 Jboot 特有的自動拆裝絕對讓你更加拍案叫絕。
比如前段傳入的內容如下:
{ "aaa":{ "bbb":[ { "id":"abc", "age":17, "amount":123 }, { "id":"abc", "age":17, "amount":123 } ] }}
在非常多的場景下,我們只想獲取 bbb 數組裡的所有物件的 id 值,並不想獲取其他內容,那麼,如下的程式碼就可以幫你輕易的拆裝:
public void array(@JsonBody("aaa.bbb[id]") String[] ids) { System.out.println("array--->" + ids); renderText("ok");}public void array(@JsonBody("aaa.bbb[id]") List<String> ids) { System.out.println("array--->" + ids); renderText("ok");}
或者,我們想獲取 bbb 陣列的第一個物件,並轉換為 Java Bean:
public void bean(@JsonBody("aaa.bbb[0]") MyBean bean) { System.out.println("bean--->" + bean); renderText("ok");}
有或者說,我們想獲取 bbb 陣列的第一個物件的 age 值:
public void age(@JsonBody("aaa.bbb[0].age") long age) { renderText("age--->" + age);}
我們來到更加複雜的,比如說如下的 JSON:
{ "aaa":{ "bbb":[ { "attr1":"abc", "beans":[ { "id":"abc", "age":17, "amount":123 }, { "id":"abc", "age":17, "amount":123 } ] }, { "attr2":"abc" } ] }}
我們的目標是為了獲取 beans 下,並轉換為 MyBean 陣列(或者 List 等集合),程式碼如下:
public void array(@JsonBody("aaa.bbb[0].beans") MyBean[] beans) { System.out.println("array--->" + JsonKit.toJson(beans)); renderText("ok");}
又或者說我們想獲取 beans 下的所有 id 值,得到一個 String 陣列:
public void array(@JsonBody("aaa.bbb[0].beans[id]") String[] ids) { System.out.println("array--->" + JsonKit.toJson(ids)); renderText("ok");}
簡單而優雅。
6、透過非注入的方式接收 JSON在以上的示例中,都是透過 @JsonBody 註解的方式進行注入的,如果不透過注入的方式,也沒問題,在 JbootController 中,已經內建了 getRawObject() 方法來輔助我們接收 JSON 資料。
比如,前端傳入的內容如下:
{ "aaa":{ "bbb":[ { "attr1":"abc", "beans":[ { "id":"abc", "age":17, "amount":123 }, { "id":"abc", "age":17, "amount":123 } ] }, { "attr2":"abc" } ] }}
我們想把 beans 接收成為一個數組,可以透過如下的程式碼:
public void array() { MyBean[] beans = getRawObject(MyBean[].class,"aaa.bbb[0].beans"); System.out.println("array--->" + JsonKit.toJson(beans)); renderText("ok");}
如果我們想接收 List<MyBean>,需要藉助 Jboot 內建的 TypeDef 來輔助接收,程式碼如下:
public void array() { List<MyBean> beans = getRawObject(new TypeDef<List<MyBean>>(){},"aaa.bbb[0].beans"); System.out.println("array--->" + JsonKit.toJson(beans)); renderText("ok");}
當然,接收其他不同的資料,值需要定義 json 的字首即可,比如說我們要接收一個 Set<String> 的 id。程式碼如下:
public void array() { Set<Strint> ids = getRawObject(new TypeDef<Set<String>>(){},"aaa.bbb[0].beans[id]"); System.out.println("array--->" + JsonKit.toJson(ids)); renderText("ok");}
但是此處需要注意的是:由於前段傳入的兩個 Object JSON 陣列中,他們的 id 值都是一樣的,當我們使用 Set 來接收的時候,Set 裡只有一個值。
開發文件:https://jbootprojects.gitee.io/docs/