[Spring MVC] - SpringMVC的各种参数绑定方式
SpringMVC的各种参数绑定方式
1. 基本数据类型(以int为例,其他类似):
Controller代码:
@RequestMapping("saysth.do") public void test(int count) { }
表单代码:
<form action="saysth.do" method="post"> <input name="count" value="10" type="text"/> ...... </form>
表单中input的name值和Controller的参数变量名保持一致,就能完成数据绑定,如果不一致可以使用@RequestParam注解。需要注意的是,如果Controller方法参数中定义的是基本数据类型,但是从页面提交过来的数据为null或者”"的话,会出现数据转换的异常。也就是必须保证表单传递过来的数据不能为null或”",所以,在开发过程中,对可能为空的数据,最好将参数数据类型定义成包装类型,具体参见下面的例子。
2. 包装类型(以Integer为例,其他类似):
Controller代码:
@RequestMapping("saysth.do") public void test(Integer count) { }
表单代码:
<form action="saysth.do" method="post"> <input name="count" value="10" type="text"/> ...... </form>
和基本数据类型基本一样,不同之处在于,表单传递过来的数据可以为null或”",以上面代码为例,如果表单中num为”"或者表单中无num这个input,那么,Controller方法参数中的num值则为null。
3. 自定义对象类型:
Model代码:
public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Controller代码:
@RequestMapping("saysth.do") public void test(User user) { }
表单代码:
<form action="saysth.do" method="post"> <input name="firstName" value="张" type="text"/> <input name="lastName" value="三" type="text"/> ...... </form>
非常简单,只需将对象的属性名和input的name值一一匹配即可。
4. 自定义复合对象类型:
Model代码:
public class ContactInfo { private String tel; private String address; public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } public class User { private String firstName; private String lastName; private ContactInfo contactInfo; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public ContactInfo getContactInfo() { return contactInfo; } public void setContactInfo(ContactInfo contactInfo) { this.contactInfo = contactInfo; } }
Controller代码:
@RequestMapping("saysth.do") public void test(User user) { System.out.println(user.getFirstName()); System.out.println(user.getLastName()); System.out.println(user.getContactInfo().getTel()); System.out.println(user.getContactInfo().getAddress()); }
表单代码:
<form action="saysth.do" method="post"> <input name="firstName" value="张" /><br> <input name="lastName" value="三" /><br> <input name="contactInfo.tel" value="13809908909" /><br> <input name="contactInfo.address" value="北京海淀" /><br> <input type="submit" value="Save" /> </form>
User对象中有ContactInfo属性,Controller中的代码和第3点说的一致,但是,在表单代码中,需要使用“属性名(对象类型的属性).属性名”来命名input的name。
5. List绑定:
List需要绑定在对象上,而不能直接写在Controller方法的参数中。
Model代码:
public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } public class UserListForm { private List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } }
Controller代码:
@RequestMapping("saysth.do") public void test(UserListForm userForm) { for (User user : userForm.getUsers()) { System.out.println(user.getFirstName() + " - " + user.getLastName()); } }
表单代码:
<form action="saysth.do" method="post"> <table> <thead> <tr> <th>First Name</th> <th>Last Name</th> </tr> </thead> <tfoot> <tr> <td colspan="2"><input type="submit" value="Save" /></td> </tr> </tfoot> <tbody> <tr> <td><input name="users[0].firstName" value="aaa" /></td> <td><input name="users[0].lastName" value="bbb" /></td> </tr> <tr> <td><input name="users[1].firstName" value="ccc" /></td> <td><input name="users[1].lastName" value="ddd" /></td> </tr> <tr> <td><input name="users[2].firstName" value="eee" /></td> <td><input name="users[2].lastName" value="fff" /></td> </tr> </tbody> </table> </form>
其实,这和第4点User对象中的contantInfo数据的绑定有点类似,但是这里的UserListForm对象里面的属性被定义成List,而不是普通自定义对象。所以,在表单中需要指定List的下标。值得一提的是,Spring会创建一个以最大下标值为size的List对象,所以,如果表单中有动态添加行、删除行的情况,就需要特别注意,譬如一个表格,用户在使用过程中经过多次删除行、增加行的操作之后,下标值就会与实际大小不一致,这时候,List中的对象,只有在表单中对应有下标的那些才会有值,否则会为null,看个例子:
表单代码:
<form action="saysth.do" method="post"> <table> <thead> <tr> <th>First Name</th> <th>Last Name</th> </tr> </thead> <tfoot> <tr> <td colspan="2"><input type="submit" value="Save" /></td> </tr> </tfoot> <tbody> <tr> <td><input name="users[0].firstName" value="aaa" /></td> <td><input name="users[0].lastName" value="bbb" /></td> </tr> <tr> <td><input name="users[1].firstName" value="ccc" /></td> <td><input name="users[1].lastName" value="ddd" /></td> </tr> <tr> <td><input name="users[20].firstName" value="eee" /></td> <td><input name="users[20].lastName" value="fff" /></td> </tr> </tbody> </table> </form>
这个时候,Controller中的userForm.getUsers()获取到List的size为21,而且这21个User对象都不会为null,但是,第2到第19的User对象中的firstName和lastName都为null。打印结果:
aaa - bbb
ccc - ddd
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
null - null
eee - fff
6. Set绑定:
Set和List类似,也需要绑定在对象上,而不能直接写在Controller方法的参数中。但是,绑定Set数据时,必须先在Set对象中add相应的数量的模型对象。
Model代码:
public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } public class UserSetForm { private Set<User> users = new HashSet<User>(); public UserSetForm() { users.add(new User()); users.add(new User()); users.add(new User()); } public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } }
Controller代码:
@RequestMapping("saysth.do") public void test(UserSetForm userForm) { for (User user : userForm.getUsers()) { System.out.println(user.getFirstName() + " - " + user.getLastName()); } }
表单代码:
<form action="saysth.do" method="post"> <table> <thead> <tr> <th>First Name</th> <th>Last Name</th> </tr> </thead> <tfoot> <tr> <td colspan="2"><input type="submit" value="Save" /></td> </tr> </tfoot> <tbody> <tr> <td><input name="users[0].firstName" value="aaa" /></td> <td><input name="users[0].lastName" value="bbb" /></td> </tr> <tr> <td><input name="users[1].firstName" value="ccc" /></td> <td><input name="users[1].lastName" value="ddd" /></td> </tr> <tr> <td><input name="users[2].firstName" value="eee" /></td> <td><input name="users[2].lastName" value="fff" /></td> </tr> </tbody> </table> </form>
基本和List绑定类似。
需要特别提醒的是,如果最大下标值大于Set的size,则会抛出org.springframework.beans.InvalidPropertyException异常。所以,在使用时有些不便。
7. Map绑定:
Map最为灵活,它也需要绑定在对象上,而不能直接写在Controller方法的参数中。
Model代码:
public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } public class UserMapForm { private Map<String, User> users; public Map<String, User> getUsers() { return users; } public void setUsers(Map<String, User> users) { this.users = users; } }
Controller代码:
@RequestMapping("saysth.do") public void test(UserMapForm userForm) { for (Map.Entry<String, User> entry : userForm.getUsers().entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue().getFirstName() + " - " + entry.getValue().getLastName()); } }
表单代码:
<form action="saysth.do" method="post"> <table> <thead> <tr> <th>First Name</th> <th>Last Name</th> </tr> </thead> <tfoot> <tr> <td colspan="2"><input type="submit" value="Save" /></td> </tr> </tfoot> <tbody> <tr> <td><input name="users['x'].firstName" value="aaa" /></td> <td><input name="users['x'].lastName" value="bbb" /></td> </tr> <tr> <td><input name="users['y'].firstName" value="ccc" /></td> <td><input name="users['y'].lastName" value="ddd" /></td> </tr> <tr> <td><input name="users['z'].firstName" value="eee" /></td> <td><input name="users['z'].lastName" value="fff" /></td> </tr> </tbody> </table> </form>
打印结果:
x: aaa - bbb
y: ccc - ddd
z: eee - fff
总述一:
SpringMVC页面传入值,一共有三种方式:
request,方法参数,对象;
//其实有篇思路比较清晰的博文,建议大家读一下:SpringMVC——接收请求参数和页面传参
首先配置和搭建项目,在web.xml中配置控制器,配置容器中打开注解扫描和注解的驱动。
<span style="font-size:18px;"><!--开启 注解的包扫描-->
<context:component-scan base-package="com.throne"></context:component-scan>
<!--配置我们的mvc驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--配置 视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans></span>
在这个之后,也就不用在增加其他内容了,相当方便。
1.使用request
java类:
public String login3(HttpServletRequest req){
String id=req.getParameter("id");
String name=req.getParameter("name");
System.out.println(id);
System.out.println(name);
return "Hello";
}
String id=req.getParameter("id");String name=req.getParameter("name");// 打印一下System.out.println(id);System.out.println(name);return "Hello";}
2 使用方法参数接受参数,注意如果方法参数名字和传入的参数名字一致,则正确用,如果不一致,则使用@RequestParam这个注入标签
<span style="font-size:18px;">@RequestMapping("/login.do")
public String login1(String id,@RequestParam("name") String na){
System.out.println(id);
System.out.println(na);
return "Hello";
//因为hyml中的id,name与此参数相同所以,spring会直接自动注入,
}</span>
<span style="font-size:18px;"> @RequestMapping("/login.do")
public String addUser5(@ModelAttribute Student s) {
System.out.println("userName is:"+s.getId());
System.out.println("password is:"+s.getName());
return "Hello";
} <pre name="code" class="java">@Component
public class Student implements Serializable{
private String id;
private String name;
public Student() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}</span>
SpringMVC向页面传出值
注意:在调试的时候,有些浏览器会有缓存,导致在测试其他传值的时候,无法预计效果,此时需要清理浏览器缓存。
<span style="font-size:18px;">//第一种 往外传值方式
public ModelAndView login5(String id, String demo){
Map<String,Object> map=new HashMap<String, Object>();
//建议使用map
map.put("idsss", id);
map.put("demosss", demo);
return new ModelAndView("Hello1", map);
}
//第二种 往外传值方式
@RequestMapping("/login.do")
public String login6(String id, String name,ModelMap model){
model.addAttribute("id", id);
model.addAttribute("name", name);
return "Hello1";
}
//第三种往外传值方式 @ModelAttribute
public String login8(@ModelAttribute Student s){
System.out.println(s.getId());
System.out.println(s.getName());
return "Hello1";
}
//第四种往外传值方式 @ModelAttribute
public String login9(HttpServletRequest req){
String id=req.getParameter("id");
String name=req.getParameter("name");
req.setAttribute("idsdfasdf", id);
req.setAttribute("sdfsad", name);
//idsdfasdf与sdfsad名字随意
return "Hello1";
}
//第五种往外传值方式 @ModelAttribute
// 得到session的方式 有两种
public String login10(String id ,String name,HttpSession session){
session.setAttribute("idsdfasdf", id);
session.setAttribute("sdfsad", name);
return "Hello1";
}</span>
springmvc请求参数获取的几种方法
1、直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交。
/** * 1.直接把表单的参数写在Controller相应的方法的形参中 * @param username * @param password * @return */ @RequestMapping("/addUser1") public String addUser1(String username,String password) { System.out.println("username is:"+username); System.out.println("password is:"+password); return "demo/index"; }
url形式:http://localhost/SSMDemo/demo/addUser1?username=lixiaoxi&password=111111 提交的参数需要和Controller方法中的入参名称一致。
2、通过HttpServletRequest接收,post方式和get方式都可以。
/** * 2、通过HttpServletRequest接收 * @param request * @return */ @RequestMapping("/addUser2") public String addUser2(HttpServletRequest request) { String username=request.getParameter("username"); String password=request.getParameter("password"); System.out.println("username is:"+username); System.out.println("password is:"+password); return "demo/index"; }
3、通过一个bean来接收,post方式和get方式都可以。
(1)建立一个和表单中参数对应的bean
package demo.model; public class UserModel { private String username; private String password; 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; } }
(2)用这个bean来封装接收的参数
/** * 3、通过一个bean来接收 * @param user * @return */ @RequestMapping("/addUser3") public String addUser3(UserModel user) { System.out.println("username is:"+user.getUsername()); System.out.println("password is:"+user.getPassword()); return "demo/index"; }
4、通过@PathVariable获取路径中的参数
/** * 4、通过@PathVariable获取路径中的参数 * @param username * @param password * @return */ @RequestMapping(value="/addUser4/{username}/{password}",method=RequestMethod.GET)
public String addUser4(@PathVariable String username,@PathVariable String password) { System.out.println("username is:"+username); System.out.println("password is:"+password); return "demo/index"; }
例如,访问http://localhost/SSMDemo/demo/addUser4/lixiaoxi/111111 路径时,则自动将URL中模板变量{username}和{password}绑定到通过@PathVariable注解的同名参数上,即入参后username=lixiaoxi、password=111111。
5、使用@ModelAttribute注解获取POST请求的FORM表单数据
Jsp表单如下:
<form action ="<%=request.getContextPath()%>/demo/addUser5" method="post"> 用户名: <input type="text" name="username"/><br/> 密 码: <input type="password" name="password"/><br/> <input type="submit" value="提交"/> <input type="reset" value="重置"/> </form>
Java Controller如下:
/** * 5、使用@ModelAttribute注解获取POST请求的FORM表单数据 * @param user * @return */ @RequestMapping(value="/addUser5",method=RequestMethod.POST) public String addUser5(@ModelAttribute("user") UserModel user) { System.out.println("username is:"+user.getUsername()); System.out.println("password is:"+user.getPassword()); return "demo/index"; }
6、用注解@RequestParam绑定请求参数到方法入参
当请求参数username不存在时会有异常发生,可以通过设置属性required=false解决,例如: @RequestParam(value="username", required=false)
/** * 6、用注解@RequestParam绑定请求参数到方法入参 * @param username * @param password * @return */ @RequestMapping(value="/addUser6",method=RequestMethod.GET) public String addUser6(@RequestParam("username") String username,@RequestParam("password") String password) { System.out.println("username is:"+username); System.out.println("password is:"+password); return "demo/index"; }