当前位置: 首页 > 知识库问答 >
问题:

指定名称空间JAXB的前缀

凌博实
2023-03-14

面临使用JAXB解组的问题。我需要使用多个名称空间。Java类是为第三方提供的XSD生成的。因此,我不想在Java类中的XMLRootElement指定名称空间,也不想手动更改多个类。

编组逻辑如下:

private <R extends BasicResponseType, T extends BasicRequestType> R doPost(T request, String requestname) throws Exception {
    if (jaxbContext == null)
        jaxbContext = JAXBContext.newInstance(TokenRequest.class, TokenResponse.class,
                BasicResponseType.class, GeneralErrorResponse.class);
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    logXML(marshaller, request);
    // POST to baseURL/requestname and show response
    HttpURLConnection conn = openConnection("/" + requestname);

    OutputStream os = conn.getOutputStream();
    marshaller.marshal(request, os);
    os.flush();
    // Normaler Output oder Error liefern, je nach HTTP Response
    InputStream is = null;
    boolean ok = true;
    if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
        is = conn.getErrorStream();
        ok = false;
    } else {
        is = conn.getInputStream();
    }
    R response = (R) unmarshaller.unmarshal(new StreamSource(is));
    is.close();
    conn.disconnect();
    logXML(marshaller, response);
    if (ok) {
        return response;
    } else {
        throw new Exception(getMessages((GeneralErrorResponse) response));
    }
}

xmlelement类TokenRequest.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "TokenRequest")
public class TokenRequest
extends BasicInRequestType{ }

BasicInRequestType.java

package exp._3_0.api;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BasicInRequestType", propOrder = {
"software"
})
@XmlSeeAlso({
TokenRequest.class    
})
public class BasicInRequestType
extends BasicRequestType {

@XmlElement(required = true)
protected SoftwareType software;

/**
 * Gets the value of the software property.
 * 
 * @return
 *     possible object is
 *     {@link SoftwareType }
 *     
 */
public SoftwareType getSoftware() {
    return software;
}

/**
 * Sets the value of the software property.
 * 
 * @param value
 *     allowed object is
 *     {@link SoftwareType }
 *     
 */
public void setSoftware(SoftwareType value) {
    this.software = value;
}}
package exp._3_0.api;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
propOrder = {
"header",
"user"
})
@XmlSeeAlso({
    BasicInRequestType.class
})
public class BasicRequestType {

@XmlElement(required = true)
protected BasicHeaderType header;
@XmlElement(required = true)
protected UserHeaderType user;
@XmlType(name = "BasicRequestType", namespace = "http://foo/1.0/common", 
/**
 * Gets the value of the header property.
 * 
 * @return
 *     possible object is
 *     {@link BasicHeaderType }
 *     
 */
public BasicHeaderType getHeader() {
    return header;
}

/**
 * Sets the value of the header property.
 * 
 * @param value
 *     allowed object is
 *     {@link BasicHeaderType }
 *     
 */
public void setHeader(BasicHeaderType value) {
    this.header = value;
}

/**
 * Gets the value of the user property.
 * 
 * @return
 *     possible object is
 *     {@link UserHeaderType }
 *     
 */
public UserHeaderType getUser() {
    return user;
}

/**
 * Sets the value of the user property.
 * 
 * @param value
 *     allowed object is
 *     {@link UserHeaderType }
 *     
 */
public void setUser(UserHeaderType value) {
    this.user = value;
}}
<TokenRequest xmlns:common="http://foo/1.0/common" xmlns:ns4="http://foo/3.0/api" xmlns:base="http://foo/3.0/base">
    <common:header>
        <common:requestId></common:requestId>
        <common:timestamp></common:timestamp>
    </common:header>
    <common:user>
        <common:login></common:login>
        <common:passwordHash></common:passwordHash>
    </common:user>
    <software>
        <softwareId></softwareId>
        <softwareName></softwareName>
    </software>
</TokenRequest>

我在package-info.java中指定了前缀

@javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
@javax.xml.bind.annotation.XmlNs(namespaceURI = "http://foo/3.0/api", prefix = ""),
@javax.xml.bind.annotation.XmlNs(namespaceURI = "http://foo/3.0/base", prefix = "base"), 
@javax.xml.bind.annotation.XmlNs(namespaceURI = "http://foo/1.0/common", prefix = "common") })
package exp._3_0.api;

