温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何进行Java中对象与表单的自动装配

发布时间:2021-10-29 10:29:33 来源:亿速云 阅读:128 作者:柒染 栏目:编程语言

这期内容当中小编将会给大家带来有关如何进行Java中对象与表单的自动装配,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

时下很多 Web 框架 都实现了 Form 表单域与 Java 对象属性的自动装配功能,该功能确实非常有用,试想如果没这功能则势必到处冲积着 request.getParameter() 系列方法与类型转换方法的调用。重复代码量大,容易出错,同时又不美观,影响市容。

现在的问题是,这些框架通过什么方法实现自动装配的?如果不用这些框架我们自己如何去实现呢?尤其对于那些纯 JSP/Servlet 应用,要是拥有自动装配功能该多好啊!本座深知各位之期盼,决定把自动装配的原理和实现方法娓娓道来。

实现原理其实比较简单,主要由以下3个步骤构成:

  • 通过 request.getParameterMap() 获取被提交的 Form 的所有表单域的名称-值映射,其中名称和值均为字符串类型。

  • 利用 java.beans.PropertyDescriptor 对象获取 Java Bean 的所有属性的名称及其类型。

  • 把表单域的名称与 Bean 的属性的名称逐个进行匹配,当找到相匹配的属性时就调用 Bean 的 setter 方法把表单域的值设置给该 Bean 属性。当然,因为表单域的值总是字符串类型,很可能与 Bean 属性的类型不一致,所以在设置 Bean 属性前要进行必要的类型转换。

上面所表述的3点原理不知大家是否完全理解,没关系,下面我们通过一个具体的表单提交的例子来看一看实际的效果,首先看看待提交的表单页面及其代码:

如何进行Java中对象与表单的自动装配

<form action="checkbean.action" method="post">     First Name: <input type="text" name="firstName" value="丑">     <br>     Last Name: <input type="text" name="lastName" value="怪兽">     <br>     Birthday: <input type="text" name="birthday" value="1978-11-03">     <br>     Gender: 男 <input type="radio"" name="gender" value="false">         &nbsp;女 <input type="radio"" name="gender" value="true" checked="checked">     <br>     Working age: <select name="working-Age">         <option value="-1">-请选择-</option>         <option value="3">三年</option>         <option value="5" selected="selected">五年</option>         <option value="10">十年</option>         <option value="20">二十年</option>     </select>     <br>     Interest: 游泳 <input type="checkbox" name="its" value="1" checked="checked">         &nbsp;打球 <input type="checkbox" name="its" value="2" checked="checked">         &nbsp;下棋 <input type="checkbox" name="its" value="3">         &nbsp;打麻将 <input type="checkbox" name="its" value="4">         &nbsp;看书 <input type="checkbox" name="its" value="5" checked="checked">     <br> <br> <input type="submit" value="确 定">&nbsp;&nbsp;<input type="reset" value="重 置"> </form>

从上图可以看出,总共有6个表单域,其名称-值分别是:{"firstName" - "丑","lastName" - "怪兽","birthday" - "1978-11-03","gender" - "女","working-Age" - "5","its" - "1,2,5"},该表单需要提交给 checkbean.action 进行处理(请注意:不要一看到 .aciton 就以为是 struts2,骑白马的不一定都是唐僧!),下面来看看 CheckBean Action 的处理代码和 Bean 的定义:

import java.util.HashMap;  import java.util.Map;   import vo.Persion;   import com.bruce.mvc.ActionSupport;   public class CheckBean extends ActionSupport  {      @Override     public String execute()      {          // 如果表单元素的名称和 Form Bean 属性名不一致则使用 keyMap 进行映射          // key: 表单元素名称, value: Form Bean 属性名          Map<String, String> keyMap = new HashMap<String, String>();          keyMap.put("working-Age", "workingAge");          keyMap.put("its", "interest");                    /* 自动装配方法一 */         // 使用表单元素创建 Form Bean          // 如果表单元素的名称和 Form Bean 属性名完全一致则不需使用 keyMap 进行映射          Persion p = createFormBean(Persion.class, keyMap);                    /* 自动装配方法二 */         // 先创建 Form Bean 对象, 然后再填充它的属性          Persion p2 = new Persion();          fillFormBeanProperties(p2, keyMap);                    // 可以获取 Form Bean 的所有属性值          //Map<String, Object> result = BeanHelper.getProperties(p);                    // 把 p 设置为 request 属性,并最终在结果页面展示          setRequestAttribute("persion", p);                    return SUCCESS;      }  }
import java.util.Date;  import java.util.List;   public class Persion  {      private String firstName;      private String lastName;      private Date birthday;      private boolean gender;      private int workingAge;      private int[] interest;      private List<String> photos;       // getter 和 setter 方法      // (略)。。。。。。  }

从 CheckBean 的代码可以看出,它是通过 createFormBean() 或 fillFormBeanProperties() 方法来自动装配 Persion 的,它们之间的区别是:前者会直接创建新的 Persion 对象,而后者填充原有 Persion 对象的属性。请注意,如果表单域的名称与 Persion 对应的属性名不一致则用 keyMap 进行映射,如表单域 "working-Age" 是对应 Persion 的 workingAge 属性的,但它们的名称不一致,所以要进行映射。另外,Persion 有一个 photos 属性,而我们的表单域却没有,自动装配时会忽略该属性。最后看一下输出的结果页面及其代码:

如何进行Java中对象与表单的自动装配

<body>   <br>   <div align="right">       <a href="index.action"><u:msg key="jsp-set_locale.back-to-index"/></a>   </div>     <br><br><br><br>     <div align="center">     <table border="1">     <caption>Persion Attributs</caption>               <tr><td>Name</td><td><c:out value="${persion.firstName} ${persion.lastName}"/>&nbsp;</td></tr>         <tr><td>Brithday</td><td><c:out value="${persion.birthday}"/>&nbsp;</td></tr>         <tr><td>Gender</td><td><c:out value="${persion.gender}"/>&nbsp;</td></tr>         <tr><td>Working Age</td><td><c:out value="${persion.workingAge}"/>&nbsp;</td></tr>         <tr><td>Interest</td><td><c:forEach var="its" items="${persion.interest}">                                      <c:out value="${its}" /> &nbsp;                                </c:forEach>&nbsp;</td></tr>         <tr><td>Photos</td><td><c:forEach var="p" items="${persion.photos}">                                      <c:out value="${p}" /><br>                               </c:forEach>&nbsp;</td></tr>     </table>    </div>   </body>

通过上面的例子可以看到,通过自动装配 Bean,我们获得了非常大的便利。现在我们就从createFormBean() 和 fillFormBeanProperties() 开始,逐步揭开自动装配的神秘面纱,先看看下面两个类及其方法的定义:

package com.bruce.mvc;   import com.bruce.util.http.HttpHelper;   /** {@link Action} 对象公共基类 */ public class ActionSupport implements Action  {      private ServletContext servletContext;      private HttpServletRequest request;      private HttpServletResponse response;      private HttpSession session;       /** 默认 {@link Action} 入口方法(返回 {@link Action#SUCCESS}) */     public String execute()      {          return SUCCESS;      }       /** 使用表单元素创建 Form Bean (表单元素的名称和 Form Bean 属性名完全一致) */     public final <T> T createFormBean(Class<T> clazz)      {          return HttpHelper.createFormBean(request, clazz);      }       /** 使用表单元素创建 Form Bean (用 keyMap 映射与表单元素名称不对应的 Form Bean 属性) */     public final <T> T createFormBean(Class<T> clazz, Map<String, String> keyMap)      {          return HttpHelper.createFormBean(request, clazz, keyMap);      }            /** 使用表单元素填充 Form Bean (表单元素的名称和 Form Bean 属性名完全一致) */     public final <T> void fillFormBeanProperties(T bean)      {          HttpHelper.fillFormBeanProperties(request, bean);      }            /** 使用表单元素填充 Form Bean (用 keyMap 映射与表单元素名称不对应的 Form Bean 属性) */     public final <T> void fillFormBeanProperties(T bean, Map<String, String> keyMap)      {          HttpHelper.fillFormBeanProperties(request, bean, keyMap);      }            // 其它方法      // (略)。。。  }
package com.bruce.util.http;   import com.bruce.util.BeanHelper;   /** HTTP 帮助类 */ public class HttpHelper  {      /** 使用表单元素创建 Form Bean (表单元素的名称和 Form Bean 属性名完全一致) */     public final static <T> T createFormBean(HttpServletRequest request, Class<T> clazz)      {          return createFormBean(request, clazz, null);      }       /** 使用表单元素创建 Form Bean (用 keyMap 映射与表单元素名称不对应的 Form Bean 属性) */     public final static <T> T createFormBean(HttpServletRequest request, Class<T> clazz, Map<String, String> keyMap)      {          Map<String, String[]> properties = getParamMap(request);          return BeanHelper.createBean(clazz, properties, keyMap);      }            /** 使用表单元素填充 Form Bean (表单元素的名称和 Form Bean 属性名完全一致) */     public final static <T> void fillFormBeanProperties(HttpServletRequest request, T bean)      {          fillFormBeanProperties(request, bean, null);      }            /** 使用表单元素填充 Form Bean (用 keyMap 映射与表单元素名称不对应的 Form Bean 属性) */     public final static <T> void fillFormBeanProperties(HttpServletRequest request, T bean, Map<String, String> keyMap)      {       Map<String, String[]> properties = getParamMap(request);       BeanHelper.setProperties(bean, properties, keyMap);      }            /** 获取 {@link HttpServletRequest} 的所有参数名称和值 */     public final static Map<String, String[]> getParamMap(HttpServletRequest request)      {          return request.getParameterMap();      }       // 其它方法      // (略)。。。  }

哈哈,大家看到了吧,我们迂回了那么久,但 ActionSupport 类和 HttpHelper 类并没有并没有做多少事情,他们只是获取请求参数 Map,并传递给 BeanHelper 类的 createBean() 和 setProperties() 方法进行装配,实际负责装配工作的是 BeanHelper 。这里解析一下为何要写得那么迂回,其实这些代码是从本座自己写的 “Portal Web 开发框架” 中摘录出来的,总之一句话:是因为框架的需要而写得那么迂回的,并非本座有意而为之。顺便做下广告:“Portal Web 开发框架”是一套功能完备的 Web 服务端开发框架,内置 MVC Web 基础架构,支持可扩展的数据访问接口(已内置 Hibernate、MyBaits 和 JDBC 支持),集成拦截器、国际化、文件上传下载和缓存等基础 Web 服务,基于纯 Jsp/Servlet API 实现,非常容易学习和使用。尤其适合那些希望使用纯 Jsp/Servlet API 进行开发或对 SSH 等主流框架的复杂性感到繁琐与无奈的人士使用。该框架已通过多个商业项目考验,并不是写来玩的哦。如果各位有兴趣,本座以后再找个机会开个专贴详细介绍下这个框架。

不扯远了,回到我们的正题,我们再来看看 BeanHelper 的装配工装是如何实现的:

/** Java Bean 帮助类,执行 Java Bean 属性的 get / set 相关操作 */ public class BeanHelper  {      /** 创建指定类型的 Java Bean,并设置相关属性       *        *  @param clazz        : Bean 类型       *  @param properties    : 属性名 / 值映射<br>       *                        其中名称为 {@link String} 类型,与属性名称可能一直也可能不一致<br>       *                        属性值可能为以下 3 中类型:<br>       *                        &nbsp; &nbsp; 1) 属性的实际类型:直接对属性赋值<br>       *                        &nbsp; &nbsp; 2) {@link String} 类型:先执行自动类型转换再对属赋值<br>       *                        &nbsp; &nbsp; 3) {@link String}[] 类型:先执行自动类型转换再对属赋值<br>       *  @param keyMap        : properties.key / Bean 属性名映射,当 properties 的 key 与属性名不对应时,       *                        用 keyMap 把它们关联起来       *  @return                  生成的 Bean实例         */     public static final <B, T> B createBean(Class<B> clazz, Map<String, T> properties, Map<String, String> keyMap)      {          B bean = null;                    try         {              // 创建 Bean 实例              bean = clazz.newInstance();              // 设置 Bean 属性              setProperties(bean, properties, keyMap);          }          catch(Exception e)          {              throw new RuntimeException(e);          }                    return bean;      }            public static final <B, T> B createBean(Class<B> clazz, Map<String, T> properties)      {          return createBean(clazz, properties, null);      }       /** 设置 Java Bean 的属性       *        *  @param bean            : Bean 实例       *  @param properties    : 属性名 / 值映射<br>       *                        其中名称为 {@link String} 类型,与属性名称可能一直也可能不一致<br>       *                        属性值可能为以下 3 中类型:<br>       *                        &nbsp; &nbsp; 1) 属性的实际类型:直接对属性赋值<br>       *                        &nbsp; &nbsp; 2) {@link String} 类型:先执行自动类型转换再对属赋值<br>       *                        &nbsp; &nbsp; 3) {@link String}[] 类型:先执行自动类型转换再对属赋值<br>       *  @param keyMap        : properties.key / Bean 属性名映射,当 properties 的 key 与属性名不对应时,       *                        用 keyMap 把它们关联起来         */     public static final <T> void setProperties(Object bean, Map<String, T> properties, Map<String, String> keyMap)      {          // 获取所有 Bean 属性          Map<String, PropertyDescriptor> pps = getPropDescMap(bean.getClass());          Set<Map.Entry<String, T>> set        = properties.entrySet();                    // 根据属性名称设置 Bean 的每个属性值          for(Map.Entry<String, T> o : set)          {              String name    = null;    // 属性名称              String key    = o.getKey();                            if(keyMap != null)                  name = keyMap.get(key);              if(name == null)                  name = key;               T value    = o.getValue();              PropertyDescriptor pd = pps.get(name);    // 名称对应的 PropertyDescriptor                            if(pd != null && value != null)                  // 设置指定属性值                  setProperty(bean, pd, value);          }      }       public static final <T> void setProperties(Object bean, Map<String, T> properties)      {          setProperties(bean, properties, null);      }       // 设置指定属性值      private static final <T> boolean setProperty(Object bean, PropertyDescriptor pd, T value)      {          // 获取属性的 setter 方法          Method method = pd.getWriteMethod();          // 只处理 public 的实例 setter 方法          if(method != null && isPublicInstanceMethod(method))          {              method.setAccessible(true);                            Class<?> clazz = pd.getPropertyType();              // 设置具体属性值              setProperty(bean, value, method, clazz);                            return true;          }                    return false;      }       // 设置具体属性值      private static <T> void setProperty(Object bean, T value, Method method, Class<?> clazz)      {          Object param                = null;          Class<?> valueType        = value.getClass();          Class<?> valueComType    = valueType.getComponentType();          Class<?> clazzComType    = clazz.getComponentType();                    // 检查是否需要作类型转换                  if(              !clazz.isAssignableFrom(valueType)            &&              (                      (valueType.equals(String.class))        ||                   (valueType.isArray() && valueComType.equals(String.class))              )                                            &&              (                      (GeneralHelper.isSimpleType(clazz))        ||                   (clazz.isArray() && GeneralHelper.isSimpleType(clazzComType))              )          )              // 转换为目标类型的属性值              param = parseParameter(clazz, value);          else             param = value;                    // 调研 setter 方法设置属性值          invokeMethod(bean, method, param);      }            // 执行类型转换 (不解释了,看官们自己参详吧 ^_^)      private static final <T> Object parseParameter(Class<?> clazz, T obj)      {          Object param        = null;          Class<?> valueType    = obj.getClass();                    if(clazz.isArray())          {              String[] value = null;                            if(valueType.isArray())                  value    = (String[])obj;              else             {                  String str    = (String)obj;                  StringTokenizer st = new StringTokenizer(str, " ,;\t\n\r\f");                  value    = new String[st.countTokens()];                   for(int i = 0; st.hasMoreTokens(); i++)                      value[i] = st.nextToken();              }                            int length        = value.length;              Class<?> type    = clazz.getComponentType();              param            = Array.newInstance(type, length);               for(int i = 0; i < length; i++)              {                  String v = value[i];                  Object p = GeneralHelper.str2Object(type, v);                  Array.set(param, i, p);              }          }          else         {              String value = null;                            if(valueType.isArray())              {                  String[] array    = (String[])obj;                  if(array.length > 0)                      value = array[0];              }              else                 value = (String)obj;                            param = GeneralHelper.str2Object(clazz, value);          }                    return param;      }            // 其他方法      // (略)。。。  }
public class GeneralHelper  {      /** 简单数据类型集合 */     public static final Set<Class<?>> SMIPLE_CLASS_SET    = new HashSet<Class<?>>(18);       static     {          SMIPLE_CLASS_SET.add(int.class);          SMIPLE_CLASS_SET.add(long.class);          SMIPLE_CLASS_SET.add(float.class);          SMIPLE_CLASS_SET.add(double.class);          SMIPLE_CLASS_SET.add(byte.class);          SMIPLE_CLASS_SET.add(char.class);          SMIPLE_CLASS_SET.add(short.class);          SMIPLE_CLASS_SET.add(boolean.class);          SMIPLE_CLASS_SET.add(Integer.class);          SMIPLE_CLASS_SET.add(Long.class);          SMIPLE_CLASS_SET.add(Float.class);          SMIPLE_CLASS_SET.add(Double.class);          SMIPLE_CLASS_SET.add(Byte.class);          SMIPLE_CLASS_SET.add(Character.class);          SMIPLE_CLASS_SET.add(Short.class);          SMIPLE_CLASS_SET.add(Boolean.class);          SMIPLE_CLASS_SET.add(String.class);          SMIPLE_CLASS_SET.add(Date.class);      }       /** 检查 clazz 是否为简单数据类型 */     public final static boolean isSimpleType(Class<?> clazz)      {          return SMIPLE_CLASS_SET.contains(clazz);      }       /** String -> Any,如果 handler 为 null 则把字符串转换为 8 种基础数据类型、及其包装类、 {@link Date} 或 {@link String},       *                   如果 handler 不为 null 则由 handler 执行转换        *        * @param type    : 目标类型的 {@link Class} 对象       * @param v        : 要转换的字符串       * @param handler    : 类型转换处理器       * @return        : 转换结果,如果转换不成功返回 null       * @throws         : 如果目标类型不支持抛出 {@link IllegalArgumentException}       *        */     @SuppressWarnings("unchecked")      public static final <T> T str2Object(Class<T> type, String v, TypeHandler<T> handler)      {          Object param = null;                    if(handler != null)              return handler.handle(v);                    if(type == String.class)              param =  safeTrimString(v);          else if(type == int.class)              param =  str2Int_0(v);          else if(type == long.class)              param =  str2Long_0(v);          else if(type == byte.class)              param =  str2Byte_0(v);          else if(type == char.class)              param =  str2Char_0(v);          else if(type == float.class)              param =  str2Float_0(v);          else if(type == double.class)              param =  str2Double_0(v);          else if(type == short.class)              param =  str2Short_0(v);          else if(type == boolean.class)              param =  str2Boolean_False(v);          else if(type == Integer.class)              param =  str2Int(v);          else if(type == Long.class)              param =  str2Long(v);          else if(type == Byte.class)              param =  str2Byte(v);          else if(type == Character.class)              param =  str2Char(v);          else if(type == Float.class)              param =  str2Float(v);          else if(type == Double.class)              param =  str2Double(v);          else if(type == Short.class)              param =  str2Short(v);          else if(type == Boolean.class)              param =  str2Boolean(v);          else if(Date.class.isAssignableFrom(type))              param =  str2Date(v);          else             throw new IllegalArgumentException(String.format("object type '%s' not valid", type));                    return (T)param;      }            public static final <T> T str2Object(Class<T> type, String v)      {          return str2Object(type, v, null);      }            // 其他方法      // (略)。。。  }

从上面的代码可以看出,BeanHelper 支持8种简单数据类型及其包装类、String 和 Date 类型以及它们的数组类型的自动装配,最后强调一下:BeanHelper 和 GeneralHelper 其实是两个用途非常广泛的类,其作用不单是为了协助 Form 表单域自动装配 Bean 。下面列出一些使用例子,帮助大家进一步了解 BeanHelper 的使用方法:

package test;      import java.beans.IntrospectionException;   import java.util.Date;   import java.util.HashMap;   import java.util.Map;   import java.util.StringTokenizer;      import com.bruce.util.BeanHelper;   import com.bruce.util.GeneralHelper;      @SuppressWarnings("unused")   public class TestBeanHelper extends Object   {       public static void main(String[] args) throws Exception       {           test();           testStr2Object();           test_setProperty();           test_setProperties_1();           test_setProperties_2();       }          private static void test()       {           //System.out.println(GeneralHelper.str2Date("  1978-11-03  "));   //System.out.println(GeneralHelper.str2Date("  1978-11-03  "));   //GeneralHelper.str2Byte(null);   //GeneralHelper.str2Char_0(null);   //GeneralHelper.str2Boolean(null);   //GeneralHelper.str2Boolean_False(null);       }          private static void testStr2Object() throws IntrospectionException       {           int i = GeneralHelper.str2Object(int.class, "123");           Date dt = GeneralHelper.str2Object(Date.class, "1978-11-03");           String[] arr = GeneralHelper.str2Object(String[].class, "12, 34, 56, 78", new GeneralHelper.TypeHandler<String[]>()           {               @Override              public String[] handle(String v)               {                   StringTokenizer st = new StringTokenizer(v, " ,;\t\r\n\f");                   String[] result = new String[st.countTokens()];                                      for(int i = 0; st.hasMoreTokens(); i++)                       result[i] = st.nextToken();                                      return result;               }           });                      // !! error !!   // String[] arr2 = GeneralHelper.str2Object(String[].class, "12, 34, 56, 78");       }          private static void test_setProperty()       {           C c = new C();           BeanHelper.setProperty(c, "dt", "2010-10-10");           BeanHelper.setProperty(c, "i", 456);           BeanHelper.setProperty(c, "l", "999");           int i = BeanHelper.getProperty(c, "i");           double l = BeanHelper.getProperty(c, "l");           boolean b = BeanHelper.getProperty(c, "b");           Date dt = BeanHelper.getProperty(c, "dt");           System.out.println(c);       }          private static void test_setProperties_1() throws Exception       {           Map<String, String[]> objs = new HashMap<String, String[]>();           objs.put("si", new String[] {"888"});           objs.put("fi", new String[] {"999"});           objs.put("b", new String[] {"true"});           objs.put("i", new String[] {"1"});           objs.put("l", new String[] {"2.3"});           objs.put("dt", new String[] {"2011-09-17"});           objs.put("__str", new String[] {"我是怪兽"});           objs.put("__ia", new String[] {"12", "34", "56"});           objs.put("__sa", new String[] {"ab", "cd", "ef"});                      Map<String, String> keyMap = new HashMap<String, String>();           keyMap.put("__str", "str");           keyMap.put("__ia", "ia");           keyMap.put("__sa", "sa");                      C c = BeanHelper.createBean(C.class, objs, keyMap);           Map<String, Object> result = BeanHelper.getProperties(c);           System.out.println(result);       }              private static void test_setProperties_2() throws Exception       {           java.sql.Date dt = new java.sql.Date(new java.util.Date().getTime());                      Map<String, Object> objs = new HashMap<String, Object>();           objs.put("si", 888);           objs.put("fi", 999);           objs.put("b", "True");           objs.put("i", 123);           objs.put("l", "2.3");           //objs.put("dt", new String[] {"2011-09-17"});           objs.put("dt", dt);           objs.put("str", "我是怪兽");           objs.put("ia", new int[] {12, 34, 56});           objs.put("sa", "ab, cd, ef");                      C c = new C();           BeanHelper.setProperties(c, objs);           Map<String, Object> result = BeanHelper.getProperties(c);           System.out.println(result);       }                 }
package test;      import java.util.Date;         class A   {       private boolean b;          public boolean isB()       {           return b;       }          public void setB(boolean b)       {           this.b = b;       }      }      public class C extends A   {       static int si;       final int fi = 100;              private int i;       private Double l;       private Date dt;       private String str;       private int[] ia;       private String[] sa;          public String[] getSa()       {           return sa;       }       public void setSa(String[] sa)       {           this.sa = sa;       }       public static int getSi()       {           return si;       }       public static void setSi(int si)       {           C.si = si;       }       public int getFi()       {           return fi;       }       public String getStr()       {           return str;       }       public void setStr(String str)       {           this.str = str;       }       public int[] getIa()       {           return ia;       }       public void setIa(int[] ia)       {           this.ia = ia;       }       public int getI()       {           return i;       }       public void setI(int i)       {           this.i = i;       }       public Double getL()       {           return l;       }       public void setL(Double l)       {           this.l = l;       }       public Date getDt()       {           return dt;       }       public void setDt(Date dt)       {           this.dt = dt;       }       }

上述就是小编为大家分享的如何进行Java中对象与表单的自动装配了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI