05.springMVC请求参数的绑定

请求参数的绑定

一、一般的参数绑定

1). 绑定的机制

表单中请求参数都是基于key=value的。SpringMVC绑定请求参数的过程是通过把表单提交的请求参数作为控制器中方法参数进行绑定的。

  1. 例如,有一个超链接,其中请求参数是accountId=10
<a href="account/findAccount?accountId=10">查询账户</a>
  1. 对应的控制器(只展示二级访问目录)
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
    System.out.println("查询了账户。。。。" + accountId);
    return "success";
}

2). 支持的数据类型及使用规则

SpringMVC绑定请求参数是框架底层自动实现的。

1. 基本类型参数:【基本类型】 + 【String】

要求参数名称必须和控制器中方法的形参名称保持一致。严格区分大小写

  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:【实体类】 + 【关联的实体类】

表单中参数名称和pojo类的属性名称保持一致,并且控制器方法的参数类型是POJO类型。

  1. 实体类代码
public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;
    private Address address;
    ...get/set/toString/构造函数...

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

public class Address implements Serializable {
    private String provinceName;
    private String cityName;
    ...get/set/toString/构造函数...
  1. jsp标签
<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. 数组和集合类型:【基本数组】 + 【List】 + 【Map】

有两种方式,如下

1. 方式一:POJO类中包含集合类型参数

要求集合类型的请求参数必须在POJO中。在表单中请求参数名称和POJO中集合属性名称相同。
给List集合中的元素赋值,使用下标。
给Map集合中的元素赋值,使用键值对。

  1. pojo相关类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

接收的请求参数是json格式数据。需要借助一个注解实现。

4. 数据类型的自动转换

内置转换器全在org.springframework.core.converter.support包下。内置的转换规则如下:

原始数据类型 ->转换后的类型以及对应的转换器
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
... ...

如果遇到特殊类型转换需求,需要自己编写自定义类型转换器。

二、自定义类型转换器绑定参数

以String转为Date为例

1). 定义一个类,实现Converter接口,该接口有两个泛型

  1. Converter接口的源码!【可千万别自己写,必须的使用Spring提供的Converter接口
/** 实现Converter接口,该接口有两个泛型,
 * S代表接收的类型,T代表目标类型 */
public interface Converter<S, T> {

    /** 实现类型转换的方法 */
    T convert(S source);
}
  1. 实现类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类型转换成日期类型 */
    @Override
    public Date convert(String source) {
        DateFormat format = null;
        try {
            if (StringUtils.isEmpty(source)) {
                throw new NullPointerException("请输入要转换的日期");
            }
            format = new SimpleDateFormat("yyyy-MM-dd");
            return format.parse(source);
        } catch (Exception e) { throw new RuntimeException(e); }
    }
}

2). 在spring配置文件springMVC.xml中配置自定义类型转换器

spring配置类型转换器的机制是将自定义的转换器注册到类型转换服务中去。

<!-- 配置类型转换工厂 -->
<bean id="converterService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <!-- 给工厂注入一个新的类型转化器 -->
    <property name="converters">
        <array>
            <!-- 配置自定义类型转换器 -->
            <bean class="com.itheima.converter.impl.StringToDateConverter"></bean>
        </array>
    </property>
</bean>

3). 在<annotation-driven>标签中应用配合的类型转换服务

<!-- 配置spring开启注解mvc的支持,并引用自定义类型转换器 -->
<mvc:annotation-driven
    conversion-service="converterService"></mvc:annotation-driven>

4). 测试代码

  1. jsp核心代码
<%-- 特殊情况值:类型转换问题! --%>
<a href="account/deleteAccount?date=2019-01-01">根据日期删除账户</a>
  1. 控制器代码
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 删除账户 */
    @RequestMapping("/deleteAccount")
    public String deleteAccount(Date date) {
        System.out.println(date);
        return "success";
    }
}

三、 使用ServletAPI对象作为方法参数

SpringMVC还支持使用原始ServletAPI对象作为控制器方法的参数。可以将这些对象直接写在控制的方法参数中并使用

支持原始Servlet的对象
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer

). 实例代码

  1. jsp核心代码
<%-- 原始ServletAPI作为控制器参数 --%>
<a href="account/testServletAPI">测试访问ServletAPI</a>
  1. 控制器代码
@Controller
@RequestMapping("/account")
public class AccountController {

    /** 测试访问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";
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容