spring绑定参数的过程

从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。springmvc中,接收页面提交的数据是通过方法形参来接收,而不是在controller类定义成员变更接收!

默认支持的类型

直接在controller方法形参上定义下边类型的对象,就可以使用这些对象,在参数绑定过程中,如果遇到下边类型直接进行绑定。

  1. HttpServletRequest,通过request对象获取请求信息
  2. HttpServletResponse,通过response处理响应信息
  3. HttpSession,通过session对象得到session中存放的对象
  4. Model/ModelMap,model是一个接口,modelMap是一个接口实现 。作用是将model数据填充到request域。

简单类型

当参数类型是java的基本数据类型时,提交到controller的name和接收方法的形参名称一致就接收到数据。如:

@RequestMapping(value="/addItems", method={RequestMethod.POST, RequestMethod.GET})
public String addItems(HttpServletRequest request, Model model, String itemsName) throws Exception {
    System.out.println("商品名称:" + itemsName);
    return "forward:queryItems";
}

这时候在浏览器输入http://localhost:8080/ssm/items/addItmes?itemsName='Java编程思想',或者请求页面中的链接为:

<a href="items/addItems?itemsName='Thinking In Java'">参数传递</a><br />

后台就会接收到商品名为《Java编程思想》的商品名。其中那个RequesMapping的属性value是对应的url,method是规定该方法接收的请求类型,这里既运行使用post请求,同事也允许get请求。

如果request传入的参数和形参的名称不一致,需要使用@RequestParam进行绑定才能映射成功

    @RequestMapping(value="/addItems", method={RequestMethod.POST, RequestMethod.GET})
    public String addItems(HttpServletRequest request, Model model, @RequestParam(value="bookName", required=false) String itemsName) throws Exception {
        System.out.println("商品名称:" + itemsName);

        return null;
    }
<a href="items/addItems?bookName='Thinking In Java'">参数传递</a><br />

可以看到请求的参数名称叫做:bookName,而方法的形参名称叫做:itemsName,但是加上这一句@RequestParam(value="bookName", required=false)之后,请求参数可以参观的映射到形参。

如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功;如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致。通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:

pojo绑定

当页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo。

我的pojo定义如下:

public class Items {

    private Integer id;

    private String name;

    private Float price;

    private String pic;

    private Date createtime;

    private String detail;

    //getter/setter
}

jsp:页面定义:

    <form action="items/addItems" method="post">
        <table width="50%" border="1px">
            <tbody>
                <tr>
                    <td>商品名称</td>
                    <td><input type="text" name="name"/></td>
                </tr>
                <tr>
                    <td>商品价格</td>
                    <td><input type="text" name="price" /></td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value="添加" /></td>
                </tr>
            </tbody>
        </table>
    </form>

先测一测简单的数据类型,商品名和商品价格,因为这两种类型都是简单的数据类型,Date类型接下来再解决。

controller的接收方法

    @RequestMapping("/addItems")
    public String addItems(HttpServletRequest request, Model model, Items items) throws Exception {
        System.out.println("商品名:" + items.getName());
        System.out.println("商品价格:" + items.getPrice());

        return null;
    }

这里可以看到,添加商品的jsp页面中,商品的input的name="name",这个值将映射成为items对象的name属性,input的name="price"商品价格的值会映射到items对象的price这个属性里边。

再来测试另外几种数据类型,再定义一个java bean:Student。

public class Student {
    /*
     * id
     */
    private int id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 是否成年
     */
    private boolean adaut;

    /**
     * 生日
     */
    private Date birthday;

    /**
     * 身高
     */
    private float hight;

    //getter/setter
}

提交表单的jsp页面如下:

<form action="items/addStudent" method="post">
    <table width="50%" border="1px">
        <tbody>
            <tr>
                <td>id</td>
                <td><input type="text" name="id"/></td>
            </tr>
            <tr>
                <td>姓名</td>
                <td><input type="text" name="name" /></td>
            </tr>
            <tr>
                <td>是否成年</td>
                <td>
                    <input type="radio" name="adaut" value="true" checked>是
                    <input type="radio" name="adaut" value="false">否
                </td>
            </tr>
            <tr>
                <td>生日</td>
                <td><input type="text" name="birthday" /></td>
            </tr>
            <tr>
                <td>身高</td>
                <td><input type="text" name="hight" /></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="添加" /></td>
            </tr>
        </tbody>
    </table>
</form>

在这个JavaBean的属性中有日期类型,需要自定义参数绑定。将请求日期数据串传成 日期类型,要转换的日期类型和pojo中日期属性的类型保持一致,需要向处理器适配器中注入自定义的参数绑定组件。

自定义日期类型绑定

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;

public class CustomDateConverter implements Converter<String, Date> {

    public Date convert(String source) {
        //实现将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return sdf.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

}

在配置文件中配置:

