`

java stax xml解析出现的一个死循环

    博客分类:
  • java
 
阅读更多

    public OfferInfo parseXml(String content) throws NumberFormatException, XMLStreamException {
        if (content == null || content.isEmpty()) {
            return null;
        }
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = null;
        try {
            reader = factory.createXMLStreamReader(new StringReader(content));
        } catch (XMLStreamException e1) {
            return null;
        }

        if (reader == null) {
            return null;
        }

        OfferInfo offerInfo = new OfferInfo();
        while (reader.hasNext()) {
            int event = 0;
            try {
                event = reader.nextTag();
            } catch (Exception e) {
            }
            switch (event) {
                case XMLStreamConstants.START_ELEMENT:
                    if (reader.getLocalName().equalsIgnoreCase(OFFER_ID)) {
                        offerInfo.setOfferId(Long.parseLong(reader.getElementText()));
                    } else if (reader.getLocalName().equalsIgnoreCase(MEMBER_ID)) {
                        offerInfo.setMemberId(reader.getElementText());
                    } else if (reader.getLocalName().equalsIgnoreCase(ACTION)) {
                        offerInfo.setAction(reader.getElementText());
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break;
            }
            //如果已经解析完需要的字段,则跳过剩余xml内容的解析,提高性能
            if(offerInfo.getOfferId() != null && offerInfo.getMemberId() != null && offerInfo.getAction() != null){
                return offerInfo;
            }
        }
        return offerInfo;

    }

 这段代码的

  try {
                event = reader.nextTag();
            } catch (Exception e) {
            }
 居然能搞出一个死循环,导致cpu跟load飙升,yonggc非常频繁

 

 

初步诊断如下:

stax在调用reader的nextTag方法时,因为格式不对,导致抛异常,本来我是只需要xml内容的三个字段,我认为如果是其他字段解析有问题,我直接忽略,所以我没打印日志,也没有跳出xml解析,而是直接解析,因为对nextTag可能不熟悉,我要的功能跟nextTag提供的不匹配,导致抛出异常之后,我又调用了该方法,然后因为nextTag抛出异常之后没有忽略当前有问题的xml内容,导致下次调用时又回到有问题的xml起始位置继续处理,重复抛出异常,这样就成为死循环了。

 

之前两个多月应用一直没问题,由于没有打印日志所以也扑捉不到当时xml的内容。

这里需要做两个教训:1.打印日志,2调用API时一定要了解API的详细处理过程,避免错误调用API导致问题;3.对于出错时event初始参数可以进行判断是否出错了,进行处理。

 

从jstack里面打印出来10几个这样的线程信息

"ActiveMQ Session Task" prio=10 tid=0x00000000451b3000 nid=0x7db7 runnable [0x00000000429ff000]
   java.lang.Thread.State: RUNNABLE
	at java.util.Arrays.copyOf(Arrays.java:2882)
	at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
	at java.lang.StringBuilder.append(StringBuilder.java:119)
	at javax.xml.stream.XMLStreamException.<init>(XMLStreamException.java:61)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:594)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1235)
	at com.alibaba.china.industry.brand.napoli.OfferNewReceiverWorker.parseXml(OfferNewReceiverWorker.java:195)
 "ActiveMQ Session Task" prio=10 tid=0x0000000046892000 nid=0x7baf runnable [0x0000000040a72000]
   java.lang.Thread.State: RUNNABLE
	at java.lang.StringBuffer.toString(StringBuffer.java:585)
	- locked <0x000000078890bc10> (a java.lang.StringBuffer)
	at java.text.MessageFormat.makeFormat(MessageFormat.java:1337)
	at java.text.MessageFormat.applyPattern(MessageFormat.java:458)
	at java.text.MessageFormat.<init>(MessageFormat.java:350)
	at java.text.MessageFormat.format(MessageFormat.java:811)
	at com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter.formatMessage(XMLMessageFormatter.java:85)
	at com.sun.xml.internal.stream.StaxErrorReporter.reportError(StaxErrorReporter.java:95)
	at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanCDATASection(XMLDocumentFragmentScannerImpl.java:1690)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2985)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:554)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1235)
 
0
0
分享到:
评论

相关推荐

    java Stax 解析xml

    为了演示如何使用StAX解析XML,我们先创建一个简单的XML文档`users.xml`: ```xml &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;user name="Tom" age="28" gender="male"&gt;Manager ...

    java心电图xml解析.zip

    Java XML解析是Java开发中的一项重要技能,尤其是在处理结构化数据时。XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于配置文件...同时,这也提供了一个学习和实践Java XML解析能力的好机会。

    java 解析xml 多级

    以下是一个使用Java DOM解析XML的步骤: 1. 引入必要的库: 需要引入`javax.xml.parsers`包,包含DOM解析器的主要类。 2. 创建解析器工厂: 使用`DocumentBuilderFactory`创建一个解析器工厂实例,然后通过`...

    stax+jaxb进行xml解析

    在Java中,有多种方法可以解析XML,其中StAX(Streaming API for XML)和JAXB(Java Architecture for XML Binding)是两种常用的技术。本篇文章将详细探讨如何结合StAX和JAXB进行高效的XML解析。 StAX是一种事件...

    有用的Java工具—XML解析工具StAx

    本篇文章将聚焦于Java中的一个高效XML解析工具——StAX(Streaming API for XML)。StAX是一种基于事件驱动的解析器,它允许程序员通过逐个处理XML事件(如开始元素、结束元素、文本等)来读取和写入XML文档,这种...

    java XML解析方式实现自动生成word文档

    以下是一个基本的步骤,展示如何使用Java和Apache POI通过XML解析生成Word文档: 1. 引入Apache POI库:在项目中添加Apache POI依赖,通常是通过Maven或Gradle的配置完成。 2. 创建Word文档对象:使用`...

    java 解析XML性能对比分析Demo

    DOM4J是另一个流行的Java XML处理库,提供了灵活的API,支持DOM、SAX和StAX解析方式。它具有强大的XPath支持,易于学习,适合复杂查询,但内存消耗介于DOM和SAX之间。 5. JAXB(Java Architecture for XML Binding...

    java大作业xml解析

    1. DOM解析:DOM将整个XML文档加载到内存中,创建一个树形结构,允许开发者通过遍历节点来访问和修改XML数据。这种方式适合小到中等规模的XML文件,因为它需要大量内存,但提供了方便的数据操作接口。 2. SAX解析:...

    java使用stax技术操作XML文档.doc

    StAX的核心理念是将XML视为一个事件流,允许应用程序主动拉取并处理这些事件,而不是被动等待解析器推送事件,就像SAX所做的那样。StAX提供了两个级别的API:基于指针的API和基于迭代器的API。 基于指针的API通过...

    kettle解析xml多层分组嵌套数据,StAX方法,完整解析案例(包含xml文件以及ktr文件)

    kettle 解析xml数据,xml多层分组嵌套,xml stax方法,完整解析案例使用(包含xml文件以及ktr文件)。ETL大数据迁移,数据清洗。XML Input Stream (StAX) 方法

    java xml 解析包

    DOM4J是Java社区的一个流行且功能强大的XML处理库,它提供了全面和灵活的API来处理XML。该库支持DOM、SAX和JDOM接口,同时提供了一些额外的功能,如XPath查询、事件驱动解析、StAX支持和XML Schema验证。 3. **DOM...

    用Stax组装及解析XML

    ### 使用StAX组装与解析XML #### 一、引言 在处理XML文档时,Java提供了多种工具和技术,包括DOM、SAX以及本文将重点讨论的Streaming API ...对于需要处理大量XML数据的应用程序而言,StAX无疑是一个非常实用的选择。

    java xml 4 种 解析xml 方法 sax jdom dom stAX

    JDOM提供了一个纯Java的XML对象模型,它将XML文档转换为树形结构,每个XML元素和属性都映射为Java对象。JDOM的优势在于它的API直观且易于使用,但缺点是对于大型XML文档,可能会占用较多的内存。使用JDOM,你可以...

    JAVA调用webservice并解析xml

    Java提供了DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for XML)等解析器来处理XML。DOM加载整个XML文档到内存,适合小型数据;SAX是事件驱动,只读且不需要全部加载;StAX允许...

    java解析xml的四种经典方法

    Java解析XML的四种经典方法是XML处理中常用的技术,它们分别是DOM、SAX、StAX和JDOM。每种方法都有其独特的特性和适用场景,下面将详细介绍这四种方法。 1. DOM(Document Object Model)解析: DOM是W3C制定的一种...

    java解析XML文件

    DOM解析器将整个XML文件加载到内存中,形成一个树形结构,即DOM树。这样可以方便地通过节点遍历、查找和修改XML文档。Java中的DOM解析主要依赖于`javax.xml.parsers.DocumentBuilderFactory`和`org.w3c.dom.Document...

    使用java解析XML文件,解析完之后将解析结果导入mysql数据库中

    - DOM解析:首先,通过`javax.xml.parsers.DocumentBuilderFactory`和`DocumentBuilder`创建一个`Document`对象,这代表了整个XML文件的根节点。然后,调用`parse()`方法读取XML文件并将其解析为`Document`对象。 ...

    stax 解析xml demo project

    STAX(Streaming API for XML)是Java平台上的一个XML处理技术,它提供了一种高效的、基于事件驱动的模型来解析和生成XML文档。STAX允许开发者以流式方式处理XML,使得处理大型XML文件时能有效地管理内存,避免一次...

    java解析xml例子

    DOM(Document Object Model)解析器是Java中的一种常用方法,它将整个XML文档加载到内存中,形成一个树形结构。以下是一个简单的DOM解析XML的例子: ```java import javax.xml.parsers.DocumentBuilderFactory; ...

Global site tag (gtag.js) - Google Analytics