SpringMVC请求参数的绑定与@RequestParam注解的使用

当用户在页面触发某种请求时,一般会将一些参数(key/value)带到后台。在SpringMVC中可以通过参数绑定,将客户端请求的key/value数据绑定到Controller处理器方法的形参上。

SpringMVC中有一些默认支持的类型,这些类型可以直接在Controller类的方法中定义,在参数绑定的过程中遇到该种类型就直接进行绑定。其默认支持的类型有以下几种:HttpServletRequest、HttpServletResponse、HttpSession 及 Model/ModelMap。HttpServletRequest可以通过request对象获取请求信息;HttpServletResponse可以通过response对象处理响应信息;HttpSession可以通过session对象得到session中存放的对象;而对于Model/ModelMap,其中Model是一个接口,ModelMap是一个接口实现,它的作用就是将model数据填充到request域。

1、简单类型参数绑定

1.1 基本数据类型参数绑定

在SpringMVC使用简单类型参数绑定,在处理key/value信息时,就会以key名寻找Controller类的方法中具有相同名称的形成并进行绑定。如下面的例子:

/**
 * 根据用户ID,获取用户信息
 */
@RequestMapping(value="getUser",method=RequestMethod.GET)
public String getUser(int id,Model model)
{
    //调用Service获取用户信息
    UserModel userModel = userService.getUserModel(id);
    //通过形成中的model将数据传递到页面
    model.addAttribute("userModel",userModel);
    //返回页面
    return "/user/userInfo";
}

在执行上面的getUser请求时,需要为其URL指定一个参数id。

1.2 @RequestParam注解

注解@RequestParam可以对自定义简单类型的参数进行绑定,即如果使用@RequestParam,就无须设置controller方法的形参名称与request传入的参数名称一致。而不使用@RequestParam注解时,就要求controller方法的形参名称与request传入的参数名称一致,这样才能绑定成功。

假设执行getUser请求时,传入的参数名为user_id,而Java代码使用的是驼峰命名,那么可以通过@RequestParam注解来指定绑定名称,而在形参中继续使用驼峰命名:

/**
 * 根据用户ID,获取用户信息
 */
@RequestMapping(value="getUser",method=RequestMethod.GET)
public String getUser(@RequestParam(value="user_id") int userId,Model model)
{
    //调用Service获取用户信息
    UserModel userModel = userService.getUserModel(userId);
    //通过形成中的model将数据传递到页面
    model.addAttribute("userModel",userModel);
    //返回页面
    return "/user/userInfo";
}

1.2.1 设置非空

如果要求绑定的参数一定不能为空,可以使用@RequestParam注解中的required属性来指定该形参是否必须传入,required属性为“true”指定参数必须传入。例子如下:

/**
 * 根据用户ID,获取用户信息
 */
@RequestMapping(value="getUser",method=RequestMethod.GET)
public String getUser(@RequestParam(value="user_id",required=true) int userId,Model model)
{
    //忽略具体代码...
}

1.2.2 设置默认值

在Controller方法的形参中,如果有一些参数可以为空,但是又期望它们为空时有一个默认值,此时可以使用@RequestParam注解中的defaultValue属性来指定某些参数的默认值。例子如下:

/**
 * 根据用户ID,获取用户信息
 */
@RequestMapping(value="getUser",method=RequestMethod.GET)
public String getUser(@RequestParam(value="user_id",defaultValue="1") int userId,Model model)
{
    //忽略具体代码...
}

2、包装类型参数绑定

在Controller方法中,也可以映射前台页面中包含的包装类型参数。

【示例】实现用户注册功能,在前台页面中使用包装类型进行参数的绑定,执行结果下图:

用户注册页面

注册成功页面

(1)创建用户信息参数类(UserParam.java)。

package com.pjb.mvc.model;

/**
 * 用户信息参数类
 * @author pan_junbiao
 **/
public class UserParam
{
    private String userName; //用户名称
    private String blogUrl; //博客地址
    private int sex; //性别
    private String province; //省份
    private String[] hobby; //兴趣爱好
    private String remark; //备注信息

    //省略getter与setter方法...
}

(2)创建用户信息模型类(UserModel.java)

package com.pjb.mvc.model;

/**
 * 用户信息模型类
 * @author pan_junbiao
 **/
public class UserModel
{
    private String userName; //用户名称
    private String blogUrl; //博客地址
    private String sex; //性别
    private String province; //省份
    private String hobbyStr; //兴趣爱好
    private String remark; //备注信息