    <mvc:annotation-driven conversion-service="conversionService" />
    <!-- 自定义参数绑定 -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!-- 转换器 -->
        <property name="converters">
            <list>
                <!-- 日期转换类型 -->
                <bean class="com.shizongger.ssm.model.CustomDateConverter" />
            </list>
        </property>
    </bean>

如此这般,jsp页面的input输入框中,日期格式如:2016-12-12 21:59:00的字符串变会转换成Date的日期格式。是否成年的boolean值也会传递到adaut属性中。

包装类型pojo参数绑定

需求:

商品查询controller方法中实现商品查询条件传入。

实现方法:

  1. 在形参中 添加HttpServletRequest request参数,通过request接收查询条件参数。
  2. 在形参中让包装类型的pojo接收查询条件参数。

分析:

页面传参数的特点:复杂,多样性。条件包括 :用户账号、商品编号、订单信息。如果将用户账号、商品编号、订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱。建议使用包装类型的pojo,pojo中属性是pojo。

定义一个查询的java bean QueryVo,所有将要查询的条件都将由这个vo接收。

public class QueryVo {

    private Items items;
    private Student student;    

    public Items getItems() {
        return items;
    }
    public void setItems(Items items) {
        this.items = items;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
}

Items和Student定义如上所述,这个vo定义了两个属性items商品和student用户(里面student就是用户),两者都有一个共同的属性名:name,items商品中有一个属性名name代表商品名称,student有一个属性名name代表用户名称,这个案例将展示如果分别向这个不同的name属性传递值。

jsp页面代码:

<form action="queryItems" method="post">
<table border="1px" width="80%">
    <tr>
        <td>商品名:<input type="text" name="items.name" /></td>
        <td>商品价格:<input type="text" name="items.price" /></td>
        <td>商品详情:<input type="text" name="items.detail" /></td>
        <td>下单用户:<input type="text" name="student.name" /></td>
        <td><input type="submit" value="查询" /></td>
    </tr>
</table>
</form>

controller代码:

    //商品查询
    @RequestMapping("/queryItems")
    public ModelAndView queryItems(HttpServletRequest request, QueryVo queryVo) throws Exception{
        if(null != queryVo && null != queryVo.getItems() && null != queryVo.getStudent()) {
            System.out.println("前端传递过来的查询条件:");
            System.out.println("商品名称:" + queryVo.getItems().getName() + " 商品价格:"
                            + queryVo.getItems().getPrice() + " 商品详情:"
                            + queryVo.getItems().getDetail() + " 下单用户:"
                            + queryVo.getStudent().getName() );
        }
    }

在input的name属性中,name值与queryVo属性的属性名对应,才能映射成功。

集合类型的绑定

数组类型绑定

需求:

商品批量删除,用户在页面选择多个商品,批量删除。

分析:

在批量删除需求中,如果能够一次性拿到jsp页面中复选框选中的内容那好办了。所以我们可以将页面选择(多选)的商品id,传到controller方法的形参,方法形参使用数组接收页面请求的多个商品id。

controller方法定义:

    @RequestMapping("/deleteItems")
    public String deleteItems(HttpServletRequest request, Integer[] itemsIds) {
        for(int i = 0; i < itemsIds.length; i++) {
            System.out.println("要删除的id:" + itemsIds[i]);
        }
        return null;
    }

jsp页面定义:

        <form id="itemsTalbe">
        <table border="1px" width="80%">
            <thead>
                <tr><td>删除</td><th>序列</th><th>商品名称</th><th>商品详情</th><th>商品价格</th><th>订单创建时间</th><th>修改</th></tr>
            </thead>
            <tbody>
                <c:forEach items="${itemsList }" var="items" varStatus="status">
                    <tr>
                        <td><input type="checkbox" name="itemsIds" value="${items.id }" /></td>
                        <td>${status.count }</td>
                        <td>${items.name }</td>
                        <td>${items.detail }</td>
                        <td>${items.price }</td>
                        <td>${items.createtime }</td>
                        <td><a href="editItems?id=${items.id }">修改</a></td>
                    </tr>
                </c:forEach>
                <tr>
                    <td colspan="7"><input type="submit" value="批量删除" onclick="batchDelete()"/></td>
                </tr>
            </tbody>
        </table>
        </form>

js代码:

        function batchDelete() {
            var form = document.getElementById("itemsTalbe");
            form.action ="${pageContext.servletContext.contextPath }/items/deleteItems";
            form.submit();
        }

在jsp页面中,用jstl迭代输出表格中每一行的记录内容。最重要的是每一行的第一个td的内容:

<td><input type="checkbox" name="itemsIds" value="${items.id }" /></td>

name属性等于itemsIds正是controller接收参数Interger数组的名称。

list绑定

通常在需要批量提交数据时,将提交的数据绑定到list< pojo>中,比如:成绩录入(录入多门课成绩,批量提交),本例子需求:

批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中。

在上诉的请求vo中,再添加属性:

private List<Items> itemsList;

完整的vo如下:

public class QueryVo {

    private Items items;
    private Student student;
    private List<Items> itemsList;

    public List<Items> getItemsList() {
        return itemsList;
    }
    public void setItemsList(List<Items> itemsList) {
        this.itemsList = itemsList;
    }
    public Items getItems() {
        return items;
    }
    public void setItems(Items items) {
        this.items = items;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }

}

jsp页面:

springmvc和struts2的区别

