在springmvc中,可以对前台传递过来的参数进行与后台实体绑定(第二种方式相对较好).
比如:
前台页面:
1 <form action="${pageContext.request.contextPath}/test/test" method="POST"> 2 用户名:<input type="text" name="name"><br/> 3 <input type="submit" value="提交"> 4 </form>
实体类:
1 package com.yemaozi.rms.domain; 2 3 public class Student { 4 private Integer id; 5 private String name; 6 public Integer getId() { 7 return id; 8 } 9 public void setId(Integer id) { 10 this.id = id; 11 } 12 public String getName() { 13 return name; 14 } 15 public void setName(String name) { 16 this.name = name; 17 } 18 }
对应的Controller:
1 @Controller 2 @Scope(value="prototype") 3 @RequestMapping("/test") 4 public class TestController { 5 @RequestMapping("/test") 6 public String test(Student stu){ 7 System.out.println(stu.getName()); 8 return "success"; 9 } 10 }
这样,在Controller是可以进行绑定的....
但是,若是,要对多个实体数据进行绑定,而且这些实体有同名的属性....
前台页面:
<form action="${pageContext.request.contextPath}/test/test" method="POST"> 学生姓名:<input type="text" name="name"><br/> 老师姓名:<input type="text" name="name"><br/> <input type="submit" value="提交"> </form>
实体类:
1 public class Teacher { 2 private Integer id; 3 private String name; 4 public Integer getId() { 5 return id; 6 } 7 public void setId(Integer id) { 8 this.id = id; 9 } 10 public String getName() { 11 return name; 12 } 13 public void setName(String name) { 14 this.name = name; 15 } 16 }
Controller:
1 @RequestMapping("/test") 2 public String test(Student stu, Teacher teacher){ 3 System.out.println(stu.getName() + teacher.getName()); 4 return "success"; 5 }
这样,就会明白,name并不是唯一标识了,所以,在后台不能精确的绑定,其实,若是将该表单进行提交,则会将这两个name属性分别都添加到stu 和teacher这两个对象中..
因为springmvc中,是根据属性来进行数据绑定的,不像struts2是基于ognl的数据绑定机制.
要解决现在这样问题的方案一:
复合实体:
即:
1 public class StuTeacher { 2 private Student stu; 3 private Teacher teacher; 4 public Student getStu() { 5 return stu; 6 } 7 public void setStu(Student stu) { 8 this.stu = stu; 9 } 10 public Teacher getTeacher() { 11 return teacher; 12 } 13 public void setTeacher(Teacher teacher) { 14 this.teacher = teacher; 15 } 16 }
创建一个拥有stu和teacher这两个实体对象的类StuTeacher.....
这样我们就可以再前台这样书写.
1 <form action="${pageContext.request.contextPath}/test/test1" method="POST"> 2 学生姓名:<input type="text" name="stu.name"><br/> 3 老师姓名:<input type="text" name="teacher.name"><br/> 4 <input type="submit" value="提交"> 5 </form>
就可以根据复合实体中的属性通过.进行导航绑定数据
在Controller中的代码:
1 @RequestMapping("/test1") 2 public String test1(StuTeacher stuTeacher){ 3 System.out.println(stuTeacher); 4 return "success"; 5 }
这种方法可以简单的处理这种数据绑定问题,好处是不需要添加任何插件代码,缺点是 扩展性不好,后期可能使得代码臃肿.
所以可以在springmvc中可以进行自定义ModelAttributeProcessor来进行数据绑定的扩展.
1,自定义注解:
1 import java.lang.annotation.Documented; 2 import java.lang.annotation.ElementType; 3 import java.lang.annotation.Retention; 4 import java.lang.annotation.RetentionPolicy; 5 import java.lang.annotation.Target; 6 7 8 @Target({ElementType.PARAMETER, ElementType.METHOD}) 9 @Retention(RetentionPolicy.RUNTIME) 10 @Documented 11 public @interface ExtModelAttribute { 12 String value() default ""; 13 }
2,继承ServletModelAttributeMethodProcessor类,实现自己的数据绑定模式.
1 import javax.servlet.ServletRequest; 2 3 import org.springframework.core.MethodParameter; 4 import org.springframework.web.bind.ServletRequestDataBinder; 5 import org.springframework.web.bind.WebDataBinder; 6 import org.springframework.web.context.request.NativeWebRequest; 7 import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor; 8 9 public class ExtServletModelAttributeMethodProcessor extends 10 ServletModelAttributeMethodProcessor { 11 12 public ExtServletModelAttributeMethodProcessor() { 13 super(false); 14 } 15 16 public ExtServletModelAttributeMethodProcessor(boolean annotationNotRequired) { 17 super(annotationNotRequired); 18 } 19 20 @Override 21 public boolean supportsParameter(MethodParameter parameter) { 22 if (parameter.hasParameterAnnotation(ExtModelAttribute.class)) { 23 return true; 24 } else { 25 return false; 26 } 27 } 28 29 @Override 30 protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) { 31 ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class); 32 ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder; 33 servletBinder.setFieldDefaultPrefix(servletBinder.getObjectName() + "."); 34 servletBinder.bind(servletRequest); 35 } 36 }
3,在springmvc配置文件中添加相应的加载驱动配置
1 <mvc:annotation-driven> 2 <!--添加在此处--> 3 <mvc:argument-resolvers> 4 <bean class="com.yemaozi.springmvc.ext.databind.ExtServletModelAttributeMethodProcessor"/> 5 </mvc:argument-resolvers> 6 </mvc:annotation-driven>
4,应用
在前台页面中:
<form action="${pageContext.request.contextPath}/test/test1" method="POST"> 学生姓名:<input type="text" name="stu.name"><br/> 老师姓名:<input type="text" name="teacher.name"><br/> <input type="submit" value="提交"> </form>
在Controller中使用方式:
1 @RequestMapping("/test2") 2 public String test2(@ExtModelAttribute("stu") Student stu, @ExtModelAttribute("teacher")Teacher teacher){ 3 System.out.println(stu.getName() + teacher.getName()); 4 return "success"; 5 }
使用刚才自定义的注解来标注对应的属性.