接收表单数据有3种方式。
1、使用简单类型接收表单数据(绑定简单数据类型)
表单:
action会有提示,但我们需要在前面加${pageContext.request.contextPath}来获取项目名(/项目名的形式),否则会把后面的路径直接拼接到域名后面。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(String username, String password, int age){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("username", username); mav.addObject("password", password); mav.addObject("age", age); return mav; } }
参数名要和表单字段的name一致。
SpringMVC会自动将请求参数转换为需要的数据类型。
如果表单字段很多,业务方法要写很多参数,太麻烦,不推荐。
2、使用pojo类接收表单数据(绑定pojo类型)
pojo:
public class User { private String username; private String password; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
属性名要与表单字段的name一致。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(User user){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("user", user); return mav; } }
推荐使用。
3、使用扩展类接收表单数据(绑定pojo的包装类)
扩展类:
public class UserExt { private User user; //此处省略其它成员变量 public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
把bean写为成员变量。
表单:
这里的user对应扩展类中的成员变量名。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(UserExt userExt){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("userExt", userExt); return mav; } }
使用扩展类接收参数,主要是表单传过来的数据有一些不属于实体类,还需要用其它的成员变量来接收。
单选框、复选框的数据接收
单选框可用普通类型来接收。
复选框常用于同时勾选多个选项,比如选择爱好、批量删除等(同一个name、多个value)。
复选框使用数组来接收,复选框的name要与数组名一致。
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(String[] hobby){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("hobby",hobby); return mav; } }
批量修改,使用List来接收
有时候我们需要批量插入、批量修改。
比如视图以表格的形式列出了多个用户的信息,管理员在页面上修改了多个用户的信息,现在要提交修改,需要使用List
不能直接使用List
包装类:
public class UserVO { private Listlist; public ListgetList() { return list; } public void setList(List list) { this.list = list; } }
VO只有一个属性,及其getter、setter方法。
表单:
此处list对应包装类的成员变量名。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(UserVO userVO){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("list", userVO.getList()); return mav; } }
日期的接收
有时候需要接收表单传递的日期,比如生日。
后台有2种接收方式:
- 使用String接收日期
如果不进行相关计算,使用String表示日期即可;如果要进行相关计算,先用String接收日期,在业务方法中把String转换为Date(可以封装为工具类,在业务方法中调用)。
表单使用、都可以,type="text"要严格校验日期格式。
- 使用Date接收日期
表单使用、都可以,如果使用type="text",日期格式只能是 年/月/日 (/分隔)。
DataBinder 数据绑定
数据绑定的概念:将请求参数的内容与controller中业务方法的参数绑定,比如表单数据的提交。
数据绑定的流程:
(1)Spring MVC将ServletRequest对象传递给DataBinder
(2)Spring MVC从controller的业务方法的签名(声明)中获取参数表(形参名),把它传递给DataBinder
(3)DataBinder调用ConversionService对ServletRequest中的请求参数进行数据类型的转换、格式化
( ConversionService会根据 原始类型 ——目标类型 调用对应的Converter来进行数据转换。Spring MVC内置了常用的类型转换器,我们也可以自定义类型转换器。)
(4)DataBinder调用Validator校验已经被转换好的请求参数是否合法
(5)DataBinder调用BindingResult,把请求参数赋给业务方法中对应的参数,完成数据绑定。
解决前端传过来的数据中文乱码
使用spring mvc提供的编码过滤器,过滤所有请求。
在web.xml中配置:
<filter> <filter-name>characterEncodingFilterfilter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class> <init-param> <param-name>encodingparam-name> <param-value>utf-8param-value> init-param> filter> <filter-mapping> <filter-name>characterEncodingFilterfilter-name> <url-pattern>/*url-pattern> filter-mapping>
@RequestParam 必需的请求参数
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
就算请求参数中没有user_id这个字段,也会调用这个业务方法来处理,就是说参数不是必需传递的。
如果参数是必需的,要求HTTP请求参数中必需要有这个字段,可以这样:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(@RequestParam("user_id") int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
在参数表的最前面加@RequestParam,里面写必需的请求参数。
如果没有传递此参数,不会调用业务方法,直接报错。
注意:
必需和必填不是一个概念,必需是指请求参数中必须要有这个字段,只有要这个字段就行,值可以是空的。
如果一个表单字段(有name属性),没填就提交了,请求参数中是有这个字段的,只不过值是空的。
可以设置是否必需:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(@RequestParam(value = "user_id",required = false) int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
默认为true——必需,没传递该参数直接报错。
false——不是必需的,传不传递都行,都会调用业务方法。
可以设置默认值:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(@RequestParam(value = "user_id",defaultValue = "0") int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
如果没有传递此参数,会自动使用默认值。