TokenRequest元素实际上引用了名称空间=“http://foo/3.0/API”。在xml输出中,TokenRequest没有正确的any前缀,但是xmlns被设置为ns4,这导致了下面的错误。

请求正文包含行[1]和列[182]错误:[意外的元素(URI:“”,本地:“TokenRequest”)。需要的元素为<{http://foo/3.0/API}TokenRequest>]

即使在package-info中为namespace“http://foo/3.0/api”指定了前缀=“”之后,在输出中它仍然附加为NS4。请帮助如何修复删除NS4。

共有1个答案

杨超
2023-03-14

如注释中所述,@xmlschema缺少namespace属性,因此,除非显式限定,否则所有@xmlrootelement@xmltype都被认为没有命名空间。您的java-package.info应该如下所示:

@XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = "http://foo/3.0/api", xmlns = {
      @XmlNs(namespaceURI = "http://foo/3.0/api", prefix = ""),
      @XmlNs(namespaceURI = "http://foo/3.0/base", prefix = "base"),
      @XmlNs(namespaceURI = "http://foo/1.0/common", prefix = "common")})
package exp._3_0.api;

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

@xmlns注释不指定Java包中使用的默认名称空间。它们只向JAXB实现提供一个建议,说明要为那些名称空间分配什么前缀。在您的示例中,标记 不属于任何名称空间,因此,JAXB为这些元素使用了一个空前缀,并且必须为http://foo/3.0/api名称空间中的元素使用另一个前缀(ns4)(没有任何名称空间)。

 类似资料:
  • 我正在开发一个客户端来使用 Web 服务,但由于某种原因,除非所有命名空间都正确且没有任何前缀,否则我的请求没有得到正确处理。 我所有的类都是由服务提供商使用提供的XSD和WSDL创建的。 NfeDadosMsg.class 包装信息.java TConsStatServ.class package br.inf.portalfiscal.nfe; 包装信息.java 输出xml: 由于某种原因,

  • 问题内容: 除了包级别注释外,还有其他方法可以使用注释来控制自定义名称空间前缀。 可以在元素级别完成吗?也可能有一个带有多个前缀的名称空间吗? 问题答案: 您实际上想做什么?为什么名称空间前缀对您很重要? 对于命名空间前缀,没有标准的元素级注释。 我知道的控制名称空间前缀的选项是: 你已经提到过。 提供习俗。 XML的低级处理(例如,在StAX,SAX或DOM级别)。 我也可以想象: / 通常使用

  • 我想知道是否有一种方法来强制JAXB创建与XSD模式相同的名称空间前缀。即,即使我从一个包含xmlns:cts=“http://cts.com”的模式创建JAXB类,在封送类之后,我得到一个具有xmlns:ns1前缀的XML。我知道我可以通过使用NamespacePrefixMapper类来重写这些,但是为什么我需要在我的XSD明确定义了默认前缀的情况下手动执行此操作呢?在我当前的XML中有大量的

  • 2)如果我按照下面的方式编辑package-info,那么它是很好的,但是问题是我创建的是一个JAXB整数元素如下所示,前缀删除没有应用于这些元素

  • 我有5个schemas.xsd,用于生成Java类,然后封送XML文件。 问题是只有一种情况--对于这个文件,JAXB生成额外的名称空间前缀NS2。这是非常奇怪的,因为所有模式都是相同的,并且编组机制对于所有模式都是通用的。 生成机制: 对于不能正常工作的包: 包信息: 对象-工厂 良好工作包: 包信息: 和对象工厂看起来完全一样(当然除了命名)。

  • 首先,我想说我已经读过 http://blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes.html 我的应用程序中有多个包,比如 等 > 我是否需要在每个软件包中放入软件包信息.java?例如,包装信息.java pkg1,pkg2等? 或者全局包信息.java可以保存所有信息。就像我想把包信息.java文件放在my.xml包中,让它工作。