05.springMVC請(qǐng)求參數(shù)的綁定

請(qǐng)求參數(shù)的綁定

一废封、一般的參數(shù)綁定

1). 綁定的機(jī)制

表單中請(qǐng)求參數(shù)都是基于key=value的窒所。SpringMVC綁定請(qǐng)求參數(shù)的過(guò)程是通過(guò)把表單提交的請(qǐng)求參數(shù)作為控制器中方法參數(shù)進(jìn)行綁定的躬窜。

  1. 例如,有一個(gè)超鏈接,其中請(qǐng)求參數(shù)是accountId=10
<a href="account/findAccount?accountId=10">查詢賬戶</a>
  1. 對(duì)應(yīng)的控制器(只展示二級(jí)訪問(wèn)目錄)
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
    System.out.println("查詢了賬戶。做修。脚猾。葱峡。" + accountId);
    return "success";
}

2). 支持的數(shù)據(jù)類型及使用規(guī)則

SpringMVC綁定請(qǐng)求參數(shù)是框架底層自動(dòng)實(shí)現(xiàn)的。

1. 基本類型參數(shù):【基本類型】 + 【String】

要求參數(shù)名稱必須和控制器中方法的形參名稱保持一致龙助。嚴(yán)格區(qū)分大小寫(xiě)

  1. jsp代碼
<a href="account/findAccount?accountId=10&accountName=zhangsan">查詢賬戶</a>
  1. 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 查詢賬戶 */
    @RequestMapping("/findAccount")
    public String findAccount(Integer accountId, String accountName) {
        System.out.println("查詢了賬戶:" + accountId + "  姓名:" + accountName);
        return "success";
    }
}

2. POJO:【實(shí)體類】 + 【關(guān)聯(lián)的實(shí)體類】

表單中參數(shù)名稱和pojo類的屬性名稱保持一致砰奕,并且控制器方法的參數(shù)類型是POJO類型。

  1. 實(shí)體類代碼
public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;
    private Address address;
    ...get/set/toString/構(gòu)造函數(shù)...

/*- - - - - - - - - - - - - - - - - - */

public class Address implements Serializable {
    private String provinceName;
    private String cityName;
    ...get/set/toString/構(gòu)造函數(shù)...
  1. jsp標(biāo)簽
<form action="account/saveAccount" method="post">
    賬戶名稱: <input type="text" name="name"> <br>
    賬戶金額: <input type="text" name="money"> <br>
    賬戶省份: <input type="text" name="address.provinceName"> <br>
    賬戶城市: <input type="text" name="address.cityName"> <br>
    <input type="submit" value="保存">
</form>
  1. 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 保存賬戶 */
    @RequestMapping("saveAccount")
    public String saveAccount(Account account) {
        System.out.println(account);
        return "success";
    }
}

3. 數(shù)組和集合類型:【基本數(shù)組】 + 【List】 + 【Map】

有兩種方式提鸟,如下

1. 方式一:POJO類中包含集合類型參數(shù)

要求集合類型的請(qǐng)求參數(shù)必須在POJO中军援。在表單中請(qǐng)求參數(shù)名稱和POJO中集合屬性名稱相同。
給List集合中的元素賦值沽一,使用下標(biāo)盖溺。
給Map集合中的元素賦值,使用鍵值對(duì)铣缠。

  1. pojo相關(guān)類User
public class User implements Serializable {
    private String username;
    private String password;
    private Integer age;
    private List<Account> accounts;
    private Map<String, Account> accountMap;
    ... get/set/toString ...
  1. jsp代碼
<form action="account/updateAccount" method="post">
    用戶名稱:<input type="text" name="username"> <br>
    用戶密碼:<input type="password" name="password"> <br>
    用戶年齡:<input type="text" name="age"> <br>

    <%-- List --%>
    賬戶1名稱:<input type="text" name="accounts[0].name"> <br>
    賬戶1金額: <input type="text" name="accounts[0].money"> <br>
    賬戶1省份:<input type="text" name="accounts[0].address.provinceName"> <br>
    賬戶1城市: <input type="text" name="accounts[0].address.cityName"> <br>

