Java 内省
- 格式:doc
- 大小:47.50 KB
- 文档页数:4
JavaBean简单介绍及其应⽤Bean的中⽂含义是“⾖⼦”,顾名思义JavaBean是⼀段Java⼩程序。
JavaBean实际上是指⼀种特殊的Java类。
它通经常使⽤来实现⼀些⽐較经常使⽤的简单功能。
并能够⾮常easy的被重⽤或者是插⼊其它应⽤程序中去。
全部遵循⼀定编程原则的Java类都能够被称作JavaBean。
⼀. Java Bean技术概述Java Bean是基于Java的组件模型,由属性、⽅法和事件3部分组成。
在该模型中,JavaBean能够被改动或与其它组件结合以⽣成新组件或完整的程序。
它是⼀种Java类,通过封装成为具有某种功能或者处理某个业务的对象。
因此。
也能够通过嵌在JSP页⾯内的Java代码訪问Bean及其属性。
Bean的含义是可反复使⽤的Java组件。
所谓组件就是⼀个由能够⾃⾏进⾏内部管理的⼀个或⼏个类所组成、外界不了解其内部信息和执⾏⽅式的群体。
使⽤它的对象仅仅能通过接⼝来操作。
⼆. Java Bean编写规范Java Bean实际上是依据JavaBean技术标准所指定Bean的命名和设计规范编写的Java类。
这些类遵循⼀个接⼝格式。
以便于使函数命名、底层⾏为以及继承或实现的⾏为,其最⼤的长处在于可以实现代码的可重⽤性。
Bean并不须要继承特别的基类(BaseClass)或实现特定的接⼝(Interface)。
Bean的编写规范使Bean的容器(Container)可以分析⼀个Java类⽂件。
并将其⽅法(Methods)翻译成属性(Properties),即把Java类作为⼀个Bean类使⽤。
Bean的编写规范包含Bean类的构造⽅法、定义属性和訪问⽅法编写规则。
2.1. Bean组件的⼯作机制在JavaBeansVersion1.01 A规范中定义了该组件的5种重要机制:(1)内省(Introspection):组建能够发表其⽀持的操作和属性。
同⼀时候也⽀持在其它组件中发现反复利⽤的对象库,如⽤户权限控制和电⼦邮件⾃⼰主动回复等。
Java 是一种面向对象的语言万事万物皆对象 People 描述所有人这一类对象对象 具体的一个人Class 描述所有类这一类对象存在共性对象 具体的一个类Method 描述所有方法这一类对象存在共性对象 具体的一个方法Field描述所有属性这一类对象存在共性对象 具体的一个属性(1) 写一个方法传递一个对象和某个属性对应的get 方法名,得到属性值(2) 写一个方法传递一个对象和某个属性对应的get 方法名,得到属性值Java Introspection Reflection一、java反射机制JA V A反射机制是在运行状态中,对于任意一个类,都能够得到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制;用一句比较白的话来概括,反射就是让你可以通过名称来得到对象类,属性,方法的技术;例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值;Java反射机制主要提供了以下功能:1、为一个类生成对应的Class对象运用已知对象getClass:Object类中的方法,每个类都拥有此方法;如:String str=new String;Class strClass=;运用已知子类的class :Class类中的方法,返回该Class的父类的Class;运用已知类全名静态方法运用已知类类名.class2、通过类名来构造一个类的实例a、调用无参的构造函数:Class newoneClass = 类全名;;b、调用有参的构造函数:我们可以自定义一个函数;public Object newInstanceString className, Object args throws Exception {etClass;}Constructor cons = argsClass; etClass;}etPropertyType.isArray etReadMethod.invokepb, null;":";etReadMethod.invokepb, null;}}etPropertyType.isArray{ifpd0i.getName.equals"childname";{ifpd0i.getPropertyType.getComponentType.equals{etWriteMethod.invokepb0,new Object{childname};}}}else{ifpd0i.getName.equals"name";{pd0i.getWriteMethod.invokepb0,name;}}}String array=;for int i = 0; i < ; i++ {}}}更难的应用请参考三、关于内省的分析struts2的action还有struts1的formbean就是这么实现的;前台的form标签具有一些属性在配置文件中知道这个form提交到那个action,而这个action有和这个form相对应的属性及其get/set,提交以后,由struts的servlet拦下来转发给某个具体的action.而在转发给action之前struts通过内省的方式将form中的值set到了action 中去;其实只要有个set或者get,内省就会理解为存在这样的属性,这样可以方便我们把Bean 类通过一个接口来定义而不用去关心具体实现,不用去关心Bean 中数据的存储;比如我们可以把所有的getter/setter 方法放到接口里定义,但是真正数据的存取则是在具体类中去实现,这样可提高系统的扩展性;四、总结将Java 的反射以及内省应用到程序设计中去可以大大的提供程序的智能化和可扩展性;有很多项目都是采取这两种技术来实现其核心功能,例如我们前面提到的Struts ,还有用于处理XML 文件的Digester 项目,其实应该说几乎所有的项目都或多或少的采用这两种技术;在实际应用过程中二者要相互结合方能发挥真正的智能化以及高度可扩展性;。
一、反射1.反射概念1)什么是反射:反射就是在运行状态把Java 类中的各种成分映射成相应的Java类,可以动态得获取所有的属性以及动态调用任意一个方法。
2)一段java代码在程序的运行期间会经历三个阶段:source-->class-->runtime3)Class对象:在java中用一个Class对象来表示一个java类的class阶段Class对象封装了一个java类定义的成员变量、成员方法、构造方法、包名、类名等。
2.反射怎么用1)获得java类的各个组成部分,首先需要获得代表java类的Class对象获得Class对象有以下三种方式:Class.forname(className) 用于做类加载Object.getClass() 用于获得对象的类型类名.class 用于获得指定的类型,传参用2)反射类的构造方法,获得实例Class clazz = 类名.class;Constuctor con = clazz.getConstructor(new Class[]{paramClazz1,paramClazz2,.....});con.newInstance(params....);3)反射类的成员方法Method m = clazz.getMethod(methodName,new Class[]{paramClazz1,paramClazz2,.....});m.invoke();4)反射类的属性Field field = clazz.getField(fieldName);field.setAccessible(true);//设置为可访问filed.setObject(value); //设置值Object value = field.get(clazz); //获得值Object staticValue = filed.get(Class); //获得静态值二、内省1.内省概念:通过反射的方式操作JavaBean的属性,jdk提供了PropertyDescription类来操作访问JavaBean的属性,Beantils工具基于此来实现。
JAVA的内省机制(introspector)与反射机制(reflection)2010-05-05 20:49相对而言,反射比内省更容易理解一点。
用一句比较白的话来概括,反射就是让你可以通过名称来得到对象 ( 类,属性,方法 ) 的技术,这种技术比内省机制使用范围更广泛。
例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值。
内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。
例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。
通过getName/setName 来访问 name 属性,这就是默认的规则。
Java 中提供了一套API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。
一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。
下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:Java代码1.package MyTest;2.public class bean {3.private String id = null ;4.private String name = null ;5.6.public String getId() {7.return id;8. }9.public void setId(String id) {10. this.id = id;11. }12.13. public String getName() {14. return name;15. }16. public void setName(String name) {17. = name;18. }19.}20.21.package MyTest;22.import java.beans.BeanInfo;23.import java.beans.EventSetDescriptor;24.import java.beans.Introspector;25.import java.beans.MethodDescriptor;26.import java.beans.PropertyDescriptor;27.import ng.reflect.Method;28.public class myBeanIntrospector {29.public myBeanIntrospector()30. {31. try32. {33. //实例化一个Bean34. bean beanObj = new bean();35. //依据Bean产生一个相关的BeanInfo类36. BeanInfo bInfoObject =37. Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());38. //定义一个用于显示的字符串39. String output = "";40.41. //开始自省42.43. /*44. * BeanInfo.getMethodDescriptors()45. * 用于获取该Bean中的所有允许公开的成员方法,以MethodDescriptor数组的形式返回46. *47. * MethodDescriptor类48. * 用于记载一个成员方法的所有信息49. * MethodDescriptor.getName()50. * 获得该方法的方法名字51. * MethodDescriptor.getMethod()52. * 获得该方法的方法对象(Method类)53. *54. * Method类55. * 记载一个具体的的方法的所有信息56. * Method.getParameterTypes()57. * 获得该方法所用到的所有参数,以Class数组的形式返回58. *59. * Class..getName()60. * 获得该类型的名字61. */62. output = "内省成员方法:\n";63. MethodDescriptor[] mDescArray =bInfoObject.getMethodDescriptors();64. for (int i=0;i<mDescArray.length ;i++ )65. {66. //获得一个成员方法描述器所代表的方法的名字67. String methodName = mDescArray[i].getName();68.69. String methodParams = new String();70. //获得该方法对象71. Method methodObj = mDescArray[i].getMethod();72. //通过方法对象获得该方法的所有参数,以Class数组的形式返回73. Class[] parameters = methodObj.getParameterTypes();74. if (parameters.length>0)75. {76. //获得参数的类型的名字77. methodParams = parameters[0].getName();78. for (int j=1;j<parameters.length ;j++ )79. {80. methodParams = methodParams + "," +parameters[j].getName();81. }82. }83. output += methodName + "(" + methodParams + ")\n";84. }85. System.out.println(output);86.87. /*88. * BeanInfo.getPropertyDescriptors()89. * 用于获取该Bean中的所有允许公开的成员属性,以PropertyDescriptor数组的形式返回90. *91. * PropertyDescriptor类92. * 用于描述一个成员属性93. *94. * PropertyDescriptor.getName()95. * 获得该属性的名字96. *97. * PropertyDescriptor.getPropertyType()98. * 获得该属性的数据类型,以Class的形式给出99. *100. */101. output = "内省成员属性:\n";102. PropertyDescriptor[] mPropertyArray =bInfoObject.getPropertyDescriptors();103.for (int i=0;i<mPropertyArray.length ;i++ ) 104. {105. String propertyName =mPropertyArray[i].getName();106. Class propertyType =mPropertyArray[i].getPropertyType();107. output += propertyName + " ( "+ propertyType.getName() + " )\n";108. }109. System.out.println(output);110.111.112./*113. * BeanInfo.getEventSetDescriptors()114. * 用于获取该Bean中的所有允许公开的成员事件,以EventSetDescriptor数组的形式返回115. *116. * EventSetDescriptor类117. * 用于描述一个成员事件118. *119. * EventSetDescriptor.getName()120. * 获得该事件的名字121. *122. * EventSetDescriptor.getListenerType()123. * 获得该事件所依赖的事件监听器,以Class的形式给出124. *125. */126. output = "内省绑定事件:\n";127. EventSetDescriptor[] mEventArray =bInfoObject.getEventSetDescriptors();128.for (int i=0;i<mEventArray.length ;i++ )129. {130. String EventName = mEventArray[i].getName(); 131. Class listenerType =mEventArray[i].getListenerType();132. output += EventName + "(" + listenerType.getName() + ")\n";133. }134. System.out.println(output);135. System.out.println("write by esonghui :"); 136.137. }138.catch (Exception e)139. {140. System.out.println("异常:" + e);141. }142. }143.public static void main(String[] args) 144. {145.new myBeanIntrospector();146. }147.}。
Java各个版本特性Java 作为⼀门经久不衰的语⾔,已经发展了20多年,本⽂简单罗列了各个版本的⼀些重要特性。
⼤家可以根据⾃⼰公司需要,选择合适的版本。
1. Java 13发布时间:2019年3⽉新特性:switch 语法优化更新⽂本块升级动态CDS档案取消使⽤未使⽤的内存重新实现旧版套接字APIFileSystems.newFileSystem新⽅法nio新⽅法核⼼库/ java.time核⼼库/ java.util中:I18N热点/ GC安全库/ java.security删除功能2. Java 12发布时间:2019年3⽉新特性:Shenandoah:低暂停时间的 GC(实验性功能)JMH 基准测试Switch 表达式(预览功能)JVM 常量 API只保留⼀个 ARM 64位实现(aarch64)默认类数据共享归档⽂件G1的可中断 mixed GC改进G1垃圾收集器,以便在不活动时将Java堆内存归还给操作系统3. Java 11Java 11 是⾃ Java 8 后的⾸个长期⽀持版本,将⽀持到2026年!发布时间:2018年9⽉新特性:基于嵌套的访问控制动态的类⽂件常量改进 Aarch64 IntrinsicsEpsilon 垃圾回收器,⼜被称为"No-Op(⽆操作)"回收器移除 Java EE 和 CORBA 模块,JavaFX 也已被移除HTTP Client (Standard)⽤于 Lambda 参数的局部变量语法采⽤ Curve25519 和 Curve448 算法实现的密钥协议Unicode 10实现 ChaCha20 和 Poly1305 加密算法启动单个 Java 源代码⽂件的程序低开销的堆分配采样⽅法对 TLS 1.3 的⽀持ZGC:可伸缩的低延迟垃圾回收器,处于实验性阶段弃⽤ Nashorn JavaScript 引擎弃⽤ Pack200 ⼯具及其 API4. Java 10发布时间:2018年3⽉新特性:var 类型推断将原来⽤ Mercurial 管理的众多 JDK 仓库代码,合并到⼀个仓库中,简化开发和管理过程。
Java内省机制和BeanUtils实现内省(Introspector) Java 语⾔对 Bean 类属性、事件的⼀种缺省处理⽅法。
例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。
通过 getName/setName 来访问 name 属性,这就是默认的规则。
Java 中提供了⼀套 API ⽤来访问某个属性的 getter/setter ⽅法,这些 API 存放于包 java.beans 中。
⼀般的做法 通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor )。
接着通过这个属性描述器就可以获取某个属性对应的 getter/setter ⽅法,最后我们可以使⽤反射机制来调⽤这些⽅法。
简单例⼦:public class IntrospectorDemo {String name;public String getName() {return name;}public void setName(String name) { = name;}public static void main(String[] args) throws Exception {IntrospectorDemo demo = new IntrospectorDemo();demo.setName("Winter Lau");// 如果不想把⽗类的属性也列出来的话,// 那 getBeanInfo 的第⼆个参数填写⽗类的信息BeanInfo bi = Introspector.getBeanInfo(demo.getClass(), Object.class);PropertyDescriptor[] props = bi.getPropertyDescriptors();for (int i = 0; i < props.length; i++) {System.out.println(props[i].getName() + "="+ props[i].getReadMethod().invoke(demo, null));}}}其它使⽤场合:1、Struts中的FormBean 它通过内省机制来将表单中的数据映射到类的属性上,因此要求 FormBean 的每个属性要有 getter/setter ⽅法。
内省机制第134 讲马剑威1、JavaBean的概念2、内省基本概念3、Introspector 相关API1、JavaBean的概念•什么是JavaBean?理解为组件意思组件在广泛的理解就是一个类对于组•Bean理解为组件意思,JavaBean就是Java组件,在广泛的理解就是一个类,对于组件来说,关键在于要具有“能够被IDE构建工具侦测其属性和事件”的能力,通常在Java中。
1、JavaBean的概念•一个JavaBean要具备这样的命名规则:的属性通常你要写两个方法任何浏•1、对于一个名称为xxx的属性,通常你要写两个方法:getXxx()和setXxx()。
任何浏览这些方法的工具,都会把get或set后面的第一个字母自动转换为小写。
•2、对于布尔型属性,可以使用以上get和set的方式,不过也可以把get替换成is。
的普通方法不必遵循以上的命名规则不过它们必须是的•3、Bean的普通方法不必遵循以上的命名规则,不过它们必须是public的。
•4、对于事件,要使用Swing中处理监听器的方式。
如addWindowListener,removeWindowListener内省基本概念2、内省基本概念•内省(IntroSpector)是Java 语言对Bean 类属性、事件的一种缺省处理方法。
例如类A 中有属性name, 那我们可以通过getName,setName 来得到其值或者设置新的值。
name getName setName•通过getName/setName 来访问name 属性,这就是默认的规则。
2、内省基本概念内省基本概念•Java 中提供了一套API 用来访问某个属性的getter/setter 方法,通过这些API 可以使API java beans中,一般的做法是通过类你不需要了解这个规则,这些API 存放于包java.beans 中,般的做法是通过类Introspector 的getBeanInfo方法来获取某个对象的BeanInfo 信息,然后通过BeanInfo 来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。
java解析中国⾏政区域并在页⾯显⽰实现动态逐级筛选⼀、实现⽬标⾸先会有⼀个存放中国⾏政区域数据的⼀个txt⽂件,⽤java读取并解析出来,并在页⾯上通过下拉框的形式展⽰出来。
实现效果如下图,当选择完省份后,在选择该省份下的城市,然后在选择该城市下的县区这样逐级显⽰:⼆、代码实现:1. 先创建⼀个javaBean,⽤来存放基本数据;1public class Area {2private String code ;//⾏政编码3private String name;//名称4private int level;//⾏政级别 0:省/直辖市 1:地级市 2:县级市5private String parentCode;//上⼀级的⾏政区划代码67public Area() {8super();9 }1011public Area(String code, String name, int level, String parentCode) {12super();13this.code = code; = name;15this.level = level;16this.parentCode = parentCode;17 }1819public String getCode() {20return code;21 }2223public void setCode(String code) {24this.code = code;25 }2627public String getName() {28return name;29 }3031public void setName(String name) { = name;33 }3435public int getLevel() {36return level;37 }3839public void setLevel(int level) {40this.level = level;41 }4243public String getParentCode() {44return parentCode;45 }4647public void setParentCode(String parentCode) {48this.parentCode = parentCode;49 }5051public String toString(){52return "⾏政编码:"+this.getCode()+"\t名称:"+this.getName()+"\t⾏政级别:"+53this.getLevel()+"\t上⼀级的⾏政区划代码:" +this.getParentCode();54 }55 }2. 然后创建⼀个读取txt资源⽂件的⼯具类;1import java.io.BufferedReader;2import java.io.File;3import java.io.FileNotFoundException;4import java.io.FileReader;5import java.io.IOException;6import java.util.ArrayList;7import java.util.HashMap;8import java.util.List;9import java.util.Map;1011import com.***.Area;1213public class ReadAreaUtil {1415public List<Area> provinceList = new ArrayList<Area>();16public List<Area> townList = new ArrayList<Area>();17public List<Area> countyList = new ArrayList<Area>();1819public Map<String,List<Area>> getAreaData(String path){20 ReadAllArea(path);21 Map<String,List<Area>> result = new HashMap<String,List<Area>>();22 result.put("provinceList", provinceList);23 result.put("townList", townList);24 result.put("countyList", countyList.subList(1, countyList.size())); //去掉表头2526return result ;27 }2829public void ReadAllArea(String path){30 String line = null;31 BufferedReader reader = null;32 File file = new File(path);3334 String cityCode="";35 String countyCode="";36try {37 FileReader in = new FileReader(file);38 reader = new BufferedReader(in);39//读取⽂件的每⼀⾏40while((line = reader.readLine())!=null){41 String[] data = cutString(line);4243//处理读取的⽂件记录44if(isProvince(data[0])){45 cityCode = data[0];46 Area area = new Area(data[0], data[1], 0, "0");47 provinceList.add(area);48 }else if(isTown(data[0])){49 countyCode =data[0];50 Area area = new Area(data[0], data[1], 1, cityCode);51 townList.add(area);52 }else{53 Area area = new Area(data[0], data[1], 2, countyCode);54 countyList.add(area);55 }56 }57 } catch (FileNotFoundException e) {58 e.printStackTrace();59 } catch (IOException e) {60 e.printStackTrace();61 }finally{62try {63 reader.close();64 } catch (IOException e) {65 e.printStackTrace();66 }67 }68 }6970//字符分割71public String[] cutString(String line){72 String code="";73 String name="";74 code = line.substring(0, 6);75 String lastStr = line.substring(7, line.length());76 name = lastStr.substring(0, lastStr.indexOf("\t"));77 String[] result = new String []{code,name};78return result;79 }8081//判断是否省或者直辖市82public boolean isProvince(String code){83 String last = code.substring(2);84if("0000".equalsIgnoreCase(last)){85return true;86 }87return false;88 }89//判断是否地级市90public boolean isTown(String code){91 String last = code.substring(4);92if("00".equalsIgnoreCase(last)){93return true;94 }95return false;96 }9798 }3. 改项⽬使⽤了struts2,在action的⽅法中调⽤即可:1//读txt数据...2 String path = ServletActionContext.getServletContext().getRealPath("/2015Area.txt");3 Map<String,List<Area>> area = new ReadAreaUtil().getAreaData(path);4 List<Area> provinceList = area.get("provinceList");5 ServletActionContext.getRequest().setAttribute("prlist", provinceList);4. JSP页⾯上的html,第⼀个select是直接遍历的,但是后⾯两个就要根据前⾯select选中的来动态显⽰了,这⾥需要⽤到jQuery的Ajax; 1<div id="areaDiv">2<a >省份:3<select id="sel_province" name="">4<option value="-1">-请选择-</option>5<c:forEach var="pro" items="${prlist }">6<option value="${pro.code }">${ }</option>7</c:forEach>8</select>9</a> 10<a class="wsy_f14">城市/区:11<select id="sel_town" name="">12<option value="-1">-----</option>13</select>14</a> 15<a class="wsy_f14">县级:16<select id="sel_county" name="">17<option value="-1">-----</option>18</select>19</a>20</div>jQuery 代码,select标签变化时触发函数并发送post请求数据;1 $(document).ready(function(){2 $('#sel_province').change(function(){3 var code = $(this).children('option:selected').val();//selected的值4 $.post("${basePath}ajax/filterArea.action",5 {6 parentCode:code,7 areaType:1//0省,1市,2县8 },9 function(data){10 $("#sel_town").html(data);11 });12 });1314 $('#sel_town').change(function(){15 var code = $(this).children('option:selected').val();//selected的值16 $.post("${basePath}ajax/filterArea.action",17 {18 parentCode:code,19 areaType:2//0省,1市,2县20 },21 function(data){22 $("#sel_county").html(data);23 });24 });25 });5. struts如何处理Ajax请求,专门写⼀个action⽤于处理ajax请求;strut.xml:1<?xml version="1.0" encoding="UTF-8" ?>2<!DOCTYPE struts PUBLIC3 "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"4 "/dtds/struts-2.1.dtd">5<struts>6<package name="ajax" namespace="/ajax" extends="json-default">7<action name="filterArea" method="filterArea" class="com.llw.action.AjaxFilter"></action>8</package>9</struts>action:1public class AjaxFilter extends ActionSupport {23//⾏政区域过滤4private String parentCode ;5private int areaType ;6public String getParentCode() {7return parentCode;8 }9public void setParentCode(String parentCode) {10this.parentCode = parentCode;11 }12public int getAreaType() {13return areaType;14 }15public void setAreaType(int areaType) {16this.areaType = areaType;17 }1819public void filterArea(){20 String htmlStr = "<option value=\"-1\">-请选择-</option>" ;2122 String path = ServletActionContext.getServletContext().getRealPath("/2015Area.txt");23 Map<String,List<Area>> area = new ReadAreaUtil().getAreaData(path);24 List<Area> areaList = null ;25if(areaType==1){ //0省,1市,2县26 areaList = area.get("townList");27 }else if(areaType==2){28 areaList = area.get("countyList");29 }30if(areaList!=null && areaList.size()>0 && parentCode!=null){31for(Area a : areaList){32if(parentCode.equals(a.getParentCode())){33 htmlStr += "<option value=\""+a.getCode()+"\">"+a.getName()+"</option>" ;34 }35 }36 }3738// System.out.println("xxxxx"+htmlStr);39 HttpServletResponse response = ServletActionContext.getResponse();40 PrintWriter writer = null;41try {42 writer = response.getWriter();43 } catch (IOException e) {44 e.printStackTrace();45 }46 writer.print(htmlStr);47 writer.flush();48 writer.close();49 }5051 }三、总结:以上基本完成了需要的效果,⽤java读取txt资源⽂件,并封装到List⾥⾯,上⾯代码中把不同级别的数据放到不同的list⾥了,也可以放到同⼀个list⾥⾯,这个根据⾃⼰需要可以去修改;然后是通过Ajax⽅式动态逐级显⽰select展⽰的内容;并演⽰了strut中如何处理ajax请求。
内省(Introspector)
1.为什么要学内省?
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。
2.什么是Java对象的属性和属性的读写方法?
内省访问JavaBean属性的两种方式:
通过PropertyDescriptor类操作Bean的属性
通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo 来获取属性的描述器(PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的getter/setter 方法,然后通过反射机制来调用这些方法。
3.内省—beanutils工具包
Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz)
自定义转换器
public void test() throws Exception{
Student stu=new Student();
BeanInfo entity=Introspector.getBeanInfo(Student.class);
PropertyDescriptor pds[]= entity.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println(pd.getName());
System.out.println(pd.getShortDescription());
System.out.println(pd.getDisplayName());
if(pd.equals("age")){
Method md=pd.getWriteMethod();
md.invoke(stu, 122);
}
}
System.out.println(stu.getAge());
}
通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器(PropertyDescriptor )通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,
然后通过反射机制来调用这些方法。
@Test
public void test() throws Exception {
Student st = new Student();
// 1、通过Introspector类获得Bean对象的 BeanInfo,
BeanInfo entity = Introspector.getBeanInfo(Student.class);
// 2、然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor )
PropertyDescriptor pdrs[] = entity.getPropertyDescriptors();
// 3、通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,
for (PropertyDescriptor pd : pdrs) {
System.out.println(pd.getName());
System.out.println(pd.getShortDescription());
System.out.println(pd.getDisplayName());
if (pd.getName().equals("age")) { //age是什么类型?
Method md = pd.getWriteMethod();
md.invoke(st, 12);
}
//获取属性的类型
System.out.println(pd.getName()+""+pd.getPropertyType());
}
System.out.println(st.getAge());
}
//简便的方法
@Test
public void test1()throws Exception{
Student st = new Student();
//通过构造器创建 PropertyDescriptor对象
PropertyDescriptor pd = new PropertyDescriptor("age",
Student.class);
Method md = pd.getWriteMethod(); //写操作
md.invoke(st, 120);
System.out.println(st.getAge());
md = pd.getReadMethod();
int value = (Integer)md.invoke(st, null); //读操作
System.out.println(value);
}
4、实例
public class Demo01 {
@Test
public void test1()throws Exception{
Class cls = Class.forName("cn.csdn.beanutils.Student");
Student bean = (Student)cls.newInstance();
BeanUtils.setProperty(bean, "name", "haiyan");
String name=BeanUtils.getProperty(bean, "name");
System.out.println(name);
System.out.println(bean.getName());
}
@Test
public void test2()throws Exception{
String str="cn.csdn.beanutils.Student";
String age="age";
Class cls = Class.forName(str);
Student bean = (Student)cls.newInstance();
BeanUtils.setProperty(bean, age, "100");
String a=BeanUtils.getProperty(bean, age);
System.out.println(a);
System.out.println(bean.getAge());
}
@Test
public void test3() throws Exception {
Student bean = new Student();
BeanUtils.setProperty(bean, "brithday", new Date());
System.out.println(bean.getBrithday());
}
@Test
public void test4() throws Exception{
Student bean=new Student();
ConvertUtils.register(new DateLocaleConverter(),
Date.class);
BeanUtils.setProperty(bean, "brithday", "2011-02-28");
System.out.println(bean.getBrithday());
}
@Test
public void test5() throws Exception{
Student bean=new Student();
ConvertUtils.register(new Converter() {
@Override
public Object convert(Class type, Object value) { if(value==null){
return null;
}
SimpleDateFormat sdf=new
SimpleDateFormat("yyyy-MM-dd");
Date dt=null;
try {
dt=sdf.parse((String)value);
} catch (ParseException e) {
throw new ConversionException("日期格式转换有问
题....");
}
return dt;
}
}, Date.class);
BeanUtils.setProperty(bean, "brithday", "2011-02-28");
System.out.println(bean.getBrithday());
}。