首頁 > 軟體

SpringBoot獲取前臺引數的六種方式以及統一響應

2023-03-31 06:01:20

請求

SpringBoot接受前臺引數的六種方式,首先因為從前臺傳送的請求沒有介面的話只能是從位址列傳送並且只能是Get請求,為了測試其他的請求,所以我們使用一個工具->Postman,Postman是一款功能強大的網頁偵錯與傳送網頁HTTP請求的Chrome外掛。

對於前臺傳過來的引數大致分為六種,下面一個一個的做演示學習:演示之前先複習一下,沒用SpringBoot獲取前臺引數的方式,通過request物件獲取。

@RestController
public class RequestController {
    //原始方式
    @RequestMapping("/simpleParam")
    public String simpleParam(HttpServletRequest request){
        // http://localhost:8080/simpleParam?name=Tom&age=10
        // 請求引數: name=Tom&age=10   (有2個請求引數)
        // 第1個請求引數: name=Tom   引數名:name,引數值:Tom
        // 第2個請求引數: age=10     引數名:age , 引數值:10

        String name = request.getParameter("name");//name就是請求引數名
        String ageStr = request.getParameter("age");//age就是請求引數名

        int age = Integer.parseInt(ageStr);//需要手動進行型別轉換
        System.out.println(name+"  :  "+age);
        return "OK";
    }
}

在Springboot的環境中,對原始的API進行了封裝,接收引數的形式更加簡單。 如果是簡單引數,引數名與形參變數名相同,定義同名的形參即可接收引數。

1、簡單引數

@RestController
public class RequestController {
        // http://localhost:8080/simpleParam?name=Tom&age=10
    // 第1個請求引數: name=Tom   引數名:name,引數值:Tom
    // 第2個請求引數: age=10     引數名:age , 引數值:10
    
    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(String name , Integer age ){//形參名和請求引數名保持一致
        System.out.println(name+"  :  "+age);
        return "OK";
    }
}

如果後臺需要但是前臺並沒傳對應的引數,這個時候會返回 null

當前臺傳的引數名和後臺接受引數的方法形參列表不一致的時候,可以通過@RequestParam(“ ”)來指定

@RestController
public class RequestController {
    // http://localhost:8080/simpleParam?name=Tom&age=20
    // 請求引數名:name

    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam("name") String username , Integer age ){
        System.out.println(username+"  :  "+age);
        return "OK";
    }
}

另外@RequestParam中的required屬性預設為true(預設值也是true),代表該請求引數必須傳遞,如果不傳遞將報錯,如果該引數是可選的,可以將required屬性設定為false

程式碼如下:

@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age){
    System.out.println(username+ ":" + age);
    return "OK";
}

這個註解還有一個引數,是defaultValue表示如果前臺沒有傳遞引數就預設為當前指定的值。

    @RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam(name = "name", required = false,defaultValue ="匿名使用者") String userName, Integer age) {
        
//        列印輸出
        System.out.println(userName+"----"+age);
        return "ok";
    }

2、實體引數

簡單實體物件:

在使用簡單引數做為資料傳遞方式時,前端傳遞了多少個請求引數,後端controller方法中的形參就要書寫多少個。如果請求引數比較多,通過上述的方式一個引數一個引數的接收,會比較繁瑣。

此時,我們可以考慮將請求引數封裝到一個實體類物件中。 要想完成資料封裝,需要遵守如下規則:請求引數名與實體類的屬性名相同

要求是前臺傳過來的引數必須和物件中的引數名稱相同,順序相同。

@RestController
public class RequestController {
    // http://localhost:8080/simpleParam?name=Tom&age=20
    
    //實體引數:簡單實體物件  User有兩個屬性,一個是name 一個是age,這樣Spring就會自動完成賦值
    @RequestMapping("/simplePojo")
    public String simplePojo(User user){
        System.out.println(user);
        return "OK";
    }
}

複雜實體物件:物件套物件

比如說User中又多了一個欄位: Address 而這個類又有兩個屬性,這個時候前臺傳遞引數的時候就需要發生改變,後臺還是用User接受

public class User {
    private String name;
    private Integer age;
    private Address address; //地址物件
    .....
}


public class Address {
    private String province;
    private String city;
    .....
}

方法程式碼

