关于XML文档pull解析的新思考-内省的应用

简介:

今天,复习黑马第6天学习的pull解析XML文档,结合第10天讲的JavaBean,突然了有了新的思考。


以下是我创建的XML文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<? xml  version = "1.0"  encoding = "UTF-8" ?>
<!-- 定义一个演示文档,存储黑马的所有班级,以及每个班级的信息
利用XML的功能之一:XML用来表示生活中有关系的数据
  -->
  < itheima >
    < class >
        < name >Anroid70期</ name >
        < teacher >于俏</ teacher >
        < time >2015年6月21日</ time >
        < count >77</ count >
    </ class >
    < class >
        < name >JavaEE70期</ name >
        < teacher >张子艺</ teacher >
        < time >2015年7月2日</ time >
        < count >83</ count >
    </ class >
  </ itheima >

下面是XML解析的Java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//pull解析xml文档开始。。。。。
         
try  {
//第1步:导入pull解析的包,得到pull解析工厂对象
     XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                     
//第2步:通过pull解析工厂得到pull解析器
     XmlPullParser parser = factory.newPullParser();
                     
//将XML文档的输入流引入pull解析器
     InputStream in =  new  FileInputStream( "D:\\HeiMa Dairy\\Other\\MyWorkSpace\\JDBCPractice\\WebRoot\\xml\\itheima.xml" );
//指定解析器的输入流和编码集
     parser.setInput(in,  "utf-8" );
//第4步:开始解析
     //创建一个List集合,用来存储javabean,javabean会封装班级信息。
         List<HeiMaClass> hmClassList =  null ;
         HeiMaClass hmClass =  null ;
         int  type =  0 ;     //标记解析的位置
         while ((type = parser.getEventType())!= XmlPullParser.END_DOCUMENT)    //到了XML的文档末尾就结束解析
         {
     //得到标签名,以作相应的判断 。
         String tagName = parser.getName();
                         
     //用switch来判断解析的具体位置,比对标签名,采取相应的操作。
         switch (type)
         {
            case  XmlPullParser.START_TAG:     //开始标签
             if ( "itheima" .equals(tagName))
             {
             //创建封装班级javabean的集合对象
                 hmClassList =  new  ArrayList<HeiMaClass>();
             }
             else  if ( "class" .equals(tagName))
             {
             //创建班级javabean,以封装数据
                 hmClass =  new  HeiMaClass();
             }
             else 
             {  
                                 //得到标签内容,用来封装进javabean  hmClass中去。
                         String tagText = parser.nextText();
                                             
                     //利用内省,直接用标签文本,也即Javabean的属性来获取对应
                     //写入方法来赋值。
                     try  {
         //内省重要代码************    //构造一个PropertyDescriptor对象
                               PropertyDescriptor pd =  new  PropertyDescriptor
                                     (tagName,hmClass.getClass());
         //内省重要代码************      //得到属性的写入方法
                                 Method writeMethod = pd.getWriteMethod();
                                 try  {
         //内省重要代码************            writeMethod.invoke(hmClass, tagText);
                                  catch  (Exception e) {
                                 e.printStackTrace();
                                 
                     catch  (IntrospectionException e) {
                         e.printStackTrace();
                     }
                   }
               break ;
             case  XmlPullParser.END_TAG:         //结束标签
             if ( "class" .equals(tagName))
             {
                 //将班级对象封装进List集合
                 hmClassList.add(hmClass);
             }
             break ;
             }
             parser.next();
         }
         //先在控制台上将List集合打印查看一下
         for (HeiMaClass cla : hmClassList)
         {
             System.out.println(cla.toString());
         }
                     
         //将List集合写到Session域中,供请求页面获取输出
         request.getSession().setAttribute( "hmClassList2" , hmClassList);
                     
         //转发到请求页面
         request.getRequestDispatcher( "/pra/jdbc.jsp" ).forward(request, response);
     catch  (XmlPullParserException e) {
         e.printStackTrace();
     }

在设计代码的时候,我采用的是javabean封装数据,XML文档中class这个标签对应的javabean代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//黑马班级类,用来演示pull解析XML,将XML中的班级数据封装到黑马班级类中。
public  class  HeiMaClass {
     private  String name,teacher,time,count;
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  String getTeacher() {
         return  teacher;
     }
 
     public  void  setTeacher(String teacher) {
         this .teacher = teacher;
     }
 
     public  String getTime() {
         return  time;
     }
 
     public  void  setTime(String time) {
         this .time = time;
     }
 
     public  String getCount() {
         return  count;
     }
 
     public  void  setCount(String count) {
         this .count = count;
     }
     
     public  String toString()
     {
         return  this .name +  ":"  this .teacher +  ":"  this .time +  ":"  this .count;
     }
}

在用else if语句判断对应javabean中的属性标签名时,我发现继续都是用属性名对应的方法来封装数据。那么,有没有可能通过javabean的属性名称(即对应xml文档的标签名称),得到这个属性的set方法呢?

后来我看了一下张孝祥老师的高新技术最后几个视频,发现这个正是内省技术,于是众多的else if语句通过javabean就很轻松的完成了。内省的简单操作是通过java.beans下的PropertyDescriptor类来实现的,构造这个类的对象需传递属性名称和字节码文件,然后通过getWriteMethod即可得到属性对应的写入方法,然后利用反射的原理即可封装数据至javabean中。

-------------------------------------------------------------------------------------------

以前看了反射和内省,当时还是朦朦胧胧,不知道它们到底有什么了不起的。现在我慢慢地发现这些技术如果明白了话,真的是非常实用的,真的像老师所说的,可以让我们少写很多的代码。


同理,pull序列化(将内存中的集合、对象)写到xml文档中去,可以使用反射和内省来减写很多的代码。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//从域中得到List集合,hmClassList2。
         List<HeiMaClass> hmClassList = (List<HeiMaClass>)request.getSession().getAttribute( "hmClassList2" );
         
         //准备进行集合的序列化
         
         try  {
             //第1步:得到解析器工厂
             XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
             
             //第2步:从解析器工厂得到序列化的接口
             XmlSerializer serializer = factory.newSerializer();
             
             //第3步:将文件输出流引入到序列化的接口
             OutputStream out =  new  FileOutputStream( "C:\\Users\\LENOVO\\Desktop\\serializer.xml" );
             serializer.setOutput(out,  "utf-8" );
             
             //第4步:正式开始序列化
             //1。生成文档声明和文档结束
             serializer.startDocument( null true );
             
             //2.生成根标签<itheima>
             serializer.startTag( null "itheima" );
             
             //3.遍历生成字标签
             for (HeiMaClass hmClass : hmClassList)
             {
                 //4.生成班级的开始和结束标签
                 serializer.startTag( null "class" );
                 //利用反射+内省技术,获取HeiMaClass这个javabean的所有属性,并获取它们的值写入xml文档。
                 Field[] fields = hmClass.getClass().getDeclaredFields();
                 //遍历字段
                 for (Field field : fields)
                 {
                     //获取字段的属性名
                     String propertyName = field.getName();
                     //得到属性描述器
                     try  {
                         PropertyDescriptor pd =  new  PropertyDescriptor(propertyName,hmClass.getClass());
                         //通过属性描述器得到字段对应的读取方法,获取得它的值并写入XML文档。
                         Method readMethod = pd.getReadMethod();
                         //调用方法获取属性值 
                         try  {
                             String propertyValue = (String)readMethod.invoke(hmClass);
                             //生成开始和结束标签,并插入标签文本。
                             serializer.startTag( null , propertyName);
                             serializer.text(propertyValue);
                             serializer.endTag( null , propertyName);
                         catch  (Exception e) {
                             e.printStackTrace();
                        
                     catch  (IntrospectionException e) {
                         e.printStackTrace();
                     }
                     
                 }
                 serializer.endTag( null "class" );
             }
             
             serializer.endTag( null "itheima" );
             
             serializer.endDocument();
             //序列化成功,返回一个提示信息到request域中去
             request.setAttribute( "tipXML" "XML文档创建成功,已保存到桌面。" );
         catch  (XmlPullParserException e) {
             //序列化失败,返回一个提示信息到request域中去,因为只想失败的一次请求提醒,所以不需要将提示写至session域中去。
             request.setAttribute( "tipXML" "XML文档创建失败!" );
             e.printStackTrace();
         } finally
         {
             //转发至请求页面
             request.getRequestDispatcher( "/pra/jdbc.jsp" ).forward(request, response);
         }


内省在WEB中的一个小小的应用,

    比如在Servlet里获取请求参数,可以利用内省根据属性名获取属性方法,将属性赋值给JavaBean.




      本文转自屠夫章哥  51CTO博客,原文链接:http://blog.51cto.com/4259297/1672205,如需转载请自行联系原作者





相关文章
|
24天前
|
XML 数据采集 API
用Lxml高效解析XML格式数据:以天气API为例
免费Python教程:实战解析中国天气网XML数据,详解Lxml库高效解析技巧、XPath用法、流式处理大文件及IP封禁应对策略,助你构建稳定数据采集系统。
130 0
|
7月前
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
318 3
|
8月前
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
1969 1
|
8月前
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
436 27
|
8月前
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
227 15
|
8月前
|
存储 弹性计算 安全
阿里云服务器ECS通用型规格族解析:实例规格、性能基准与场景化应用指南
作为ECS产品矩阵中的核心序列,通用型规格族以均衡的计算、内存、网络和存储性能著称,覆盖从基础应用到高性能计算的广泛场景。通用型规格族属于独享型云服务器,实例采用固定CPU调度模式,实例的每个CPU绑定到一个物理CPU超线程,实例间无CPU资源争抢,实例计算性能稳定且有严格的SLA保证,在性能上会更加稳定,高负载情况下也不会出现资源争夺现象。本文将深度解析阿里云ECS通用型规格族的技术架构、实例规格特性、最新价格政策及典型应用场景,为云计算选型提供参考。
|
8月前
|
数据采集 机器学习/深度学习 存储
可穿戴设备如何重塑医疗健康:技术解析与应用实战
可穿戴设备如何重塑医疗健康:技术解析与应用实战
295 4
|
8月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
6月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
136 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
248 1

推荐镜像

更多
  • DNS