SpringMVC参数绑定

1. 绑定简单数据类型

1.1 需求

编辑商品信息,需要根据商品id查询商品信息,然后展示到页面。
请求的url:/itemEdit.action
参数:id(商品id)
响应结果:商品编辑页面,展示商品详细信息。

1.2 Controller参数绑定

要根据id查询商品数据,需要从请求的参数中把请求的id取出来。Id应该包含在Request对象中。可以从Request对象中取id。

@RequestMapping("/itemEdit")
    public ModelAndView itemEdit(HttpServletRequest request) {
        //从Request中取id
        String strId = request.getParameter("id");
        Integer id = null;
        //如果id有值则转换成int类型
        if (strId != null && !"".equals(strId)) {
            id = new Integer(strId);
        } else {
            //出错
            return null;
        }
        Items items = itemService.getItemById(id);
        //创建ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        //向jsp传递数据
        modelAndView.addObject("item", items);
        //设置跳转的jsp页面
        modelAndView.setViewName("editItem");
        return modelAndView;
    }

如果想获得Request对象只需要在Controller方法的形参中添加一个参数即可。Springmvc框架会自动把Request对象传递给方法。

1.3 默认支持的参数类型
  • HttpServletRequest : 通过request对象获取请求信息
  • HttpServletResponse :通过response处理响应信息
  • HttpSession :通过session对象得到session中存放的对象
  • Model/ModelMap :ModelMap是Model接口的实现类,通过Model或ModelMap向页面传递数据,如下:
//调用service查询商品信息
Items item = itemService.findItemById(id);
model.addAttribute("item", item);

页面通过${item.XXXX}获取item对象的属性值
使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap。
如果使用Model则可以不使用ModelAndView对象,Model对象可以向页面传递数据,View对象则可以使用String返回值替
代。不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。
如果使用Model则方法可以改造成:

@RequestMapping("/itemEdit")
    public String itemEdit(HttpServletRequest request, Model model) {
        //从Request中取id
        String strId = request.getParameter("id");
        Integer id = null;
        //如果id有值则转换成int类型
        if (strId != null && !"".equals(strId)) {
            id = new Integer(strId);
        } else {
            //出错
            return null;
        }
        Items items = itemService.getItemById(id);
        //创建ModelAndView
        //ModelAndView modelAndView = new ModelAndView();
        //向jsp传递数据
        //modelAndView.addObject("item", items);
        model.addAttribute("item", items);
        //设置跳转的jsp页面
        //modelAndView.setViewName("editItem");
        //return modelAndView;
        return "editItem";
    }
1.4 绑定简单类型

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。从Request取参数的方法可以进一步简化。

@RequestMapping("/itemEdit")
    public String itemEdit(Integer id, Model model) {
        Items items = itemService.getItemById(id);
        //向jsp传递数据
        model.addAttribute("item", items);
        //设置跳转的jsp页面
        return "editItem";
    }
  • 支持的数据类型
    参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
    整形:Integer、int
    字符串:String
    单精度:Float、float
    双精度:Double、double
    布尔型:Boolean、boolean
    说明:对于布尔类型的参数,请求的参数值为true或false。
    处理器方法:
    public String editItem(Model model,Integer id,Boolean status) throws Exception
    请求url:
    http://localhost:8080/xxx.action?id=2&status=false

  • @RequestParam

使用@RequestParam常用于处理简单类型的绑定

value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报;
TTP Status 400 - Required Integer parameter 'XXXX' is not present

defaultValue:默认值,表示如果请求中没有同名参数时的默认值,定义如下:

public String editItem(@RequestParam(value="item_id",required=true) String id) {

}

形参名称为id,但是这里使用value=" item_id"限定请求的参数名为item_id,所以页面传递参数的名必须为item_id。
注意:如果请求参数中没有item_id将跑出异常:
HTTP Status 500 - Required Integer parameter 'item_id' is not present

这里通过required=true限定item_id参数为必需传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,
即使required=true也可以不传item_id参数值

