1. 程式人生 > >SpringMVC 請求引數繫結

SpringMVC 請求引數繫結

什麼是請求引數繫結

請求引數格式

  預設是key/value格式,比如:http:xxxx?id=1&type=2

請求引數值的資料型別

  都是字串型別的各種值

請求引數值要繫結的目標型別

  Controller類中的方法引數,比如簡單型別、POJO型別、集合型別等。

SpringMVC內建的引數解析元件

  預設內建了24種引數解析元件(ArgumentResolver)

什麼是引數繫結?

  就是將請求引數串中的value值獲取到之後,在進行型別轉換,然後將轉換後的值賦值給Controller類中方法的形參,這個過程就是引數繫結

 

 預設支援的引數型別(Servlet API支援)

Controller方法形參中可以隨時新增如下型別的引數,處理介面卡會自動識別並進行賦值。

  • HttpServletRequest
    • 通過request物件獲取請求資訊
  • HttpServletResponse
    • 通過response處理響應資訊
  • HttpSession
    • 通過session物件獲取session中存放的物件
  • InputStream、OutputStream
  • Reader、Writer
  • Model/ModelMap
    • ModelMap繼承自LinkedHashMap,Model是一個介面,它們的底層實現都是同一個類(BindingAwareModelMap),作用就是向頁面傳遞資料,相當於Request的作用,如下

繫結簡單資料型別

簡單型別引數繫結方式

  簡單型別指的就是8種基本型別資料以及它們的包裝類,還有String型別。

  在SpringMVC中,對於java簡單型別的引數,推薦的引數繫結方式有兩種:

  1. 直接繫結
  2. 註解繫結

直接繫結

要求

  http請求引數的key和controller方法的形參名稱一致

請求URL

  http://localhose:8080/xxx/findItem?id=1

  請求引數的key為id

Controller方法

  Controller的形參為Interger id,它和請求引數的key一致,所以直接繫結成功

@RequestMapping(value = "/findItem")
    public String findItem(Integer id) {
         System.out.println("接收到的請求引數是:"+ id);
        return "success";
    }

註解繫結

要求

  請求引數key和controller方法的形參名稱不一致時,需要使用@RequestParam註解才能將請求引數繫結成功。

請求URL

  http://localhost:8080/xxx/findItem?itemId=1

  請求引數的key為itemId

Controller方法

  Controller的形參為Integer id,它和請求的引數不一致,需要使用@RequestParam註解才能繫結成功

     @RequestMapping(value = "/findItem")
    // 通過@RequestParam註解繫結簡單型別
    public String findItem(@RequestParam("itemId") Integer id) {
          System.out.println("接收到的請求引數是:"+ id);
          return "success";
    }

RequestParam註解介紹

  value:引數名字,即入參的請求引數名字,如value="itemId"表示請求的引數中的名字為itemId的引數的值將傳入

  required:是否必須,預設是true,表示請求中一定要有響應的引數,否則將報;

    http Status 400 - Required Integer parameter 'xxx' is not present

  defaultValue:預設值,表示如果請求中沒有同名引數時的預設值

@RequestMapping(value = "/findItem")
    // 通過@RequestParam註解繫結簡單型別
    // 學習@RequestParam註解中的value、required、defaultValue屬性
    public String findItem (
            @RequestParam(value = "itemId", required = true, defaultValue = "2") Integer id) {

         System.out.println("接收到的請求引數是:"+ id);
          return "success";
    }

繫結POJO型別

要求

  控制器方法的引數型別是POJO型別。

  要求表單中引數名稱和POJO類的屬性名稱保持一致。

請求URL

  http://localhost:8080/xxx/updateItem?id=!&name=iphone&price=1000

Controller方法

POJO定義:

 

Controller方法

@RequestMapping("/updateItem")
    public String updateItem(Integer id,Items item) {
        
         System.out.println("接收到的請求引數是:"+ id);
         System.out.println("接收到的請求引數是:"+ item);
        return "success";
    }

繫結包裝POJO

   包裝POJO類,依然是一個POJO,只是說為了方便溝通,將POJO中包含另一個POJO的這種類,稱之為包裝POJO。

包裝物件

public class ItemQueryVO {
    //商品資訊
    private Items item;
}

頁面定義(item-list.jsp)

查詢條件:
        <table width="100%" border=1>
            <tr>
                <td>商品名稱:<input type="text" name="items.name" /></td>
                <td><input type="submit" value="查詢" /></td>
            </tr>
        </table>

Controller方法

 

 測試方法:斷點跟蹤,檢視vo中的item物件是否有值

使用簡單型別陣列接收引數

要求

  通過HTTP請求批量傳遞簡單型別資料的情況,Controller方法中可以用String[]或者POJO的String[]屬性接收(二選一),但是不能使用集合接收。

請求URL

  http://localhost:8080/xxx/deleteItem?id=1&id=2&id=3

Controller方法

    @RequestMapping("/deleteItem")
    public String deleteitem(Integer[] itemId){
        
        return "success";
    }

使用POJO型別集合或陣列接收引數

要求

  批量傳遞的請求引數,最終要使用List<POJO>來接收,那麼這個List<POJO>必須放在另一個POJO類中。

接收商品列表的POJO

public class ItemQueryVO {

    // 商品資訊
    private Item item;
    // 其他資訊

    // 商品資訊集合
    private List<Items> itemsList;
}

請求URL

  http://localhost:8080/xxx/batchUpdateItem?itemsList[0].id=1&itemsList[0].name=iphone&itemsList[0].price=1000&itemsList[1].id=2&itemsList[1].name=華為&items[1].price=5000

Controller

    @RequestMapping("/batchUpdateItem")
    public String batchUpdateItem(ItemQueryVO vo) {
        return "success";
    }

自定義引數繫結

請求URL

  http://localhost:8080/xxx/saveItem?date=2019-12-4

Controller方法

    @RequestMapping("/saveItem")
    public String saveItem(String date){
        System.out.println("接收到的請求引數是:"+ date);
        return "success";
    }

但是如何將date引數的型別有String改為Date,則報錯

自定義Converter

public class DateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

配置Converter

在springmvc.xml中,進行以下配置

    <!-- 載入註解驅動 -->
    <mvc:annotation-driven conversion-service="conversionService"/>
    <!-- 轉換器配置 -->
    <bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.cyb.ssm.controller.converter.DateConverter"/>
            </set>
        </property>
    </bean>