@RestController
public class RequestController {
    //實體引數:複雜實體物件
    @RequestMapping("/complexPojo")
    public String complexPojo(User user){
        System.out.println(user);
        return "OK";
    }
}

3、陣列集合引數

陣列集合引數的使用場景:在HTML的表單中,有一個表單項是支援多選的(核取方塊),可以提交選擇的多個值。

xxxxxxxx?hobby=game&hobby=java

後端程式接收上述多個值的方式有兩種:

  • 陣列
  • 集合

陣列引數:請求引數名與形引陣列名稱相同且請求引數為多個,定義陣列型別形參即可接收引數

@RestController
public class RequestController {
    //陣列集合引數
    @RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby){
        System.out.println(Arrays.toString(hobby));
        return "OK";
    }
}

集合引數:請求引數名與形參集合物件名相同且請求引數為多個,@RequestParam 繫結引數關係

預設情況下,請求中引數名相同的多個值,是封裝到陣列。如果要封裝到集合,要使用@RequestParam繫結引數關係

Controller方法:

@RestController
public class RequestController {
    //陣列集合引數
    @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return "OK";
    }
}

4、日期引數

上述演示的都是一些普通的引數,在一些特殊的需求中,可能會涉及到日期型別資料的封裝(其實我們一般都存字串,不會轉來轉去,所以這裡瞭解)。比如,如下需求:

因為日期的格式多種多樣(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那麼對於日期型別的引數在進行封裝的時候,需要通過@DateTimeFormat註解,以及其pattern屬性來設定日期的格式。

  • @DateTimeFormat註解的pattern屬性中指定了哪種日期格式,前端的日期引數就必須按照指定的格式傳遞。
  • 後端controller方法中,需要使用Date型別 LocalDateT或LocalDateTime型別,來封裝傳遞的引數。

Controller方法:

@RestController
public class RequestController {
    //日期時間引數
   @RequestMapping("/dateParam")
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
        System.out.println(updateTime);
        return "OK";
    }
}

5、JSON引數

在學習前端技術時,我們有講到過JSON,而在前後端進行互動時,如果是比較複雜的引數,前後端通過會使用JSON格式的資料進行傳輸。 (JSON是開發中最常用的前後端資料互動方式) ,其實我們也會看到, 後臺如果返回給前臺資料的時候,有的是字串,又的是集合,有的是JSON, 那麼前臺在解析的時候就十分的麻煩, 後來經過一個實體類用來存放所有的資料, 然後返回這個物件, 這樣前臺在接受的時候只要處理JSON就好.在筆記的最後會提到

下面介紹在Postman中怎麼傳送JSON資料:

伺服器端Controller方法接收JSON格式資料:

  • 傳遞json格式的引數,在Controller中會使用實體類進行封裝。
  • 封裝規則:JSON資料鍵名與形參物件屬性名相同,定義POJO型別形參即可接收引數。需要使用 @RequestBody標識。

@RequestBody註解:將JSON資料對映到形參的實體類物件中(JSON中的key和實體類中的屬性名保持一致)

通過新增@RequestBody註解Spring可以自動的將JSON轉換為物件.

實體類:

public class User {
    private String name;
    private Integer age;
    private Address address;
    
    //省略GET , SET 方法
}  
@RestController
public class RequestController {
    //JSON引數
    @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user){
        System.out.println(user);
        return "OK";
    }
}

6、路徑引數(開發中使用的模式)

傳統的開發中請求引數是放在請求體(POST請求)傳遞或跟在URL後面通過?key=value的形式傳遞(GET請求)。

在現在的開發中,經常還會直接在請求的URL中傳遞引數。例如:

http://localhost:8080/user/1        
http://localhost:880/user/1/0

上述的這種傳遞請求引數的形式呢,我們稱之為:路徑引數。

學習路徑引數呢,主要掌握在後端的controller方法中,如何接收路徑引數。

路徑引數:

  • 前端:通過請求URL直接傳遞引數
  • 後端:使用{…}來標識該路徑引數,需要使用@PathVariable獲取路徑引數

Controller方法:

@RestController
public class RequestController {
    //路徑引數
    @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id){
        System.out.println(id);
        return "OK";
    }
}

傳遞多個路徑引數:

