(二)Spring MVC 入门教程之请求参数绑定

一、请求参数绑定概念介绍

这部分的内容是很重要的,希望认真看。 那么问题来了,什么是请求参数绑定呢?举个例子:我们在注册账号的时候,我们需要填写用户名、密码、邮箱等。那么如何对这些手动输入的数据进行操作呢?这个时候就需要进行参数的绑定。 更多的详情介绍如下:

######## 一、请求参数绑定的相关说明

#### 1、绑定机制
表单提交的数据都是 k=v 格式的。例如:username=haha&password=123
SpringMVC 的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
要求:提交表单的 name 属性和参数的名称是相同的

#### 2、支持的数据类型
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map 集合等)


######## 二、基本数据类型和字符串类型
提交表单的 name 属性和参数的名称是相同的
区分大小写

######## 三、实体类型(JavaBean)
提交表单的 name 属性和 JavaBean 中的属性名称需要一致
如果一个 JavaBean 类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性。例如:user.age

######## 四、集合属性数据封装
JSP 页面编写方式:list[0].xxx 属性


######## 五、请求参数中文乱码的解决
在 web.xml 中配置 Spring 提供的过滤器类

二、基本类型封装

1、编写 param.jsp 页面

第一步:在 WEB-INF/pages/ 目录下新建 param.jsp 页面。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>请求参数绑定</title>
</head>
<body>

<h2>请求参数绑定成功!!!</h2>

</body>
</html>

2、编写 ParamController 控制器

第二步:新建 ParamController 控制器,用于接收路径中的请求参数。 代码如下:

package club.guoshizhan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 请求参数绑定
 */
@Controller
@RequestMapping("/param")
public class ParamController {

    @RequestMapping("/testParam")
    public String testParam(String username, String password) {
        System.out.println("请求参数入门……");
        System.out.println(username);
        System.out.println(password);
        return "param";
    }
    
}

3、重写 index.jsp 页面

第三步:重写 index.jsp 页面。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>SpringMVC</title>
</head>
<body>

<h3>SpringMVC 入门程序</h3>
    <a href="/hello">SpringMVC 入门程序</a><br>
    <a href="param/testParam?username=Java&password=123">SpringMVC 的请求参数绑定</a>
</body>
</html>

4、启动 tomcat 进行测试

最后:启动 tomcat 服务器进行测试。 结果如下:

控制器输出的结果如下:

请求参数入门……
Java
123

你以为到这里,请求参数就结束了? 肯定不是啦,还有好多内容的呢。接下来搞定实体类型的封装

三、实体类型封装

1、编写实体类

第一步:编写 Account 实体类,让其作为方法的一个参数用于数据的封装。 代码如下:

package club.guoshizhan.domain;

import java.io.Serializable;

public class Account implements Serializable {

    private String username;
    private String password;
    private Double money;

    // 此处省略 getXxx/setXxx 方法以及 toString 方法
}

2、编写 param.jsp 页面

第二步:编写 param.jsp 页面,提供表单相关代码,作为参数传到后台。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>请求参数绑定</title>
</head>
<body>
    <%-- 把数据封装 Account 类中 --%>
    <%-- 注意:表单中 name 属性的值要和实体类中的属性的名字一样才能实现封装 --%>
    <form action="/param/saveAccount" method="post">
        姓名:<input type="text" name="username" /><br/>
        密码:<input type="text" name="password" /><br/>
        金额:<input type="text" name="money" /><br/>
        <input type="submit" value="提交" />
    </form>
</body>
</html>

3、编写 ParamController 控制器

第三步:编写 ParamController 类。 代码如下:

package club.guoshizhan.controller;

import club.guoshizhan.domain.Account;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 请求参数绑定
 */
@Controller
@RequestMapping("/param")
public class ParamController {

    // 请求参数绑定入门
    @RequestMapping("/testParam")
    public String testParam(String username, String password) {
        System.out.println("请求参数入门……");
        System.out.println(username);
        System.out.println(password);
        return "param";
    }

    // 把数据封装到 JavaBean 中,即我们的实体类中
    @RequestMapping("/saveAccount")
    public String testSaveAccount(Account account) {
        System.out.println("请求参数入门……");
        System.out.println(account);
        return "success";
    }

    @RequestMapping("/toParam")
    public String toParam() {
        return "param";
    }

}

4、编写 index.jsp 页面

第四步:编写 index.jsp 页面。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>SpringMVC</title>
</head>
<body>
    <h3>SpringMVC 入门程序</h3>
    <a href="hello">SpringMVC 入门程序</a><br>
    <a href="param/testParam?username=Java&password=123">SpringMVC 的请求参数绑定</a><br>
    <a href="param/toParam">SpringMVC 的请求参数绑定之封装 JavaBean 对象</a>
