SpringMVC在对应绑定不同实体,但具有相同属性名的解决方案....

在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 }

使用刚才自定义的注解来标注对应的属性.

时间: 2024-10-29 05:21:05

SpringMVC在对应绑定不同实体,但具有相同属性名的解决方案....的相关文章

MyBatis学习总结_04_解决字段名与实体类属性名不相同的冲突

一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('aaaa', 23); INSERT INTO orders(order_no, order_price) VALUES('bbbb', 33); INSER

MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突

在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('aaaa'

MyBatis——解决字段名与实体类属性名不相同的冲突

原文:http://www.cnblogs.com/xdp-gacl/p/4264425.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSER

Mybatis解决字段名与实体类属性名不相同的冲突

在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('aaaa'

MyBatis学习总结4--解决字段名与实体类属性名不相同的冲突

在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定是完全相同的,如果直接在xml映射文件中使用sql进行映射,会造成返回值为空的情况,下面阐述解决方案: 测试所用表和数据 create table orders( order_id int primary key auto_increment, order_no varchar(20), order_price float ); insert into orders(order_no, order_price) values('aaa

SpringMVC绑定到实体数组、list、set、和map时要注意

实体的属性前一定要用.分割,如果是使用jquery的ajax提交的一个js数组对象,则请求数据会被格式化为 var sub = [{name:1,num:2},{name:1,num:2}] $.post(url,{test,sub}) 但是springmvc绑定实体时,是检测“.”符号,“.”之前的作为实体list在其bean中的名称,“.”之后的作为实体的属性而存在的,所以这里要用“.”来分割属性与list名 要想使用jquery自带的方法格式化为下面这种形式是不可能的(因为中间带有的.符号

SpringMVC基本参数绑定(7种)

SpringMVC基本参数绑定(7种) 1.默认参数支持 HttpServletRequest HttpServletResponse HttpSession 示例: @RequestMapping("edit.action") public ModelAndView editShop(HttpServletRequest request){ ? String name= request.getParameter("id"); } 2.绑定基本类型(int,stri

springmvc(2)--参数绑定

一.以实例来看springmvc各种参数绑定方式 先定义个dto类: public class RestInDto implements Serializable { private static final long serialVersionUID = -5461373449802431627L; private String userName; private BigDecimal salary; private boolean isVip; private int id; ......

java android布局里的控件值 反射绑定给实体类,实体类绑定给控件,表单提交绑定很有用

注意了:根据实际情况,添加实体里字段的类型,控件类型的判断才可使用.这里控件只有TextView EditText 实体类字段只有String int类型,带值的控件添加tag ,值和实体类的字段值一致 package ice.ui.service; import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import jav