    <%-- Map --%>
    賬戶2名稱:<input type="text" name="accountMap['one'].name"> <br>
    賬戶2金額:<input type="text" name="accountMap['one'].money"> <br>
    賬戶2省份:<input type="text" name="accountMap['one'].address.provinceName"> <br>
    賬戶2城市:<input type="text" name="accountMap['one'].address.cityName"> <br>
    <input type="submit" value="保存">
</form>
  1. 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 更新賬戶 */
    @RequestMapping("/updateAccount")
    public String updateAccount(User user) {
        System.out.println(user);
        return "success";
    }
}
2. 方式二:JSON

接收的請(qǐng)求參數(shù)是json格式數(shù)據(jù)烘嘱。需要借助一個(gè)注解實(shí)現(xiàn)昆禽。

4. 數(shù)據(jù)類型的自動(dòng)轉(zhuǎn)換

內(nèi)置轉(zhuǎn)換器全在org.springframework.core.converter.support包下。內(nèi)置的轉(zhuǎn)換規(guī)則如下:

原始數(shù)據(jù)類型 ->轉(zhuǎn)換后的類型以及對(duì)應(yīng)的轉(zhuǎn)換器
java.lang.Boolean -> java.lang.String : ObjectToStringConverter
java.lang.Character -> java.lang.Number : CharacterToNumberFactory
java.lang.Character -> java.lang.String : ObjectToStringConverter
java.lang.Enum -> java.lang.String : EnumToStringConverter
java.lang.Number -> java.lang.Character : NumberToCharacterConverter
java.lang.Number -> java.lang.Number : NumberToNumberConverterFactory
java.lang.Number -> java.lang.String : ObjectToStringConverter
java.lang.String -> java.lang.Boolean : StringToBooleanConverter
java.lang.String -> java.lang.Character : StringToCharacterConverter
java.lang.String -> java.lang.Enum : StringToEnumConverterFactory
java.lang.String -> java.lang.Number : StringToNumberConverterFactory
java.lang.String -> java.util.Locale : StringToLocaleConverter
java.lang.String -> java.util.Properties : StringToPropertiesConverter
java.lang.String -> java.util.UUID : StringToUUIDConverter
java.util.Locale -> java.lang.String : ObjectToStringConverter
java.util.Properties -> java.lang.String : PropertiesToStringConverter
java.util.UUID -> java.lang.String : ObjectToStringConverter
... ...

如果遇到特殊類型轉(zhuǎn)換需求蝇庭,需要自己編寫(xiě)自定義類型轉(zhuǎn)換器醉鳖。

二、自定義類型轉(zhuǎn)換器綁定參數(shù)

以String轉(zhuǎn)為Date為例

1). 定義一個(gè)類哮内,實(shí)現(xiàn)Converter接口盗棵,該接口有兩個(gè)泛型

  1. Converter接口的源碼!【可千萬(wàn)別自己寫(xiě)北发,必須的使用Spring提供的Converter接口
/** 實(shí)現(xiàn)Converter接口纹因,該接口有兩個(gè)泛型,
 * S代表接收的類型琳拨,T代表目標(biāo)類型 */
public interface Converter<S, T> {

    /** 實(shí)現(xiàn)類型轉(zhuǎn)換的方法 */
    T convert(S source);
}
  1. 實(shí)現(xiàn)類StringToDateConverter
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class StringToDateConverter implements Converter<String, Date> {

    /** 將String類型轉(zhuǎn)換成日期類型 */
    @Override
    public Date convert(String source) {
        DateFormat format = null;
        try {
            if (StringUtils.isEmpty(source)) {
                throw new NullPointerException("請(qǐng)輸入要轉(zhuǎn)換的日期");
            }
            format = new SimpleDateFormat("yyyy-MM-dd");
            return format.parse(source);
        } catch (Exception e) { throw new RuntimeException(e); }
    }
}

2). 在spring配置文件springMVC.xml中配置自定義類型轉(zhuǎn)換器

spring配置類型轉(zhuǎn)換器的機(jī)制是將自定義的轉(zhuǎn)換器注冊(cè)到類型轉(zhuǎn)換服務(wù)中去瞭恰。

<!-- 配置類型轉(zhuǎn)換工廠 -->
<bean id="converterService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <!-- 給工廠注入一個(gè)新的類型轉(zhuǎn)化器 -->
    <property name="converters">
        <array>
            <!-- 配置自定義類型轉(zhuǎn)換器 -->
            <bean class="com.itheima.converter.impl.StringToDateConverter"></bean>
        </array>
    </property>
</bean>

3). 在<annotation-driven>標(biāo)簽中應(yīng)用配合的類型轉(zhuǎn)換服務(wù)

<!-- 配置spring開(kāi)啟注解mvc的支持,并引用自定義類型轉(zhuǎn)換器 -->
<mvc:annotation-driven
    conversion-service="converterService"></mvc:annotation-driven>

4). 測(cè)試代碼

  1. jsp核心代碼
<%-- 特殊情況值:類型轉(zhuǎn)換問(wèn)題狱庇! --%>
<a href="account/deleteAccount?date=2019-01-01">根據(jù)日期刪除賬戶</a>
  1. 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 刪除賬戶 */
    @RequestMapping("/deleteAccount")
    public String deleteAccount(Date date) {
        System.out.println(date);
        return "success";
    }
}

三惊畏、 使用ServletAPI對(duì)象作為方法參數(shù)

SpringMVC還支持使用原始ServletAPI對(duì)象作為控制器方法的參數(shù)。可以將這些對(duì)象直接寫(xiě)在控制的方法參數(shù)中并使用

支持原始Servlet的對(duì)象
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer

). 實(shí)例代碼

  1. jsp核心代碼
<%-- 原始ServletAPI作為控制器參數(shù) --%>
<a href="account/testServletAPI">測(cè)試訪問(wèn)ServletAPI</a>
  1. 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 測(cè)試訪問(wèn)testServletAPI */
    @RequestMapping("/testServletAPI")
    public String testServletAPI(HttpServletRequest request,
                                 HttpServletResponse response,
                                 HttpSession session) {
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
        return "success";
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末密任,一起剝皮案震驚了整個(gè)濱河市颜启,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浪讳,老刑警劉巖缰盏,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異驻债,居然都是意外死亡乳规,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門合呐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)暮的,“玉大人,你說(shuō)我怎么就攤上這事淌实《潮纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵拆祈,是天一觀的道長(zhǎng)恨闪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)放坏,這世上最難降的妖魔是什么咙咽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮淤年,結(jié)果婚禮上钧敞,老公的妹妹穿的比我還像新娘蜡豹。我一直安慰自己,他們只是感情好溉苛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布镜廉。 她就那樣靜靜地躺著,像睡著了一般愚战。 火紅的嫁衣襯著肌膚如雪娇唯。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天寂玲,我揣著相機(jī)與錄音塔插,去河邊找鬼。 笑死敢茁,一個(gè)胖子當(dāng)著我的面吹牛佑淀,可吹牛的內(nèi)容都是我干的留美。 我是一名探鬼主播彰檬,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谎砾!你這毒婦竟也來(lái)了逢倍?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤景图,失蹤者是張志新(化名)和其女友劉穎较雕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體挚币,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亮蒋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妆毕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慎玖。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖笛粘,靈堂內(nèi)的尸體忽然破棺而出趁怔,到底是詐尸還是另有隱情,我是刑警寧澤薪前,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布润努,位于F島的核電站,受9級(jí)特大地震影響示括,放射性物質(zhì)發(fā)生泄漏铺浇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一垛膝、第九天 我趴在偏房一處隱蔽的房頂上張望鳍侣。 院中可真熱鬧裁着,春花似錦、人聲如沸拱她。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)秉沼。三九已至桶雀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間唬复,已是汗流浹背矗积。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留敞咧,地道東北人棘捣。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像休建,于是被迫代替她去往敵國(guó)和親乍恐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容