</body>
</html>

5、启动 tomcat 进行测试

最后:启动 tomcat 服务器进行测试。 结果如下:

控制器输出的结果如下:

请求参数入门……
Account{username='Java', password='123', money=1000.0}

那么问题来了,如果 Account 类中包含 User 类的引用,那该引用类型如何封装数据呢?

四、引用类型封装

1、编写实体类

第一步:编写 User 实体类。 代码如下:

package club.guoshizhan.domain;

import java.io.Serializable;

public class User implements Serializable {

    private String uname;
    private Integer age;

   // 此处省略 getXxx/setXxx 方法以及 toString 方法
}

第二步:重新编写 Account 实体类。 代码如下:

package club.guoshizhan.domain;

import java.io.Serializable;

public class Account implements Serializable {

    private String username;
    private String password;
    private Double money;

    private User user;

    // 此处省略 getXxx/setXxx 方法以及 toString 方法
}

2、编写 param.jsp 页面

第三步:重新编写 param.jsp 页面(引用类型如何封装数据就在其中)。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>请求参数绑定</title>
</head>
<body>
    <%-- 把数据封装 Account 类中 --%>
    <%-- 注意:表单中 name 属性的值要和实体类中的属性的名字一样才能实现封装 --%>
    <form action="/param/saveAccount" method="post">
        姓名:<input type="text" name="username" /><br/>
        密码:<input type="text" name="password" /><br/>
        金额:<input type="text" name="money" /><br/>

        <%-- 类中存在 User 对象,那么取值使用 user.xxx 来取值 --%>
        用户姓名:<input type="text" name="user.uname" /><br/>
        用户年龄:<input type="text" name="user.age" /><br/>
        <input type="submit" value="提交" />
    </form>
</body>
</html>

3、启动 tomcat 进行测试

最后:启动 tomcat 服务器进行测试。 结果如下:

控制器输出的结果如下:

请求参数入门……
Account{username='Java', password='123', money=1000.0, user=User{uname='Python', age=23}}

由上面的示例可知,我们的输入都是英文,这是因为如果输入中文的话,控制台会乱码。 所以,我们现在需要解决这个 中文乱码问题

4、中文乱码问题

那么如何解决中文乱码呢?在 web.xml 配置文件中加入如下代码(写在 <web-app> 标签里面)。 代码如下:

<!-- 配置解决中文乱码的过滤器 -->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

配置好之后,重启项目,然后在表单输入中文,提交之后,发现控制台就不乱码了

五、集合类型封装

1、编写实体类

第一步:重新编写 Account 实体类,新加了 list 属性和 map 属性。 代码如下:

package club.guoshizhan.domain;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class Account implements Serializable {

    private String username;
    private String password;
    private Double money;

    private List<User> list;
    private Map<String, User> map;

    // 此处省略 getXxx/setXxx 方法以及 toString 方法
}

2、编写 param.jsp 页面

第二步:重新编写 param.jsp 页面(集合类型如何封装数据就在其中)。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>请求参数绑定</title>
</head>
<body>
    <%-- 把数据封装 Account 类中 --%>
    <%-- 注意:表单中 name 属性的值要和实体类中的属性的名字一样才能实现封装 --%>
    <form action="/param/saveAccount" method="post">
        姓名:<input type="text" name="username" /><br/>
        密码:<input type="text" name="password" /><br/>
        金额:<input type="text" name="money" /><br/>

        <%-- 类中存在 list 集合,取值方式如下 --%>
        用户姓名:<input type="text" name="list[0].uname" /><br/>
        用户年龄:<input type="text" name="list[0].age" /><br/>

        <%-- 类中存在 map 集合,取值方式如下 --%>
        用户姓名:<input type="text" name="map['one'].uname" /><br/>
        用户年龄:<input type="text" name="map['one'].age" /><br/>
        <input type="submit" value="提交" />
    </form>
</body>
</html>

3、启动 tomcat 进行测试

最后:启动 tomcat 服务器进行测试。 结果如下:

控制器输出的结果如下:

请求参数入门……
Account{username='Java', password='123', money=1000.0, list=[User{uname='Java-用户', age=23}], map={one=User{uname='python-用户', age=24}}}

到这里为止,请求参数绑定基本就介绍完了。 接下来再介绍一个知识点:自定义类型转换器

六、自定义类型转换器

