JAXB将嵌套元素反序列化为null。

9

XML片段:

<datasource formatted-name="blah" inline="blah">
    <repository-location derived-from="blah" id="blah" path="blah" revision="blah" site="blah"/>
</datasource>

我正在尝试将所有内容解组到一个类(DataSource)中,其中包含嵌套的静态类。以下是我的DataSource类:

@XmlRootElement(name = "datasource")
@XmlAccessorType(XmlAccessType.FIELD)
public class DataSource {

    @XmlAttribute(name = "formatted-name")
    protected String formattedName;
    @XmlAttribute(name = "inline")
    protected String inline;
    @XmlElement(name = "repository-location")
    protected RepositoryLocation repositoryLocation;

    // public getters and setters for fields above

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class RepositoryLocation {

        @XmlAttribute(name = "derived-from")
        protected String derivedFrom;
        @XmlAttribute(name = "id")
        protected String id;
        @XmlAttribute(name = "path")
        protected String path;
        @XmlAttribute(name = "revision")
        protected String revision;
        @XmlAttribute(name = "site")
        protected String site;

        // public getters and setters for fields above
    }
}

Unmarshaller:

JAXBContext jaxbContext = JAXBContext.newInstance(DataSource.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(responseXML);
dataSourceResponse = (DataSource) unmarshaller.unmarshal(reader);

我能成功输出数据源字段“formattedName”和“inline”,但“repositoryLocation”为空。有人可以帮忙吗?


它应该可以工作。你有repositoryLocation的getter/setter吗? - ulab
是的,我有它们。 - toadead
你如何进行反序列化操作?请附上代码。 - ulab
3个回答

4
JAXB能够在没有Getter/Setter的情况下进行解组,甚至可以使用私有字段。考虑到上面的DataSource类,在DataSourceRepositoryLocation中添加一些生成的toString方法,以下内容将打印出所有属性:
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import java.io.StringReader;

public class Jaxb {

    public static void main(String[] args) throws JAXBException {
        String xml = "<datasource formatted-name=\"blah\" inline=\"blah\">\n" +
                "    <repository-location derived-from=\"blah\" id=\"blah\"" +
                " path=\"blah\" revision=\"blah\" site=\"blah\"/>\n" +
                "</datasource>";

        JAXBContext context = JAXBContext.newInstance(DataSource.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        DataSource dataSource = (DataSource) unmarshaller.unmarshal(new StringReader(xml));
        System.out.println(dataSource);
    }

    @XmlRootElement(name = "datasource")
    @XmlAccessorType(XmlAccessType.FIELD)
    private class DataSource {

        @XmlAttribute(name = "formatted-name")
        private String formattedName;
        @XmlAttribute(name = "inline")
        private String inline;
        @XmlElement(name = "repository-location")
        private RepositoryLocation repositoryLocation;

        @XmlAccessorType(XmlAccessType.FIELD)
        private class RepositoryLocation {

            @XmlAttribute(name = "derived-from")
            private String derivedFrom;
            @XmlAttribute(name = "id")
            private String id;
            @XmlAttribute(name = "path")
            private String path;
            @XmlAttribute(name = "revision")
            private String revision;
            @XmlAttribute(name = "site")
            private String site;

            @Override
            public String toString() {
                return "RepositoryLocation{" +
                        "derivedFrom='" + derivedFrom + '\'' +
                        ", id='" + id + '\'' +
                        ", path='" + path + '\'' +
                        ", revision='" + revision + '\'' +
                        ", site='" + site + '\'' +
                        '}';
            }
        }

        @Override
        public String toString() {
            return "DataSource{" +
                    "formattedName='" + formattedName + '\'' +
                    ", inline='" + inline + '\'' +
                    ", repositoryLocation=" + repositoryLocation +
                    '}';
        }
    }
}

这是我得到的:DataSource{formattedName='个人BI Mart(副本)',inline='true',version='9.2',xmlBase='null',xmlnsUser='null',repositoryLocation=null} - toadead
这种方法可行,但需要在内部类名称定义中添加 static。谢谢! - Roberto

2

问题解决了!我发现我的Java 1.7库缺少一些jar文件。所以我决定升级到1.8版本。它像魔法一样奏效了!


2

我也尝试过使用Java 1.7,它可以正常工作。在xml.txt文件中,XML已经被保存了。

package testSingleJar.specificpackage;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args ) throws Exception
    {
        JAXBContext jaxbContext = JAXBContext.newInstance(DataSource.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        String responseXML =  "";
        //filename is filepath string
        BufferedReader br = new BufferedReader(new FileReader(new File("D:\\xml.txt")));
        String line;
        StringBuilder sb = new StringBuilder();

        while((line=br.readLine())!= null){
            sb.append(line.trim());
        }

        responseXML=sb.toString();
        StringReader reader = new StringReader(responseXML);
        DataSource dataSourceResponse = (DataSource) unmarshaller.unmarshal(reader);
        System.out.println(dataSourceResponse.getRepositoryLocation().getDerivedFrom());
    }
}


@XmlRootElement(name = "datasource")
@XmlAccessorType(XmlAccessType.FIELD)
class DataSource {

    @XmlAttribute(name = "formatted-name")
    protected String formattedName;
    @XmlAttribute(name = "inline")
    protected String inline;
    @XmlElement(name = "repository-location")
    protected RepositoryLocation repositoryLocation;

    // public getters and setters for fields above

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class RepositoryLocation {

        @XmlAttribute(name = "derived-from")
        protected String derivedFrom;
        @XmlAttribute(name = "id")
        protected String id;
        @XmlAttribute(name = "path")
        protected String path;
        @XmlAttribute(name = "revision")
        protected String revision;
        @XmlAttribute(name = "site")
        protected String site;
        public String getDerivedFrom() {
            return derivedFrom;
        }
        public void setDerivedFrom(String derivedFrom) {
            this.derivedFrom = derivedFrom;
        }
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getPath() {
            return path;
        }
        public void setPath(String path) {
            this.path = path;
        }
        public String getRevision() {
            return revision;
        }
        public void setRevision(String revision) {
            this.revision = revision;
        }
        public String getSite() {
            return site;
        }
        public void setSite(String site) {
            this.site = site;
        }

    }

    public String getFormattedName() {
        return formattedName;
    }

    public void setFormattedName(String formattedName) {
        this.formattedName = formattedName;
    }

    public String getInline() {
        return inline;
    }

    public void setInline(String inline) {
        this.inline = inline;
    }

    public RepositoryLocation getRepositoryLocation() {
        return repositoryLocation;
    }

    public void setRepositoryLocation(RepositoryLocation repositoryLocation) {
        this.repositoryLocation = repositoryLocation;
    }
}

输出: 呃啊


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接