我有一个Java
类来生成以下XML
:
<v:Envelope xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header>
<b>LGE Nexus 5</b>
<c>ANDROID</c>
<d>6.0.1</d>
<e>4.1.5</e>
<f>127.0.0.1</f>
<g/>?<g>
<h>0.0</h>
<i>0.0</i>
<j"/>
<k>8320738e-8634-4f73-a4dd-874a5d79e336</k>
<l>2017-08-14 13:24:01</l>
<m>8797e74f0d6eb7b1ff3dc114d4aa12d3</m>
</v:Header>
<v:Body>
<ns2:getStatus xmlns:ns2="http://soap.ws.placa.service.sinesp.serpro.gov.br/">
<a>ABC1234</a>
</ns2:getStatus>
</v:Body>
</v:Envelope>
但我目前的结果是:
<v:Envelope xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header>
<b xmlns="http://schemas.xmlsoap.org/soap/envelope/">LGE Nexus 5</b>
<c xmlns="http://schemas.xmlsoap.org/soap/envelope/">ANDROID</c>
<d xmlns="http://schemas.xmlsoap.org/soap/envelope/">6.0.1</d>
<e xmlns="http://schemas.xmlsoap.org/soap/envelope/">4.1.5</e>
<f xmlns="http://schemas.xmlsoap.org/soap/envelope/">127.0.0.1</f>
<g xmlns="http://schemas.xmlsoap.org/soap/envelope/">?</g>
<h xmlns="http://schemas.xmlsoap.org/soap/envelope/">0.0</h>
<i xmlns="http://schemas.xmlsoap.org/soap/envelope/">0.0</i>
<j xmlns="http://schemas.xmlsoap.org/soap/envelope/" />
<k xmlns="http://schemas.xmlsoap.org/soap/envelope/">8320738e-8634-4f73-a4dd-874a5d79e336</k>
<l xmlns="http://schemas.xmlsoap.org/soap/envelope/">2017-08-14 13:24:01</l>
<m xmlns="http://schemas.xmlsoap.org/soap/envelope/">8797e74f0d6eb7b1ff3dc114d4aa12d3</m>
</v:Header>
<v:Body>
<ns2:getStatus xmlns:ns2="http://soap.ws.placa.service.sinesp.serpro.gov.br/">
<a>ABC1234</a>
</ns2:getStatus>
</v:Body>
</v:Envelope>
我的class
如下:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import org.w3c.dom.Document;
@XmlRootElement(name = "getStatus", namespace = "http://soap.ws.placa.service.sinesp.serpro.gov.br/")
public class Request {
private String plate;
private String device;
private Double latitude;
private String operationalSystem;
private String majorVersion;
private String minorVersion;
private String ip;
private String token;
private String uuid;
private Double longitude;
private String date;
private String hash;
public Request() {
this.device = "LGE Nexus 5";
this.operationalSystem = "ANDROID";
this.majorVersion = "6.0.1";
this.minorVersion = "4.1.5";
this.ip = "127.0.0.1";
this.hash = "8797e74f0d6eb7b1ff3dc114d4aa12d3";
}
@XmlElement(name = "a")
public String getPlate() {
return plate;
}
public void setPlate(String plate) {
this.plate = plate;
}
@XmlTransient
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
@XmlTransient
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
@XmlTransient
public String getOperationalSystem() {
return operationalSystem;
}
public void setOperationalSystem(String operationalSystem) {
this.operationalSystem = operationalSystem;
}
@XmlTransient
public String getMajorVersion() {
return majorVersion;
}
public void setMajorVersion(String majorVersion) {
this.majorVersion = majorVersion;
}
@XmlTransient
public String getMinorVersion() {
return minorVersion;
}
public void setMinorVersion(String minorVersion) {
this.minorVersion = minorVersion;
}
@XmlTransient
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
@XmlTransient
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@XmlTransient
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@XmlTransient
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
@XmlTransient
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
@XmlTransient
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public String toXML() {
Document document;
Marshaller marshaller;
SOAPMessage soapMessage;
ByteArrayOutputStream outputStream;
String output;
try {
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
marshaller = JAXBContext.newInstance(Request.class).createMarshaller();
marshaller.marshal(this, document);
soapMessage = MessageFactory.newInstance().createMessage();
this.fillEnvelope(soapMessage.getSOAPPart().getEnvelope());
this.fillBody(soapMessage.getSOAPBody(), document);
this.fillHeaders(soapMessage.getSOAPHeader());
outputStream = new ByteArrayOutputStream();
soapMessage.writeTo(outputStream);
output = new String(outputStream.toByteArray());
} catch (IOException | JAXBException | ParserConfigurationException | SOAPException ex) {
throw new RuntimeException(ex);
}
return output;
}
private void fillEnvelope(SOAPEnvelope envelope) {
Iterator prefixes;
envelope.setPrefix("v");
prefixes = envelope.getNamespacePrefixes();
while (prefixes.hasNext()) {
String prefix = (String) prefixes.next();
envelope.removeNamespaceDeclaration(prefix);
}
}
private void fillHeaders(SOAPHeader soapHeader) throws SOAPException {
soapHeader.setPrefix("v");
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "b")).setValue(this.device);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "c")).setValue(this.operationalSystem);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "d")).setValue(this.majorVersion);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "e")).setValue(this.minorVersion);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "f")).setValue(this.ip);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "g")).setValue(this.token);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "h")).setValue(String.valueOf(this.longitude));
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "i")).setValue(String.valueOf(this.latitude));
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "j")).setValue("");
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "k")).setValue(this.uuid);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "l")).setValue(this.date);
soapHeader.addHeaderElement(new QName(soapHeader.getNamespaceURI(), "m")).setValue(this.hash);
}
private void fillBody(SOAPBody soapBody, Document document) throws SOAPException {
soapBody.addDocument(document);
soapBody.setPrefix("v");
}
}
测试方法是:
public static void main(String[] args) {
Request request = new Request();
request.setToken("?");
request.setLatitude(0.0);
request.setLongitude(0.0);
request.setUuid(UUID.randomUUID().toString()); // RFC 4122 Class 4 random UUID
request.setDate("2017-08-14 13:24:01");
request.setPlate("ABC1234");
System.out.println(request.toXML());
}
我需要做些什么才能删除namespace
的{{1}}属性?
答案 0 :(得分:2)
您可以使用正则表达式删除命名空间:
xml.replaceAll(" xmlns=\".*?\"", "");
其中变量xml是您的XML字符串。
答案 1 :(得分:1)
每个SOAP标头块(Header
元素的直接子节点)必须根据SOAP specification限定名称空间。因此,您的XML将违反SOAP规范。
您当然可以使用其他方法或纯XML库来创建所需的XML,但在使用soapHeader.addHeaderElement
时,JAX-RS实现(至少在Oracle的JRE中)验证此要求并抛出异常,如果您尝试添加带有空名称的标题块。
答案 2 :(得分:0)
这是一个对我有用的恶心黑客。首先,您需要知道 namespaceURI 存储在哪个类中。您可以通过调试应用程序、查看 SOAPHeaderElement 对象的字段并导航到 namespaceURI 的源来实现这一点。
从那里,您在实例化后使用反射将字段设置为空。然后删除该属性。这应该导致属性不被写出。这取决于实现。
SOAPHeaderElement headerElement = header.addHeaderElement(new QName("whatever", "myHeaderName") );
// Disgusting hack to remove the xmlns attribute
Field namespaceURIField = ElementNSImpl.class.getDeclaredField("namespaceURI");
namespaceURIField.setAccessible(true);
namespaceURIField.set(headerElement, null);
namespaceURIField.setAccessible(false);
headerElement.removeAttribute("xmlns");