2. 绑定pojo类型

2.1 需求

请求的url:/updateitem.action
参数:表单中的数据。
响应内容:更新成功页面

2.2 使用pojo接收表单数据

如果提交的参数很多,或者提交的表单中的内容很多的时候可以使用pojo接收数据。要求pojo对象中的属性名和表单中input的name属性一致。
页面定义如下;

<input type="text" name="name"/>
<input type="text" name="price"/>

Pojo定义:

public class Items {
    private Integer id;

    private String name;
    private Float price;

    private String pic;
}

请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性

@RequestMapping("/updateitem")
    public String updateItem(Items items) {
        itemService.updateItem(items);
        return "success";
    }


注意:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定
的内容。
2.4 解决post乱码问题

在web.xml中加入:

<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>

以上可以解决post请求乱码问题。
对于get请求中文参数出现乱码解决方法有两个:

1.修改tomcat配置文件添加编码与工程编码一致,如下:

<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" 
protocol="HTTP/1.1" redirectPort="8443"/>

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

2.对参数进行重新编码

String userName new 
String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

3. 绑定包装pojo

3.1 需求

包装对象定义如下:

Public class QueryVo {
private Items items;

}

页面定义:

<input type="text" name="items.name" />
<input type="text" name="items.price" />

Controller方法定义如下:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
System.out.println(queryVo.getItems());
3.2 接收查询条件
@RequestMapping("/queryitem")
    public String queryItem(QueryVo queryVo) {
        System.out.println(queryVo.getItems().getName());
        System.out.println(queryVo.getItems().getPrice());
        return null;
    }

4. 自定义参数绑定

4.1 需求

由于日期数据有很多种格式,所以springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。在springmvc这可以在处理器适配器上自定义Converter进行参数绑定。如果使用可以在此标签上进行扩展。

4.2 自定义Converter
public class DateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}
4.3 配置Converter

方式1

<!-- 加载注解驱动 -->
    <mvc:annotation-driven conversion-service="conversionService"/>
    <!-- 转换器配置 -->
    <bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="cn.itcast.springmvc.convert.DateConverter"/>
            </set>
        </property>
    </bean>

方式2

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

    <!-- 扫描带Controller注解的类 -->
    <context:component-scan base-package="cn.itcast.springmvc.controller" />

    <!-- 转换器配置 -->
    <bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="cn.itcast.springmvc.convert.DateConverter"/>
            </set>
        </property>
    </bean>
    <!-- 自定义webBinder -->
    <bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
        <property name="conversionService" ref="conversionService" />
    </bean>
    <!--注解适配器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
         <property name="webBindingInitializer" ref="customBinder"></property> 
    </bean>
    <!-- 注解处理器映射器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <!-- 加载注解驱动 -->
    <!-- <mvc:annotation-driven/> -->
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <!-- jsp前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- jsp后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>
注意:此方法需要独立配置处理器映射器、适配器,不再使用<mvc:annotation-driven/>

4. 绑定数组

4.1 需求

要求商品列表页面中的每个商品前有一个checkbook,选中多个商品后点击删除按钮把商品id传递给Controller,根据商品id删除商品信息。

4.2 Jsp中实现
<c:forEach items="${itemList }" var="item">
<tr>
    <td><input name="ids" value="${item.id}" type="checkbox"></td>
    <td>${item.name }</td>
    <td>${item.price }</td>
    <td><fmt:formatDate value="${item.createtime}"  pattern="yyyy-MM-dd HH:mm:ss"/></td>
    <td>${item.detail }</td>
    <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>

生成html代码如下:
页面选中多个checkbox向controller方法传递

<table width="100%" border=1>
<tr>
    <td>商品名称</td>
    <td>商品价格</td>
    <td>生产日期</td>
    <td>商品描述</td>
    <td>操作</td>
</tr>
<tr>
    <td><input name="ids" value="1" type="checkbox"></td>
    <td>台式机</td>
    <td>3000.0</td>
    <td>2016-02-03 13:22:53</td>
    <td></td>
    <td><a href="/springmvc-web/itemEdit.action?id=1">修改</a></td>