从页面提交的数据,全部都是以【字符串方式】提交。比如 age 输入框中的 30,它是字符串类型,而不是 Integer 类型。 那么这样的话,Spring MVC 框架又是如何把数据封装成功的呢?欲知结果如何,往下看!!!

1、编写实体类

第一步:重新编写 User 类,新加了一个 Date 类型的属性。 代码如下:

package club.guoshizhan.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

    private String uname;
    private Integer age;
    private Date birthday;

    // 此处省略 getXxx/setXxx 方法以及 toString 方法
}

2、编写 param.jsp 页面

第二步:重新编写 param.jsp 页面。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>请求参数绑定</title>
</head>
<body>
    <%-- 自定义类型转换器 --%>
    <form action="/param/saveUser" method="post">
        用户姓名:<input type="text" name="uname" /><br/>
        用户年龄:<input type="text" name="age" /><br/>
        用户生日:<input type="text" name="birthday" /><br/>
        <input type="submit" value="提交" />
    </form>
</body>
</html>

3、添加测试方法

第三步:给 ParamController 类新加如下方法。 代码如下:

// 自定义的类型转换器
@RequestMapping("/saveUser")
public String saveUser(User user) {
    System.out.println("自定义的类型转换器……");
    System.out.println(user);
    return "success";
}

4、启动 tomcat 进行测试

最后:启动 tomcat 服务器进行测试。 结果如下:

控制器输出的结果如下:

自定义的类型转换器……
User{uname='Java', age=23, birthday=Thu Sep 17 00:00:00 CST 2020}

5、输入特殊格式

上述的封装结果是成功了的,那换一种日期的输入方式,就不能成功了。例如:2020-9-16 ,以此种方式输入,程序会报错。结果如下:

那我们如何去解决上述的报错问题呢? 解决这种类型转换的问题就需要 自定义的类型转换器

6、自定义的类型转换器

第一步:编写 StringToDateConverter 转换器类。 代码如下:

package club.guoshizhan.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义类型转换器,把字符串以指定的格式转换成日期类型,需要实现 Converter 接口
 */
public class StringToDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        if (source == null) {
            throw new RuntimeException("您未输入数据!!!");
        }

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        try {
            return df.parse(source);
        } catch (Exception e) {
            throw new RuntimeException("数据转换出现错误!!!");
        }
    }

}

第二步:编写 SpringMvc.xml 配置文件,新加自定义类型转换器相关的配置。 代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="club.guoshizhan"/>

    <!-- 视图解析器对象,让 controller 里面的方法知道去哪个地方找页面 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 配置自定义类型转换器 -->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="club.guoshizhan.utils.StringToDateConverter"/>
            </set>
        </property>
    </bean>

    <!-- 开启 SpringMVC 框架注解的支持,并把自己定义的类型转换器也配置一下使其生效 -->
    <mvc:annotation-driven conversion-service="conversionService"/>

</beans>

配置完成之后,重启 tomcat 服务器。 结果如下:

控制器输出的结果如下:

自定义的类型转换器……
User{uname='Java', age=23, birthday=Thu Sep 17 00:00:00 CST 2020}

七、获取 Servlet 的原生 API

1、编写 param.jsp 页面

第一步:重新编写 param.jsp 页面。 代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>请求参数绑定</title>
</head>
<body>
    <a href="/param/testServlet">获取 Servlet 原生的 API</a>
</body>
</html>

2、添加新方法

第二步:给 ParamController 类新加如下方法。 代码如下:

// 获取 Servlet 原生的 API
@RequestMapping("/testServlet")
public String testServlet(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("获取 Servlet 原生的 API……");
    System.out.println("request:" + request);

    HttpSession session = request.getSession();
    System.out.println("session:" + session);

    ServletContext servletContext = session.getServletContext();
    System.out.println("servletContext:" + servletContext);

    System.out.println("response:" + response);
    return "success";
}

3、启动 tomcat 进行测试

最后:启动 tomcat 服务器进行测试。 结果如下:

控制器输出的结果如下:

获取 Servlet 原生的 API……
request:org.apache.catalina.connector.RequestFacade@1b4aceb
session:org.apache.catalina.session.StandardSessionFacade@1e5b14
servletContext:org.apache.catalina.core.ApplicationContextFacade@15bbed9
response:org.apache.catalina.connector.ResponseFacade@1afcf1f

TIPS: 请求参数入门 到此结束!!!

  • 文章作者:root
  • 创建时间:2020-09-14 09:54:23
  • 更新时间:2022-01-03 03:46:57
  • 版权声明:本文为博主原创文章,未经博主允许不得转载!
请 在 评 论 区 留 言 哦 ~~~
1024