参数绑定过程

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

简单类型参数绑定

        在Spring MVC中还可以自定义简单类型,这些类型也是直接在Controller类的方法中定义,在处理key/value信息时,就会以key名寻找Controller类的方法中具有相同名称的形参并进行绑定。例如下面的例子:

@RequestMapping(value="/queryFruit",method={RequestMethod.GET})
public String queryFruitsById(Model model,Integer id) throws Exception{
    Fruits fruit = fruitsService.queryFruitById(id);
    //通过形参中的model将model数据传到界面
    //相当于modelAndView.addObject方法
    model.addAttribute("fruit",fruit);
    return "fruits/fruitsDetail";
}

可以在执行queryFruit请求时,为其指定一个参数id,由于通过RequestMapping的method属性指定了请求类型为GET类型,所以使用下面的URL请求,就可以获得id为1的水果商品的详细信息。

http://localhost:8080/SpringMVC/test/queryFruit.action?id=1

当然,如果参数名字不为“id”,绑定就不会成功,但是可以通过@RequestParam注解可以对自定义简单类型的参数进行绑定,即如果使用@RequestParam,就无需设置controller方法的形参名称与request传入的参数名称一致。若不使用@RequestParam,则两者必须一致,这样才能绑定成功。下面例子就是出入的属性名称为fruit_id,实际用的是fruitId。

@RequestMapping(value="/queryFruit",method={RequestMethod.GET})
public String queryFruitById(Model model,@RequestParam(value="fruit_id") Integer fruitId) throws Exception{
    //implements
}

当Controller有多个形参时,如果请求中不包含其中的某个形参,此时是不会报错的,若要求不能为空,则这样写

@RequestMapping(value="/queryFruit",method={RequestMethod.GET})
public String queryFruitById(Model model,@RequestParam(value="fruit_id",
    required=true) Integer fruitId) throws Exception{
    //implements
}

若期望他们为空时有个默认值,则这样写

@RequestMapping(value="/queryFruit",method={RequestMethod.GET})
public String queryFruitById(Model model,@RequestParam(value="fruit_id",defaultValue="1")         
Integer fruitId) throws Exception{
    //implements
}

包装类型参数绑定

界面以form表单提交的方式请求后台,可以看到name指定的名称为Fruits包装类的属性名,这种类型会被SpringMVC的处理器适配器解析,会创建具体的实体类,并将相关属性值通过set方法绑定到包装类中。

<form action="queryFruitsByCondition.action" method="post">
    名称:<input type="text" name="name"/>
    产地:<input type="text" name="producing_area"/>
    <input type="submit" value="搜索"/>
</form>

编写controller接收参数,该方法设置了两个参数,一个是返回视图数据的Model对象,一个是接收前端页面绑定的实体类对象

@Controller
@RequestMapping("query")
public class FindControllerTest{
    @RequestMapping("queryFruitsByCondition")
    public String queryFruitsByCondition(Model model,Fruits fruits){
        //implements
    }
}

同样也可以在形参中放置HttpServletRequest和HttpServletResponse

    @RequestMapping("queryFruitsByCondition")
    public String queryFruitsByCondition(Model model,HttpServletRequest request,
        HttpServletResponse response){
        Fruits fruits = request.getParameter("fruits");
        //省略
    }
}

其实在包装类中也可以嵌套包装类,即Java实体类中包含其他实体类,此时SpringMVC依然可以解析并成功绑定该类型的包装类。实例如下,首先设定实体类:

public class UserAndProductQryModel{
    private User user;
    private Fruits userFruits;
    //set,get
}

在进行查询的时候,指定input的name属性为"包装对象.属性"的形式。

<form action="queryFruitsByCondition.action" method="post">
    名称:<input type="text" name="userFruits.name"/>
    产地:<input type="text" name="userFruits.producing_area"/>
    <input type="submit" value="搜索"/>
</form>

在Controller中拿到该类型也很简单

    @RequestMapping("queryFruitsByCondition")
    public String queryFruitsByCondition(Model model,UserAndProductQryModel uapqm){
        String name = uapqm.getUserFruits().getName();
        //省略
    }
}

