SpringMVC中关于参数绑定的方法

       在使用SSM框架开发项目时,springmvc负责处理页面的一些请求,然后将数据再通过视图返回给用户的。那么请求是前端通过参数传递到后台在进行执行的。那么这些参数怎么传呢?又有哪些参数可以传递呢?这就是SpringMvc框架中涉及到的参数绑定的问题。

1.参数绑定的过程

        在springmvc中,接收页面提交的数据是通过方法形参来接收的。从客户端请求的key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上,然后就可以在controller中使用该参数了。来看一下这个过程: 

参数绑定

2.默认支持的类型 

       使用springmvc框架时,有支持的默认类型的绑定。也就是说,直接在controller方法形参上直接定义默认支持的类型的对象,就可以使用这些对象。

SpringMvc默认支持的类型对象:

HttpServletRequest对象
HttpServletResponse对象
HttpSession对象
Model/ModelMap对象

       在参数绑定过程中,如果遇到上面4种类型就可以直接进行绑定。也就是说,我们可以在controller的方法的形参中直接定义上面这些类型的参数,springmvc会自动绑定。这里要说明一下的就是Model/ModelMap对象,Model是一个接口,ModelMap是一个接口实现 ,作用是将Model数据填充到request域,跟ModelAndView类似。

3.简单类型的绑定

       假设在开发中有个需求:根据商品的id来修改对应商品信息。所以前台页面肯定要传进来这个需要被修改商品的id,然后springmvc的controller进行处理查询出要修改的数据。也就是数据库中根据id进行查询的sql语句。

前台页面通过url将参数传递过来,请求的路径是editItems.action。 

<td><a href="${pageContext.request.contextPath }/editItems.action?id=${item.id}">修改</a></td>

在Controller层中的方法为:

@Controller
public class Controller(){
@RequestMapping("/editItems")
 public String editItems(Model model, Integer id) throws Exception {
    //根据id查询对应的Items
    ItemsCustom itemsCustom = itemsService.findItemsById(id);

    model.addAttribute("itemsCustom", itemsCustom);

    //通过形参中的model将model数据传到页面
    //相当于modelAndView.addObject方法
    return "/WEB-INF/jsp/items/editItems.jsp";
 }
}

       从上面的代码中可以看出model可以直接作为参数,springmvc默认会绑定它,然后使用model将查询到的数据放到request域中,这样就可以在前台页面取出该数据了。 

       注意:简单类型的绑定中,方法形参中的参数名要和前台传进来的名一样才能完成参数的绑定。那么,如果参数名不一致了想让它绑定成功,那咋整呢?有解决办法么?有!我们可以使用注解@RequestParam对简单的类型进行参数绑定,如下: 

requestParam注解

通过@RequestParam中的required属性指定参数是否必须要传入,如果设置为true,没有传入参数就会报错。

4.POJO类型的绑定

4.1普通的POJO类型

        继续上面的案例,当页面根据id查询展示了商品详细信息后,我在信息上做了一些修改,然后点击提交这个页面数据,后台应该将我提交的这些数据全部更新到数据库的items表中,相当于数据库中的修改的sql语句。这个时候提交的参数就不是一个了,可能是两个、三个、四个甚至更多。这个时候我们可以将这些修改页面信息的属性封装到一个pojo中,直接将这个pojo对象作为参数绑定。

数据库Items表中的属性:

属性

        绑定很简单,对于基本类型,要求页面中input标签的name属性值和controller的pojo形参中的属性名称一致,即可将页面中数据绑定到pojo。也就是说前台页面传进来的name要和要封装的pojo属性名一模一样,然后就可以将该pojo作为形参放到controller的方法中,如下: 

pojo类型

        这样就能将前台表单传进来的不同属性值封装到ItemsCustom中了。但是运行一下就会发现报错,报错的信息是无法将String类型转换成java.util.Date类型,因为上面Items中有一个属性是Date类型的createtime。这就需要我们自己定义转换器了,这也是这部分的重点,下面我们自己定义一个日期转换器:

//需要实现Converter接口,这里是将String类型转换成Date类型
public class CustomDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        //实现 将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss)
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            //转成直接返回
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //如果参数绑定失败返回null
        return null;

    }
}

 定义好了转换器后,需要在springmvc.xml中进行如下配置:

转换器配置

此时就可以了。但有时候会提交之后发现提交的数据有乱码现象,那么就配置一个过滤器来进行解决。在web.xml中配置:

post乱码解决

4.2 包装的POJO类型

这个包装类型pojo与上面普通的pojo有啥区别呢?包装类型pojo指的是pojo中有另一个也是pojo的属性,即pojo中套pojo。

看一下下面这个包装类型的pojo:

包装类型pojo

图中显示,在ItemsQueryVo的这个类中又包含着itemsCustom包装类,这就是包装的pojo类型。

       那么使用包装的pojo类型时,这个ItemsCustom中有name属性,假如我们要想将前台传进来的name属性封装到ItemsCustom中的name属性中,该如何传入呢?这就是包装类型的pojo参数绑定问题。

前端的属性绑定:

包装pojo参数 

然后controller中方法的形参传入包装类型的pojo,即ItemsQueryVo,打个断点,即可查看值有没有传进来。如下:

后台接收

5.集合类型的绑定

5.1 数组的绑定

        数组的绑定指的是前台传来多个同一类型的数据,在controller中使用数组形参来接收前台传来的数据。比如现在我们要批量删除商品,那么我们需要勾选好几个商品,这些商品都有id号,在controller中,我们需要将这些id号全部获取并放到一个数组中,然后再根据数组中的id号挨个删除数据库中对应的项。那么该如何绑定呢?如下: 

前端传入的参数:

前台传入id

添加到包装类中:

Controller层中的代码:

数组

5.2 List绑定

     我们进行修改一个商品提交时,需要绑定一个pojo类,通常在需要批量提交数据时,就将提交的数据绑定到list<pojo>类中,比如:成绩录入(录入多门课成绩,批量提交),在这里我们假设有需求:批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中,即一次性更新多个商品信息。 
  所以思路是在上述扩展类ItemsQueryVo中新添加一个List<ItemsCustom>,然后将不同商品的信息都存到这个List中,所以修改如下:

List

Controller层中的代码:

批量更新

      前端jsp页面中是如何传入参数的呢?这是我们所关心的问题,因为后台形参中接收数据用的就是包装类ItemsQueryVo。看下面: 

传参

前端的name属性是通过类似于list[i].name这种形式来传递参数的。list[i]表示第i个ItemsCustom,然后 list[i].属性 表示第i个ItemsCustom中对应的属性。

问题:如果我在形参上不绑定ItemsQueryVo,直接绑定List<ItemsCustom> itemsList可以吗?

回答:不可以,这样做springmvc不认识,所以只有先封装进QueryVo中,再进行执行。

5.3 Map的绑定

Map的绑定其实和List的绑定是差不多的,首先也是在包装的pojo中新添加一个Map类型的属性,如(我随便举个例子,跟本例无关了)

我定义一个QueryVo 的包装pojo类:

关键是前端传递参数时候和List传参有所区别,Map是这样传参的:

我们可以看到,Map的参数绑定传来的是Map中的key,然后value值会直接自动绑定到Map中的那个对象的属性中。

猜你喜欢

转载自blog.csdn.net/MyBloggerlxs/article/details/81628445