  1. springmvc基于方法开发的,struts2基于类开发的。springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。方法执行结束,形参数据销毁。springmvc的controller开发类似service开发。

  2. springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。

  3. 经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。

参考资料:<传智播客_Springmvc+Mybatis由浅入深之spring mvc>

spring mvc参数绑定的更多相关文章

  1. spring mvc 参数绑定

    基础类型 原始类型:id必须要传,否则报错. @RequestMapping("/test") @ResponseBody public ResponseData test(int ...

  2. Spring MVC参数绑定(如何接收请求参数及返回参数)

    在SpringMVC interceptor案例实践中遇到了获取jsp表单传递参数失败的问题,怎么的解决的呢?下面详细介绍. 先讲述下https://www.cnblogs.com/ilovebath ...

  3. spring mvc: 资源绑定视图解析器(不推荐)

    spring mvc: 资源绑定视图解析器(不推荐) 不适合单控制器多方法访问,有知道的兄弟能否告知. 访问地址: http://localhost:8080/guga2/hello/index 项目 ...

  4. spring mvc: 参数方法名称解析器(用参数来解析控制器下的方法)MultiActionController/ParameterMethodNameResolver/ControllerClassNameHandlerMapping

    spring mvc: 参数方法名称解析器(用参数来解析控制器下的方法)MultiActionController/ParameterMethodNameResolver/ControllerClas ...

  5. Spring MVC资源绑定视图解析器

    ResourceBundleViewResolver使用属性文件中定义的视图bean来解析视图名称. 以下示例显示如何使用Spring Web MVC框架中的ResourceBundleViewRes ...

  6. Spring MVC 参数的绑定方法

    在Spring MVC中,常见的应用场景就是给请求的Url绑定参数.本篇就介绍两种最最基本的绑定参数的方式: 基于@RequestParam 这种方法一般用于在URL后使用?添加参数,比如: @Req ...

  7. spring自定义参数绑定(日期格式转换)

    spring参数绑定时可能出现 BindException(参数绑定异常),类似下面的日期绑定异常(前台传过来是String类型,实际的pojo是Date类型) default message [Fa ...

  8. Spring MVC参数处理

    使用Servlet API作为参数 HttpServletRequest HttpServletResponse HttpSession 使用流作为参数 总结 Spring MVC通过分析处理处理方法 ...

  9. spring mvc 参数

    Struts(表示层)+Spring(业务层)+Hibernate(持久层) Struts: Struts是一个表示层框架,主要作用是界面展示,接收请求,分发请求. 在MVC框架中,Struts属于V ...

随机推荐

  1. 15款最好的 jQuery Modal(模态窗口)插件

    jQuery 模态窗口插件帮助网站开发人员显示网页中的特定内容,让用户聚焦到这个地方.模态窗口是嵌入到当前网页中,不用重定向到新网页的弹出窗口.这种技术可以用在图像画廊,电子商务网站,登陆框,电子邮件 ...

  2. 《javascript权威指南》读书笔记(连载)

    这是一篇很长的博客 终于把权威指南给买回来了,之前一直犹豫,第一:书太厚,怕买了不能坚持看完.第二:觉得太贵,最少100¥.现在实习也能发点工资了,给自己定了一个志愿:把一个月的工资用于买书.这么一想 ...

  3. android tools使用方式

    我们希望在布局中显示测试的属性,而这个属性不会影响到正式代码,因此我们就需要tools这个命名空间. 首先定义:xmlns:tools="http://schemas.android.com ...

  4. JavaScript学习05 定时器

    JavaScript学习05 定时器 定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout(“<表达式>”,毫秒) ...

  5. 看代码学知识之(2) ListView无数据时显示其他View

    看代码学知识之(2) ListView无数据时显示其他View 今天看的一块布局是这样的: <!-- The frame layout is here since we will be show ...

  6. android加固系列—4.加固前先学会破解,无源码调试apk

    [版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5138585.html] 项目关键java代码为,将tv设置为从jni读取的字符串,这里的破解内 ...

  7. symfony2 安装并创建第一个页面

    1.安装和配置 参考 http://symfony.cn/docs/book/installation.html 使用安装工具: windows系统 Open your command console ...

  8. Scrum敏捷项目管理精要

    1. 简介: 敏捷项目管理在我们国家起步比较晚,成功运用的项目不多 百分之六十五的敏捷项目用户为scrum 2.互联网时代的特征,雷军的话: 专注,极致,口碑,快(敏捷项目开发就是要快速) 3.敏捷开 ...

  9. 谈谈用ASP.NET开发的大型网站有哪些架构方式(成本)

    在上篇文章里(http://www.cnblogs.com/ms0017/archive/2011/07/26/2117676.html),列举了国内外用ASP.NET开发的大型网站有哪些.最后提到了 ...

  10. Git从零教你入门(4):Git服务之 gogs部署安装

    Git从零入门系列4: 先看上一篇文章: http://www.51testing.com/index.php?uid-497177-action-viewspace-itemid-3706817 今 ...