注意:因为搜索条件中中文信息,可能中文数据传输到后台会发生中文乱码的情况,此时需要配置一个过滤器,对传输的数据格式进行统一的转码,一般会在web.xml中设置Spring MVC的转码过滤器来解决这种问题:

  <filter>
    <filter-name>encodingFilter</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>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

集合类型参数绑定

一般批量请求的请求参数在Java中是以数组或者集合的形式接收的,SpringMVC提供了接收和解析数据和集合参数类型的机制。

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

<form action="queryFruitsByCondition.action" method="post">
    <table width="300px;" border=1>
    <tr>
        <td>选择</td>
        <td>名称</td>
        <td>价格</td>
        <td>产地</td>
    </tr>
    <c:forEach items=${fruitsList} var ="fruit">
    <tr>
        <td><input type="checkbox" name="fids" value="${fruit.id}"</td>
        <td>${fruit.name}</td>
        <td>${fruit.price}</td>
        <td>${fruit.producing_area}</td>
    </tr>
    </c:forEach>
    </table>
<input type="submit" value="批量提交"
</form>

此时一个或多个被选中的input控件的name是相同的,这就需要使用一个name相同的数组类型的参数去接受批量参数,所以,在Web端使用一个名为fids的形参去接收批量请求的参数;注意form表单name属性要和Controller相关方法形参保持一致

    @RequestMapping("fruitsArrayTest")
    public String fruitsArrayTest(Model model,int [] fids){
        for(int i=0;i<fids.length;i++){
            System.out.println(fids[i]);
        }
    }
}

集合类型的请求参数:把页面上的批量数据通过springMVC转换为WEB端的List类型的对象时,每一组数据的input控件的name属性使用“集合名[下标].属性”的形式。首先设定model

public class ListQryModel{
    private List<Fruits> fruitList;
    //set,get
}

界面如下:

<form action="fruitsListTest.action" method="post">
    <table width="300px;" border=1>
    <tr>
        <td>选择</td>
        <td>名称</td>
        <td>价格</td>
        <td>产地</td>
    </tr>
    <c:forEach items=${fruitsList} var ="fruit" varStatus="status">
    <tr>
        <td><input  name="fruitsList[${status.index}].name" value="${fruits.name}"</td>
        <td><input  name="fruitsList[${status.index}].price" value="${fruits.price}"</td>
        <td><input  name="fruitsList[${status.index}].producing_area" value="${fruits.producing_area}"</td>
    </tr>
    </c:forEach>
    </table>
<input type="submit" value="批量提交"
</form>

下面是Controller处理方法,注意form表单name属性要和Controller相关方法形参保持一致.

    @RequestMapping("fruitsListTest")
    public String fruitsArrayTest(Model model,ListQryModel listQryModel){
        List<Fruits> fruits = listQryModel.getFruitList();
        for(int i=0;i<fruits.size();i++){
           //
        }
    }
}

Map类型的请求参数:每一组数据的input控件的name属性使用“Map名['key值']”的形式。

设定model

public class MapQryModel{
    private Map<String,Object> fruitMap;
    //set,get
}

设定界面,这里每一个input的参数都使用了“Map名 ['key值']”的表达形式。

<form action="fruitsListTest.action" method="post">
    <table width="300px;" border=1>
    <tr>
        <td>选择</td>
        <td>名称</td>
        <td>价格</td>
        <td>产地</td>
    </tr>
    <tr>
        <td><input  name="fruitMap['name']" value="凤梨"</td>
        <td><input  name="fruitMap['price']" value="5.7"</td>
        <td><input  name="fruitMap['producing_area']" value="广州"</td>
    </tr>
    </table>
<input type="submit" value="批量提交"
</form>

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

    @RequestMapping("fruitsListTest")
    public String fruitsMap(Model model,MapQryModel mapQryModel){
        Map<String,Object> fruitMap = mapQryModel.getFruitMap();
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值