java - 我得到空字段 Unmarshalling a xml with spring-oxm

标签 java xml spring jaxb gradle

我正在编写一个小型命令行工具来维护数据库。作为起点,我将问题减少到一张表。基本上我对它执行 CRUD 操作。输入是一个 xml 文件。我创建了一个 spring 应用程序,这是我第一次在 web 应用程序上下文之外使用它。对于构建,我使用的是 gradle 1.11。

我有一个测试类。其中一个测试非常简单:从类路径中读取一个测试 xml 文件并将其解码。这是 server.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<xs2:server xmlns:xs2="http://www.opsource.net/simpleapp">
    <xs2:id>5</xs2:id>
    <xs2:name>Server_5</xs2:name>
</xs2:server>

这是解码 xml 的方法:

@Autowired
private Unmarshaller unMarshaller;

public ServerType unMarshallServerType(InputStream is) throws XmlMappingException, IOException{
    ServerType server = (ServerType) unMarshaller.unmarshal(new StreamSource(is));
    return server;
}

在应用程序上下文中,我定义了我的 jaxb2Marshaller:

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <list>
            <value>com.mangrar.jaxb.ServerType</value>
        </list>
    </property>
</bean>

我已经检查过 InputStream 的内容是正确的,并且 Unmarshalling 没有抛出任何异常,但是 ServerType 实例中的 2 个属性为空。这是 ServerType 类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "serverType", propOrder = {
    "id",
    "name"
})
@XmlRootElement(namespace = "http://www.opsource.net/simpleapp", name = "server" )
public class ServerType {

    @XmlElement(required = true)
    protected String id;
    @XmlElement(required = true)
    protected String name;
}

最奇怪的是,如果我运行“gradle test”,测试会正常运行,但 IDE 却不行。我已经尝试使用最新版本的 IDEA 和 Eclipse,但仍然为空。我已经向 Jetbrains 创建了一个支持请求,但目前也没有使用 gradle。

知道它可能不起作用吗?

最佳答案

您只为根元素指定了 namespace 限定。有几种方法可以解决这个问题。

选项 #1 - 一切都在一个类中

您可以利用 @XmlElement 注释上的 namespace 属性以及 @XmlRootElement 注释上的属性。

ServerType.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "serverType", propOrder = {
    "id",
    "name"
})
@XmlRootElement(namespace = "http://www.opsource.net/simpleapp", name = "server" )
public class ServerType {

    @XmlElement(namespace = "http://www.opsource.net/simpleapp", required = true)
    protected String id;
    @XmlElement(namespace = "http://www.opsource.net/simpleapp", required = true)
    protected String name;
}

选项 #2 - 使用 @XmlSchema 指定命名空间限定条件

package-info.java

当您在包级 @XmlSchema 注释上指定 namespace 限定时。

@XmlSchema(
    namespace = ""http://www.opsource.net/simpleapp",
    elementFormDefault = XmlNsForm.QUALIFIED)
package example;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

ServerType.java

然后它将自动应用,您不必在 @XmlRootElement@XmlElement 上指定它。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "serverType", propOrder = {
    "id",
    "name"
})
@XmlRootElement(name = "server" )
public class ServerType {

    @XmlElement(required = true)
    protected String id;
    @XmlElement(required = true)
    protected String name;
}

了解更多信息

我在我的博客上写了更多关于 JAXB 和命名空间的文章:

关于java - 我得到空字段 Unmarshalling a xml with spring-oxm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24271518/

相关文章:

java - 出于安全目的,如何在某些节点上禁用 Hazelcast 分布式 IExecutorService?

java - 我可以为具有特定注释的类创建通用接口(interface)吗?

java - 无法在父项目中使用外部 jar 文件的 Autowiring 类

java - 通过java中的标签拆分XML字符串

swift - 无法将 xml 转换为对象 - Swift4

java - 执行命令在 Spring Roo 中不起作用

java - 使用 Spring Boot 运行脚本时出现 SQL 错误

java - Gradle Failiure:无法通过 '13.0.1'确定Java版本

java - JSR-310 年份映射到 MySQL 中的 TINYBLOB

javascript - IE9 拒绝处理 XML 响应