1. 程式人生 > >SpringMVC 引數繫結詳解

SpringMVC 引數繫結詳解

概述

記得之前跟前端同事聯調介面的時候,後端springMVC需要接收陣列型別的引數,然後跟前端說需要傳陣列型別過來。後來前端童鞋傳了陣列,但是後端接收不成功,聯調失敗。那時候由於時間關係沒有仔細研究這塊,當時想了個辦法就是前端傳一個json字串,後端換成接收json字串然後轉成需要的陣列物件。這顯然不是一種好的做法,框架幫我們做好的事我們沒有用上,還平白多了兩次資料的轉換。所以今天花時間研究了下,將springMVC的資料繫結做個總結。

1. 簡單型別引數

即幾種java原生的基本資料型別已經其封裝類以及String型別。比較簡單,選一種布林型別來講解。
測試程式碼:

    @RequestMapping
(value = "test") @ResponseBody public Object testDataBind(@RequestParam(name = "test") Boolean test) { System.out.println(test); return "success"; }

使用postman工具傳送請求:
這裡寫圖片描述

控制檯輸出:

true

這種的比較簡單,沒有太多可說的。這裡需要注意的是,引數如果沒有加@RequestParam註解的話,傳參需要預設引數的名稱test作為傳參引數的名稱,而且沒有加註解的話,前端在傳送http請求的時候可以不傳該引數,也不會報錯。但是如果加了該註解,在沒有設定註解的屬性required = false的前提下,該引數必傳,不然會報400錯誤。如果該註解中指定了name屬性,name前端需要以name的值作為前端傳參名稱,如果沒有指定name屬性,在按引數名稱test為前端傳參名稱。

大家可逐一驗證。

2. 簡單型別陣列/list

分別為兩種情況:

1) 直接使用陣列作為方法的引數,可以用@RequestParam註解修飾,如果使用List,必須使用@RequestParam註解修飾

介面程式碼:

    @RequestMapping(value = "test")
    @ResponseBody
    public Object testDataBind(String[] tests) {
        System.out.println(tests[0] + "    " + tests[1]);
        return "success";
    }

這種前端傳參需要遵守一定格式。

  • form表單
    表單元素name的值必須一樣
name="tests" value="arony1"
name="tests" value="arony2"

postman傳送請求:
這裡寫圖片描述

控制檯輸出:

arony1    arony2
  • ajax
    陣列各個元素值需用“,”隔開。
data:{"tests":"arony1,arony2"}

值得注意的是,如果後端的springMVC方法引數用的是陣列來接收的話,前端用ajax傳送請求,那麼只能用上面這一種格式傳參,使用下面說的tests[0],tests[1]傳參是不行的。
postman傳送請求:
這裡寫圖片描述

控制檯輸出:

arony1    arony2

2)使用自定義類裡面封裝一個數組或者List,用自定義類例項作為方法引數,不能用@RequestParam註解修飾

介面程式碼:

    @RequestMapping(value = "test")
    @ResponseBody
    public Object testDataBind(Person person) {
        System.out.println(person.getTests()[0] + "    " + person.getTests()[1]);
        return "success";
    }

Person:

    public class Person {

        private String[] tests;

        public String[] getTests() {
            return tests;
        }

        public void setTests(String[] tests) {
            this.tests = tests;
        }
    }
  • form表單

有兩種形式進行傳值

name="tests" value="arony1"
name="tests" value="arony2"
name="tests[0]" value="arony1"
name="tests[1]" value="arony2"

postman傳送請求:
這裡寫圖片描述
這裡寫圖片描述

控制檯輸出:

arony1    arony2
  • ajax

    ajax也有兩種方式傳值:

data:{"tests":"arony1,arony2"}
data:{"tests[0]":"arony1","tests[1]":"arony2"}

效果跟表單完全一樣。

3. 自定義型別

首先定義一個自定型別User,包含以下屬性,生成get/set方法,toString方法:

    private Integer id;
    private String loginname;

