1

我的 JAXB 解析器今天突然停止工作。它工作了几个星期。我收到以下消息。我已经好几个星期没有更改此代码了。想知道这个设置好不好。


编辑2:请有人帮助我!我想不通。



编辑 1:我运行下面相同代码的验收测试工作正常。我相信这是一个类加载问题。我在 JDK 中使用 JAXB 和 StAX。但是,当我部署到 jboss 5.1 时,出现以下错误。使用 1.6.0_26(本地)和 1.6.0_30(开发服务器)。仍然对解决方案感到困惑。


意外元素(uri:“”,本地:“lineEquipmentRecord”)。预期元素为 <{}switchType>、<{}leSwitchId>、<{}nodeAddress>、<{}leId>、<{}telephoneSuffix>、<{}leFormatCode>、<{}groupIdentifier>、<{}telephoneNpa> ,<{}telephoneLine>,<{}telephoneNxx>

这是我的解组类:

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;


public class PartialUnmarshaller<T> {
    XMLStreamReader reader;
    Class<T> clazz;
    Unmarshaller unmarshaller;

    public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
        this.clazz = clazz;
        this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
        unmarshaller.setEventHandler(new ValidationEventHandler() {

            @Override
            public boolean handleEvent(ValidationEvent event) {
                System.out.println(event.getMessage());
                return true;
            }
        });
        this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);

        /* ignore headers */
        skipElements(XMLStreamConstants.START_DOCUMENT);
        /* ignore root element */
        reader.nextTag();
        /* if there's no tag, ignore root element's end */
        skipElements(XMLStreamConstants.END_ELEMENT);
    }

    public T next() throws XMLStreamException, JAXBException {
        if (!hasNext())
            throw new NoSuchElementException();

        T value = unmarshaller.unmarshal(reader, clazz).getValue();

        skipElements(XMLStreamConstants.CHARACTERS, XMLStreamConstants.END_ELEMENT);
        return value;
    }

    public boolean hasNext() throws XMLStreamException {
        return reader.hasNext();
    }

    public void close() throws XMLStreamException {
        reader.close();
    }

    private void skipElements(Integer... elements) throws XMLStreamException {
        int eventType = reader.getEventType();

        List<Integer> types = new ArrayList<Integer>(Arrays.asList(elements));
        while (types.contains(eventType))
            eventType = reader.next();
    }
}

此类使用如下:

List<MyClass> lenList = new ArrayList<MyClass>();
PartialUnmarshaller<MyClass> pu = new PartialUnmarshaller<MyClass>(
        is, MyClass.class);
while (pu.hasNext()) {
    lenList.add(pu.next());
}

被解组的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<lineEquipment>
    <lineEquipmentRecord>
        <telephoneNpa>333</telephoneNpa>
        <telephoneNxx>333</telephoneNxx>
        <telephoneLine>4444</telephoneLine>
        <telephoneSuffix>1</telephoneSuffix>
        <nodeAddress>xxxx</nodeAddress>
        <groupIdentifier>LEN</groupIdentifier>
    </lineEquipmentRecord>
    <lineEquipmentRecord>
        <telephoneNpa>111</telephoneNpa>
        <telephoneNxx>111</telephoneNxx>
        <telephoneLine>2222</telephoneLine>
        <telephoneSuffix>0</telephoneSuffix>
        <nodeAddress>xxxx</nodeAddress>
        <groupIdentifier>LEN</groupIdentifier>
    </lineEquipmentRecord>
</lineEquipment>

最后,这是 MyClass:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * This class is used as an envelope to hold Martens
 * line equipment information.
 * @author spgezf
 *
 */
@XmlRootElement(name="lineEquipmentRecord")
public class MyClass {

    private String telephoneNpa;
    private String telephoneNxx;
    private String telephoneLine;

    private String telephoneSuffix;
    private String nodeAddress;
    private String groupIdentifier;

    public MyClass(){       
    }


    // Getters and Setters.

    @XmlElement(name="telephoneNpa")
    public String getTelephoneNpa() {
        return telephoneNpa;
    }

    public void setTelephoneNpa(String telephoneNpa) {
        this.telephoneNpa = telephoneNpa;
    }
    @XmlElement(name="telephoneNxx")
    public String getTelephoneNxx() {
        return telephoneNxx;
    }

    public void setTelephoneNxx(String telephoneNxx) {
        this.telephoneNxx = telephoneNxx;
    }
    @XmlElement(name="telephoneLine")
    public String getTelephoneLine() {
        return telephoneLine;
    }

    public void setTelephoneLine(String telephoneLine) {
        this.telephoneLine = telephoneLine;
    }


    @XmlElement(name="telephoneSuffix")
    public String getTelephoneSuffix() {
        return telephoneSuffix;
    }

    public void setTelephoneSuffix(String telephoneSuffix) {
        this.telephoneSuffix = telephoneSuffix;
    }

    @XmlElement(name="nodeAddress")
    public String getNodeAddress() {
        return nodeAddress;
    }

    public void setNodeAddress(String nodeAddress) {
        this.nodeAddress = nodeAddress;
    }

    @XmlElement(name="groupIdentifier")
    public String getGroupIdentifier() {
        return groupIdentifier;
    }

    public void setGroupIdentifier(String groupIdentifier) {
        this.groupIdentifier = groupIdentifier;
    }


}
4

2 回答 2

1

谢谢,这是我无法克服的类加载问题,所以我放弃了 JAXB。

于 2013-01-10T22:02:41.327 回答
0

你的PartialUnmarshaller代码对我有用。下面是一个替代版本,它改变了skipElements可能更好的方法。

import java.io.InputStream;
import java.util.NoSuchElementException;

import javax.xml.bind.*;
import javax.xml.stream.*;

public class PartialUnmarshaller<T> {
    XMLStreamReader reader;
    Class<T> clazz;
    Unmarshaller unmarshaller;

    public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
        this.clazz = clazz;
        this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
        unmarshaller.setEventHandler(new ValidationEventHandler() {

            @Override
            public boolean handleEvent(ValidationEvent event) {
                System.out.println(event.getMessage());
                return true;
            }
        });
        this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);

        /* ignore headers */
        skipElements();
        /* ignore root element */
        reader.nextTag();
        /* if there's no tag, ignore root element's end */
        skipElements();
    }

    public T next() throws XMLStreamException, JAXBException {
        if (!hasNext())
            throw new NoSuchElementException();

        T value = unmarshaller.unmarshal(reader, clazz).getValue();

        skipElements();
        return value;
    }

    public boolean hasNext() throws XMLStreamException {
        return reader.hasNext();
    }

    public void close() throws XMLStreamException {
        reader.close();
    }

    private void skipElements() throws XMLStreamException {
        while(reader.hasNext() && !reader.isStartElement()) {
            reader.next();
        }
    }

}
于 2012-12-19T11:27:23.067 回答