</tr>
<tr>
    <td><input name="ids" value="2" type="checkbox"></td>
    <td>笔记本</td>
    <td>6000.0</td>
    <td>2015-02-09 13:22:57</td>
    <td></td>
    <td><a href="/springmvc-web/itemEdit.action?id=2">修改</a></td>
</tr>
<tr>
    <td><input name="ids" value="3" type="checkbox"></td>
    <td>背包</td>
    <td>200.0</td>
    <td>2015-02-06 13:23:02</td>
    <td></td>
    <td><a href="/springmvc-web/itemEdit.action?id=3">修改</a></td>
</tr>
</table>
4.3 Controller

Controller方法中可以用String[]接收,或者pojo的String[]属性接收。两种方式任选其一即可。
定义如下:

@RequestMapping("/queryitem")
    public String queryItem(QueryVo queryVo, String[] ids) {
        System.out.println(queryVo.getItems().getName());
        System.out.println(queryVo.getItems().getPrice());
        System.out.println(ids.toString());
        return null;
    }

或者

public class QueryVo {
    private Items items;
    private String[] ids;

    public String[] getIds() {
        return ids;
    } 

    public void setIds(String[] ids) {
    this.ids = ids;
    }
}

5 将表单的数据绑定到List

5.1 需求

要想实现商品数据的批量修改,需要在商品列表中可以对商品信息进行修改,并且可以批量提交修改后的商品数据。

5.2 接收商品列表的pojo

List中存放对象,并将定义的List放在包装类中,使用包装pojo对象接收。

public class QueryVo {
    private Items items;
    private String[] ids;
    private  List<Items> itemList;

    public List<Items> getItemList() {
        return itemList;
    } 

    public void setItemList(List<Items> itemList) {
        this.itemList= itemList;
    }

    get/set...
}
5.3 Jsp改造

页面定义如下:

<tr>
<td>
<input type="text" name=" itemsList[0].id" value="${item.id}"/>
</td>
<td>
<input type="text" name=" itemsList[0].name" value="${item.name }"/>
</td>
<td>
<input type="text" name=" itemsList[0].price" value="${item.price}"/>
</td>
</tr>
<tr>
<td>
<input type="text" name=" itemsList[1].id" value="${item.id}"/>
</td>
<td>
<input type="text" name=" itemsList[1].name" value="${item.name }"/>
</td>
<td>
<input type="text" name=" itemsList[1].price" value="${item.price}"/>
</td>
</tr>

Name属性必须是包装pojo的list属性+下标+元素属性(接收参数)。

展示的Jsp做如下改造:

<c:forEach items="${itemList }" var="item">
<tr>
    <td><input name="ids" value="${item.id}" type="checkbox"></td>
    <td>
        <input name="id" value="${item.id}" type="hidden">
        <input name="name" value="${item.name }" type="text">
    </td>
    <td><input name="name" value="${item.price }" type="text"></td>
    <td><input name="name" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" type="text"></td>
    <td><input name="name" value="${item.detail }" type="text"></td>
    <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>
varStatus属性常用参数总结下:
${status.index}      输出行号,从0开始。
${status.count}      输出行号,从1开始。
${status.current}   当前这次迭代的(集合中的)项
${status.first}  判断当前项是否为集合中的第一项,返回值为truefalse
${status.last}   判断当前项是否为集合中的最后一项,返回值为truefalse
beginend、step分别表示:起始序号,结束序号,跳跃步伐。
5.4 Controller
@RequestMapping("/queryitem")
    public String queryItem(QueryVo queryVo, String[] ids) {
        System.out.println(queryVo.getItems().getName());
        System.out.println(queryVo.getItems().getPrice());
        System.out.println(ids.toString());
        return null;
    }

注意:接收List类型的数据必须是pojo的属性,方法的形参为List类型无法正确接收到数据。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值