介面程式碼:

    @RequestMapping(value = "test")
    @ResponseBody
    public Object testDataBind(User user) {
        System.out.println(user);
        return "success";
    }

postman傳送請求:
這裡寫圖片描述
控制檯輸出:

User{id=1, loginname='arony'}

可以看到,跟User屬性名一樣的引數如果傳了值,就可以被User物件所接受,沒有傳的為預設值。
我們嘗試下,給引數user加上@RequestParam註解看看。使用postman傳送請求,會發現返回400。所以我們要理解@RequestParam註解含義,它標示的是該方法引數接受的是一個http引數。因此,如果是用一個自定義物件作為引數的話,不要在之前加上@RequestParam,因為SpringMVC在解析http請求的引數user的時候,不能將接收到的引數轉化成一個User物件。

4. 自定義型別陣列/list

注意:這種情況只能使用一個自定義類來包裝陣列/list。
再定義一個引數類:

public class Parameter {

    private Person[] person;

    public Person[] getPerson() {
        return person;
    }

    public void setPerson(Person[] person) {
        this.person = person;
    }
}

Person:

public class Person {

    private String tests;

    public String getTests() {
        return tests;
    }

    public void setTests(String tests) {
        this.tests = tests;
    }
}

介面程式碼:

    @RequestMapping(value = "test")
    @ResponseBody
    public Object testDataBind(Parameter parameter) {
        System.out.println(parameter.getPerson()[0].getTests() + "    " + parameter.getPerson()[1].getTests());
        return "success";
    }
  • form表單傳參
name="person[0].tests" value="arony1"
name="person[1].tests" value="arony2"
  • ajax傳參
data:{"person[0].tests":"arony1","person[1].tests":"arony2"}

postman傳送請求:
這裡寫圖片描述

控制檯輸出:

arony1    arony2

5. Map<String,基本型別>

與上面一樣 這種情況只能使用一個自定義類來包裝map。

Parameter:

public class Parameter {

    private Map<String, String> map;

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }
}

介面程式碼:

    @RequestMapping(value = "test")
    @ResponseBody
    public Object testDataBind(Parameter parameter) {
        parameter.getMap().forEach((key, value) -> {
            System.out.println(key + "   " + value);
        });
        return "success";
    }

前端傳參格式:

  • form表單
name="map[key1]" value="arony1"
name="map[key2]" value="arony2"
或者
name="map.key1" value="arony1"
name="map.key2" value="arony2"
  • ajax
data:{"map[key1]":"arony1","map[key2]":"arony2"}
或者
data:{"map.key1":"arony1","map.key2":"arony2"}

postman傳送請求:
這裡寫圖片描述
這裡寫圖片描述

控制檯輸出:

key1   arony1
key2   arony2

6. Map<String, 自定義類>

跟5是很類似的。
Parameter:

public class Parameter {

    private Map<String, Person> map;

    public Map<String, Person> getMap() {
        return map;
    }

    public void setMap(Map<String, Person> map) {
        this.map = map;
    }
}

Person:

public class Person {

    private String tests;

    public String getTests() {
        return tests;
    }

    public void setTests(String tests) {
        this.tests = tests;
    }
}

介面程式碼:

    @RequestMapping(value = "test")
    @ResponseBody
    public Object testDataBind(Parameter parameter) {
        parameter.getMap().forEach((key, value) -> {
            System.out.println(key + "   " + value.getTests());
        });
        return "success";
    }

前端傳參格式:

  • form表單
name="map[key1].tests" value="arony1"
name="map[key2].test2" value="arony2"

這裡注意,name=”map.key1.tests” value=”arony1”這樣傳值是不行的。必須用方括號。

  • ajax
data={"map[key1].tests":"arony1","map[key2].test2":"arony2"}

這裡也必須使用方括號。

使用postman傳送請求:
這裡寫圖片描述

控制檯輸出:

key1   arony1
key2   arony2

總結

以上的SpringMVC引數繫結可以總結為下圖:

這裡寫圖片描述

其中,Map<String, ①> 前端還可以使用“.”代替方括號。