【问题标题】:XML binding with the use of JAXB and Spring-MVC使用 JAXB 和 Spring-MVC 进行 XML 绑定
【发布时间】:2012-05-10 10:08:59
【问题描述】:

以下 xml 位于服务器上的存储库中:

   <author xmlns="http://www..." xmlns:atom="http://www.w3.org/2005/atom">
     <name>S. Crocker</name>
     <address>None</address>
     <affiliation></affiliation>
     <email>None</email>
   </author>

我的模型课:

  @XmlRootElement(name = "author", namespace="http://www...")
  @XmlAccessorType(XmlAccessType.FIELD)
  public class Author {


    @XmlAttribute(name="author")
    private String author;
    @XmlElement(name="name")
private String name;
    @XmlElement(name="address")
private String address;
    @XmlElement(name="affiliation")
private String affiliation;
    @XmlElement(name="email")
    private String email;



    public String getAuthor() {
    return author;
}
public void setAuthor(String author) {
    this.author = author;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}
public String getAffiliation() {
    return affiliation;
}
public void setAffiliation(String affiliation) {
    this.affiliation = affiliation;
}
public String getEmail() {
    return email;
}
public void setEmail(String email) {
    this.email = email;
}

 }

根据我看到的教程,我应该将 @XmlSchema 用于 package-info.java 我创建了一个类 package-info.java 但我不知道如何处理。

实际上我的问题是我不知道如何使用正确的注释将xml与模型类绑定。整个故事是我试图从存储库中检索 XML 文档,但我采用空值。我在这里看到的问题:JAXB: How to bind element with namespace 是我没有使用正确的注释。有谁知道哪些是正确的注释以及我应该如何使用它们?

【问题讨论】:

  • 请任何可以帮助我的人!
  • 你是怎么调用webservice然后绑定结果的?也许也显示此代码?你也看过 Spring RestTemplate(这里的教程:informit.com/guides/content.aspx?g=java&seqNum=546)?
  • 您是否也尝试为所有 XmlElement 和 XmlAttribute 注释提供命名空间属性?只是为了尝试问题位于错误的命名空间匹配...

标签: java spring-mvc annotations jaxb xsd


【解决方案1】:

我从来不需要在@XmlRootElement 上使用namespace 参数,请尝试将其关闭;此外,您为author 指定了@XmlAttribute,但除了标签名称之外,您的示例中没有author

至于:

其实我的问题是我不知道如何使用 corect 将 xml 与模型类绑定的注释。

在你的 spring 配置中你可以这样做:

<oxm:jaxb2-marshaller id="jaxb2Marshaller">
    <oxm:class-to-be-bound name="com.mycompany.Author"/>
    <!-- ... -->
</oxm:jaxb2-marshaller>

然后直接注入jaxb2Marshaller 或像这样使用MessageConverter

<bean id="xmlConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
    <constructor-arg>
        <ref bean="jaxb2Marshaller"/>
    </constructor-arg>
    <property name="supportedMediaTypes">
        <list>
            <bean class="org.springframework.http.MediaType">
                <constructor-arg index="0" value="application"/>
                <constructor-arg index="1" value="xml"/>
                <constructor-arg index="2" value="UTF-8"/>
            </bean>
        </list>
    </property>
</bean>

如果你想使用 spring 的内容协商,你可以使用 AnnotationMethodHandlerAdapter 和消息转换器:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="xmlConverter"/>
            <!-- other converters if you have them, e.g. for JSON -->
        </list>
    </property>
</bean>

【讨论】:

  • 感谢 beerbajay 的回复。我遇到的问题是我收到空值。发生这种情况可能是因为作者没有正确绑定我收到的 xml。所以首先我需要在模型类中将模型与 XML 正确绑定。我需要使用@XmlSchema 或类级别的属性来做到这一点。
【解决方案2】:

以下是如何映射此用例的示例:

包裹信息

我会使用包级别的@XmlSchema 注释来指定命名空间限定。将 namespace 指定为您的目标命名空间 ("http://www.../ckp")。您希望将此命名空间应用于所有 XML 元素,因此请指定 elementFormDefault=XmlNsForm.QUALIFIED。使用 xmlns 将前缀与您的命名空间 URI 相关联。

@XmlSchema(
    namespace="http://www.../ckp",
    elementFormDefault=XmlNsForm.QUALIFIED,
    xmlns={
        @XmlNs(prefix="", namespaceURI="http://www.../ckp"),
        @XmlNs(prefix="atom", namespaceURI="http://www.w3.org/2005/atom"),
    }
)
package forum10388261;

import javax.xml.bind.annotation.*;

作者

下面是你的Author 类的样子。我已经删除了不必要的注释(相当于默认映射的注释)。

package forum10388261;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Author {

    @XmlAttribute
    private String author;
    private String name;
    private String address;
    private String affiliation;
    private String email;

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getAffiliation() {
        return affiliation;
    }

    public void setAffiliation(String affiliation) {
        this.affiliation = affiliation;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

演示

package forum10388261;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Author.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10388261/input.xml");
        Author author = (Author) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(author, System.out);
    }

}

输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<author xmlns:atom="http://www.w3.org/2005/atom" xmlns="http://www.../ckp">
    <name>S. Crocker</name>
    <address>None</address>
    <affiliation></affiliation>
    <email>None</email>
</author>

更多信息

【讨论】:

  • 谢谢你!你解决了我的问题。还有很棒的教程!干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
相关资源
最近更新 更多