    //省略getter与setter方法...
}

(3)编写Controller控制器中的执行方法。

/**
 * 用户控制器
 * 使用@Controller注解来标识它是一个控制器
 * 使用@RequestMapping注解指定一个URL映射名
 * @author pan_junbiao
 **/
@Controller
@RequestMapping("/user")
public class UserController
{
    /**
     * 用户注册
     */
    @RequestMapping(value="registerUser",method=RequestMethod.POST)
    public String registerUser(UserParam userParam, Model model)
    {
        //获取参数信息
        UserModel userModel = new UserModel();
        userModel.setUserName(userParam.getUserName());
        userModel.setBlogUrl(userParam.getBlogUrl());
        userModel.setSex(userParam.getSex()==1?"男":"女");
        userModel.setProvince(userParam.getProvince());
        userModel.setHobbyStr(java.util.Arrays.toString(userParam.getHobby()));
        userModel.setRemark(userParam.getRemark());
        //通过形成中的model将数据传递到页面
        model.addAttribute("userModel",userModel);
        //返回页面
        return "/user/regsuccess";
    }
}

(4)解决中文乱码

如果中文数据传递到后台出现乱码现象,则需要配置一个过滤器,对传递的数据格式进行统一的转码。一般会在web.xml中设置SpringMVC的转码过滤器来解决这种问题:

<!-- 中文乱码过滤器 -->
<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>

(5)创建用户注册页面(register.jsp)。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户注册</title>
    <meta name="author" content="pan_junbiao的博客">
    <style>
        .txtBox{
            padding: 3px;
            width: 300px;
            font-size: 16px;
        }
    </style>
</head>
<body>
<form action="user/registerUser.action" method="post" name="myform">
    <table align="center">
        <caption>用户注册</caption>
        <tr>
            <th>用户名称:</th>
            <td>
                <input class="txtBox" type="text" name="userName" value="pan_junbiao的博客"/>
            </td>
        </tr>
        <tr>
            <th>博客地址:</th>
            <td>
                <input class="txtBox" type="text" name="blogUrl" value="https://blog.csdn.net/pan_junbiao"/>
            </td>
        </tr>
        <tr>
            <th>性别:</th>
            <td>
                <input id="male" name="sex" type="radio" value="1" checked="checked"/>
                <label for="male">男</label>
                <input id="female" name="sex" type="radio" value="2"/>
                <label for="female">女</label>
            </td>
        </tr>
        <tr>
            <th>省份:</th>
            <td>
                <select name="province" class="txtBox">
                    <option value="广东省">广东省</option>
                    <option value="山东省">山东省</option>
                    <option value="安徽省">安徽省</option>
                </select>
            </td>
        </tr>
        <tr>
            <th>兴趣爱好:</th>
            <td>
                <input id="lq" name="hobby" type="checkbox" value="篮球" checked="checked">
                <label for="lq">篮球</label>
                <input id="zq" name="hobby" type="checkbox" value="足球" checked="checked">
                <label for="zq">足球</label>
                <input id="ymq" name="hobby" type="checkbox" value="羽毛球">
                <label for="ymq">羽毛球</label>
                <input id="ppq" name="hobby" type="checkbox" value="乒乓球">
                <label for="ppq">乒乓球</label>
            </td>
        </tr>
        <tr>
            <th>备注信息:</th>
            <td>
                <input class="txtBox" type="text" name="remark" value="您好,欢迎访问 pan_junbiao的博客!" />
            </td>
        </tr>
        <!-- 以下是提交、取消按钮 -->
        <tr>
            <td colspan="2" style="text-align: center;">
                <input type="submit" value="提交"/>
                <input type="reset" value="重置" />
            </td>
        </tr>
    </table>
</form>
</body>
</html>

