面临使用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。
如注释中所述,@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包中,让它工作。