@RestController
public class RequestController {
    //路徑引數  前臺路徑  xxxx/path/12/jack
    @RequestMapping("/path/{id}/{name}")
    public String pathParam2(@PathVariable Integer id, @PathVariable String name){
        System.out.println(id+ " : " +name);
        return "OK";
    }
}

響應:

前面我們學習過HTTL協定的互動方式:請求響應模式(有請求就有響應)

那麼Controller程式呢,除了接收請求外,還可以進行響應。先說一下使用到的註解:

@ResponseBody

  • 型別:方法註解、類註解
  • 位置:書寫在Controller方法上或類上
  • 作用:將方法返回值直接響應給瀏覽器

如果返回值型別是實體物件/集合,將會轉換為JSON格式後在響應給瀏覽器

在我們前面所編寫的controller方法中,都已經設定了響應資料。看一下類的註解@RestController, 這個註解是一個複合註解,裡面包括了 @ResponseBody

結論:在類上新增@RestController就相當於新增了@ResponseBody註解。

類上有@RestController註解或@ResponseBody註解時:表示當前類下所有的方法返回值做為響應資料方法的返回值,如果是一個POJO物件或集合時,會先轉換為JSON格式,在響應給瀏覽器

下面我們來測試下響應資料:

@RestController
public class ResponseController {
    //響應字串
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("Hello World ~");
        return "Hello World ~";
    }
    //響應實體物件
    @RequestMapping("/getAddr")
    public Address getAddr(){
        Address addr = new Address();//建立實體類物件
        addr.setProvince("廣東");
        addr.setCity("深圳");
        return addr;
    }
    //響應集合資料
    @RequestMapping("/listAddr")
    public List<Address> listAddr(){
        List<Address> list = new ArrayList<>();//集合物件
        
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");

        Address addr2 = new Address();
        addr2.setProvince("陝西");
        addr2.setCity("西安");

        list.add(addr);
        list.add(addr2);
        return list;
    }
}

在服務響應了一個物件或者集合,那私前端獲取到的資料是什麼樣子的呢?我們使用postman傳送請求來測試下。測試效果如下:

統一響應結果

可能大家會發現,我們在前面所編寫的這些Controller方法中,返回值各種各樣,沒有任何的規範。

如果我們開發一個大型專案,專案中controller方法將成千上萬,使用上述方式將造成整個專案難以維護。那在真實的專案開發中是什麼樣子的呢?

在真實的專案開發中,無論是哪種方法,我們都會定義一個統一的返回結果。方案如下:

這樣前端只需要按照統一格式的返回結果進行解析(僅一種解析方案),就可以拿到資料。

統一的返回結果使用類來描述,在這個結果中包含:

  • 響應狀態碼:當前請求是成功,還是失敗
  • 狀態碼資訊:給頁面的提示資訊
  • 返回的資料:給前端響應的資料(字串、物件、集合)

定義在一個實體類Result來包含以上資訊。程式碼如下:

public class Result {
    private Integer code;//響應碼,1 代表成功; 0 代表失敗
    private String msg;  //響應碼 描述字串
    private Object data; //返回的資料

    public Result() { }
    public Result(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    //增刪改 成功響應(不需要給前端返回資料)
    public static Result success(){
        return new Result(1,"success",null);
    }
    //查詢 成功響應(把查詢結果做為返回資料響應給前端)
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    //失敗響應
    public static Result error(String msg){
        return new Result(0,msg,null);
    }
}

改造後的Controller:統一返回Result

@RestController
public class ResponseController { 
    //響應統一格式的結果
    @RequestMapping("/hello")
    public Result hello(){
        System.out.println("Hello World ~");
        //return new Result(1,"success","Hello World ~");
        return Result.success("Hello World ~");
    }

    //響應統一格式的結果
    @RequestMapping("/getAddr")
    public Result getAddr(){
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");
        return Result.success(addr);
    }

    //響應統一格式的結果
    @RequestMapping("/listAddr")
    public Result listAddr(){
        List<Address> list = new ArrayList<>();

        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");

        Address addr2 = new Address();
        addr2.setProvince("陝西");
        addr2.setCity("西安");

        list.add(addr);
        list.add(addr2);
        return Result.success(list);
    }
}

 到此這篇關於SpringBoot獲取前臺引數的六種方式以及統一響應的文章就介紹到這了,更多相關SpringBoot獲取前臺引數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com