(6)创建注册成功页面(regsuccess.jsp)。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册成功</title>
    <meta name="author" content="pan_junbiao的博客">
    <style>
        table { border-collapse: collapse;}
        table,table tr th, table tr td { border:1px solid #000000; padding: 5px 10px;}
    </style>
</head>
<body>
<table align="center">
    <caption><h2 style="color: red">注册成功</h2></caption>
    <tr>
        <th>用户姓名</th>
        <td>${userModel.userName}</td>
    </tr>
    <tr>
        <th>博客地址</th>
        <td>${userModel.blogUrl}</td>
    </tr>
    <tr>
        <th>性别</th>
        <td>${userModel.sex}</td>
    </tr>
    <tr>
        <th>省份</th>
        <td>${userModel.province}</td>
    </tr>
    <tr>
        <th>兴趣爱好</th>
        <td>${userModel.hobbyStr}</td>
    </tr>
    <tr>
        <th>备注信息</th>
        <td>${userModel.remark}</td>
    </tr>
</table>
</body>
</html>

3、集合类型参数绑定

有时候前端请求的数据时批量的,此时就要求Web端去处理请求时,获取这些批量的请求参数。一般批量的请求参数在Java中是以数组或者集合的形式接收的,而SpringMVC提供了接收和解析数据和集合参数类型的机制。

3.1 数组类型的请求参数

第一种是数组类型的请求参数。在JSP页面可能出现类似复选框的表单,让用户选择一个或者多个数据进行操作。

【示例】在JSP页面中通过复选框选择一个或者多个用户信息,并提交到后台,后台Controller控制器中的方法获取数组类型的请求参数。

(1)创建JSP页面,通过复选框选择一个或者多个用户信息,并提交到后台

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>数组类型的请求参数</title>
    <meta name="author" content="pan_junbiao的博客">
</head>
<body>
<form action="user/getUserIdArray.action" method="post" name="myform">
    <input id="uid01" type="checkbox" name="userIds"  value="1">
    <label for="uid01">pan_junbiao的博客_001</label><br>
    <input id="uid02" type="checkbox" name="userIds"  value="2">
    <label for="uid02">pan_junbiao的博客_002</label><br>
    <input id="uid03" type="checkbox" name="userIds"  value="3">
    <label for="uid03">pan_junbiao的博客_003</label><br>
    <input id="uid04" type="checkbox" name="userIds"  value="4">
    <label for="uid04">pan_junbiao的博客_004</label><br>
    <input id="uid05" type="checkbox" name="userIds"  value="5">
    <label for="uid05">pan_junbiao的博客_005</label><br>
    <input type="submit" value="批量测试提交"/>
</form>
</body>
</html>

页面执行如下:

(2)编写Controller控制器中的执行方法,获取数组类型的请求参数。

/**
 * 获取用户ID数组
 * @author pan_junbiao
 */
@RequestMapping(value = "getUserIdArray", method = RequestMethod.POST)
public void getUserIdArray(int[] userIds)
{
    if (userIds != null && userIds.length > 0)
    {
        System.out.println("您选择的用户ID列表为:");
        System.out.println(java.util.Arrays.toString(userIds));
    }
}

控制台输出结果:

注意:form表单的多选控件的name属性要和Controller相关方法的形参保持一致。

3.2 List类型的请求参数

第二种是List类型的请求参数。当想把页面上的批量数据通过SpringMVC转换为Web端的List类型的对象时,每一组数据的input控件的name属性使用“集合名[下标].属性”的形式,当请求传递到Web端时,处理器适配器会根据name的格式将请求参数解析为相应的List集合。

【示例】前端JSP页面提交多条用户信息,后台Controller控制器中的方法获取List类型的请求参数。

(1)创建JSP页面,提交多条用户信息到后台Controller控制器中的方法。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>List类型的请求参数</title>
    <meta name="author" content="pan_junbiao的博客">
    <style>
        table { border-collapse: collapse; margin-bottom: 10px}
        table,table tr th, table tr td { border:1px solid #000000; padding: 5px 10px;}
    </style>
</head>
<body>
<form action="user/getUserList.action" method="post" name="myform">
    <table>
        <caption>List类型的请求参数</caption>
        <tr>
            <th>用户名称</th>
            <th>性别</th>
            <th>省份</th>
        </tr>
        <tr>
            <td><input name="userList[0].userName" value="pan_junbiao的博客_001"/></td>
            <td><input name="userList[0].sex" value="男"/></td>
            <td><input name="userList[0].province" value="广东省"/></td>
        </tr>
        <tr>
            <td><input name="userList[1].userName" value="pan_junbiao的博客_002"/></td>
            <td><input name="userList[1].sex" value="男"/></td>
            <td><input name="userList[1].province" value="山东省"/></td>
        </tr>
        <tr>
            <td><input name="userList[2].userName" value="pan_junbiao的博客_003"/></td>
            <td><input name="userList[2].sex" value="男"/></td>
            <td><input name="userList[2].province" value="黑龙江省"/></td>
        </tr>
    </table>
    <input type="submit" value="批量测试提交"/>
</form>
</body>
</html>

页面执行如下:

(2)创建用户列表查询参数类(ListQryModel.java),该类中包含一个用户列表属性。

package com.pjb.mvc.model;

import java.util.List;

/**
 * 用户列表查询参数类
 * @author pan_junbiao
 **/
public class ListQryModel
{
    private List<UserModel> userList; //用户列表

    public List<UserModel> getUserList()
    {
        return userList;
    }

    public void setUserList(List<UserModel> userList)
    {
        this.userList = userList;
    }
}

(3)编写Controller控制器中的执行方法,获取List类型的请求参数。

/**
 * 获取用户列表
 * @author pan_junbiao
 */
@RequestMapping(value = "getUserList", method = RequestMethod.POST)
public void getUserList(ListQryModel listQryModel)
{
    List<UserModel> userList = listQryModel.getUserList();
    if (userList != null && userList.size() > 0)
    {
        System.out.println("用户列表参数为:");
        //遍历用户列表参数
        for (UserModel user : userList)
        {
            System.out.println("用户名称:" + user.getUserName() + " 性别:" + user.getSex() + " 省份:" + user.getProvince());
        }
    }
}

控制台输出结果:

注意:form表单的集合元素的name属性要和Controller相关方法的List形参对象名称保持一致。

3.3 Map类型的请求参数

第三种是Map类型的请求参数。当想把页面上的批量数据通过SpringMVC转换为Web端的Map类型的对象时,每一组数据的input控件的name属性使用“Map名['key值']”的形式,当请求传递到后台Controller控制器中的执行方法时,处理器适配器会根据name的格式将请求参数解析为相应的Map集合。

【示例】前端JSP页面提交Map类型的用户参数信息,后台Controller控制器中的方法获取Map类型的请求参数。

(1)创建JSP页面,提交Map类型的用户参数信息到后台Controller控制器中的方法。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Map类型的请求参数</title>
    <meta name="author" content="pan_junbiao的博客">
    <style>
        .txtBox{
            padding: 3px;
            width: 300px;
            font-size: 16px;
        }
    </style>
</head>
<body>
<form action="user/getUserMap.action" method="post" name="myform">
    <table>
        <caption>Map类型的请求参数</caption>
        <tr>
            <th>用户名称:</th>
            <td><input name="userMap['userName']" value="pan_junbiao的博客" class="txtBox"/></td>
        </tr>
        <tr>
            <th>博客地址:</th>
            <td><input name="userMap['blogUrl']" value="https://blog.csdn.net/pan_junbiao" class="txtBox"/></td>
        </tr>
        <tr>
            <th>备注信息:</th>
            <td><input name="userMap['remark']" value="您好,欢迎访问 pan_junbiao的博客!" class="txtBox"/></td>
        </tr>
    </table>
    <input type="submit" value="批量测试提交"/>
</form>
</body>
</html>

页面执行如下:

(2)创建用户Map查询参数类(MapQryModel.java),该类中包含一个用户Map属性。

package com.pjb.mvc.model;

import java.util.Map;

/**
 * 用户Map查询参数类
 * @author pan_junbiao
 **/
public class MapQryModel
{
    private Map<String,Object> userMap; //用户Map

    public Map<String, Object> getUserMap()
    {
        return userMap;
    }

    public void setUserMap(Map<String, Object> userMap)
    {
        this.userMap = userMap;
    }
}

(3)编写Controller控制器中的执行方法,获取Map类型的请求参数。

/**
 * 获取用户Map
 * @author pan_junbiao
 */
@RequestMapping(value = "getUserMap", method = RequestMethod.POST)
public void getUserMap(MapQryModel mapQryModel)
{
    Map<String,Object> userMap = mapQryModel.getUserMap();
    if(userMap!=null && userMap.size()>0)
    {
        System.out.println("用户Map参数为:");
        for(String key: userMap.keySet())
        {
            System.out.println("userMap["+ key +"]="+userMap.get(key));
        }
    }
}

控制台输出结果:

注意:form表单的Map元素的name属性要和Controller相关方法的Map形参名,以及对应的key键保持一致。

发布了354 篇原创文章 · 获赞 208 · 访问量 165万+

猜你喜欢

转载自blog.csdn.net/pan_junbiao/article/details/103762960