用Java构建SOAP客户机
我想在Java中使用一个SOAP API,它接收像这样的XML,来调用一个方法:用Java构建SOAP客户机,java,xml,web-services,soap,jaxb,Java,Xml,Web Services,Soap,Jaxb,我想在Java中使用一个SOAP API,它接收像这样的XML,来调用一个方法: <?xml version="1.0" encoding="utf-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan
<?xml version="1.0" encoding="utf-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<GetReturnAnalysis xmlns="http://www.address.com/integration">
<entityCode>186D3CAD-0841</entityCode>
</GetReturnAnalysis>
</env:Body>
</env:Envelope>
并生成以下代码以生成要发送的消息:
private SOAPMessage createSOAPRequest(GetReturnAnalysis request) throws SOAPException, JAXBException, IOException, ParserConfigurationException, SAXException {
MessageFactory messageFactory = MessageFactory.newInstance("SOAP 1.2 Protocol");
SOAPMessage message = messageFactory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
message.getSOAPHeader().detachNode();
SOAPBody body = envelope.getBody();
String requestString = XmlHelper.toOutputString(request);
Document doc = convertStringToDocument(requestString);
body.addDocument(doc);
message.writeTo(System.out);
message.saveChanges();
message.writeTo(System.out);
return message;
}
(在本代码中,内部调用的方法):
但是当我添加到消息(body.addDocument方法)时,它检索到一个错误(那里不应该有名称空间)
正如您可能已经注意到的,在代码中,我将两个message.writeTo(对于调试,在createSOAPRequest方法上)。第一个正确地给出了XML,第二个正确地给出了XML,在我调用“save”之后,我在GetReturnAnalysis上得到了xmlns属性为空的XML
我想知道你是否能帮我。我是个肥皂迷,在这个问题上有很多麻烦
更新1
我已使用postman成功发送了一条包含以下XML的消息:
<?xml version="1.0" encoding="utf-8"?>
<env:Envelope xmlns="http://www.address.com/integration" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<GetReturnAnalysis >
<entityCode>186D3CAD-0841</entityCode>
</GetReturnAnalysis>
</env:Body>
</env:Envelope>
以及创建SOAP请求方法:
private SOAPMessage createSOAPRequest(GetReturnAnalysis request) throws SOAPException, JAXBException, IOException, ParserConfigurationException, SAXException {
MessageFactory messageFactory = MessageFactory.newInstance("SOAP 1.2 Protocol");
SOAPMessage message = messageFactory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("", "http://www.address.com/integration");
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
message.getSOAPHeader().detachNode();
SOAPBody body = envelope.getBody();
String requestString = XmlHelper.toOutputString(request);
Document doc = convertStringToDocument(requestString);
body.addDocument(doc);
message.writeTo(System.out);
message.saveChanges();
message.writeTo(System.out);
return message;
}
但是,由于某些不确定的原因,当我调用message.saveChanges时,GetReturnAnalysis类的结果如下:
@XmlRootElement(name = "GetReturnAnalysis", namespace = "http://www.address.com/integration")
public class GetReturnAnalysisRequest { ...
<GetReturnAnalysis xmlns="">
<EntityCode>186D3CAD-0841</EntityCode>
</GetReturnAnalysis>ityCode>
186D3CAD-0841
ITY代码>
空的xmlns属性覆盖了我提供的整个名称空间。我想知道为什么会这样?它不能简单地保存我想要保存的字符串而不进行更改吗???您的代码中有几个问题 命名空间定义:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "GetReturnAnalysis", namespace = "http://www.address.com/integration")
public class GetReturnAnalysisRequest {
@XmlElement(name = "entityCode", namespace = "http://www.address.com/integration")
protected String entityCode;
public GetReturnAnalysisRequest(String entityCode) {
this.entityCode = entityCode;
}
public GetReturnAnalysisRequest() { }
public String getEntityCode() {
return entityCode;
}
public void setEntityCode(String entityCode) {
this.entityCode = entityCode;
}
}
第二个-将文档生成器设置为命名空间感知
String requestString = toOutputString(request);
Document doc = convertStringToDocument(requestString);
body.addDocument(doc);
message.writeTo(System.out);
-
使用框架
要使用web服务,实际上应该使用框架。我会建议(我的首选)或。然后,您可以定义服务接口并生成适当的wsdl和客户机类,还可以获得对其他可选协议和扩展(例如安全性)的支持
仅在特殊情况下才直接处理XML,例如RPC文本、自定义安全性或其他不再受支持的协议 您必须定义请求对象的名称空间。但我建议贯穿整个WS生命周期。从拥有WSDL开始,生成客户机类和消息对象,并使用对象级API调用或公开web服务。我建议使用一些成熟的框架,如Axis2或CXF(我的首选)。您能发布错误/异常吗?当我使用空属性调用时,会显示响应:response SOAP Message…SOAP:SenderSystem.Web.Services.Protocols.SoapException:如果没有有效的操作参数,则无法处理请求。请提供有效的soap操作。位于System.Web.Services.Protocol.Soap12ServerProtocolHelper.RouterRequest()处的System.Web.Services.Protocols.SoapServerProtocol.Initialize()。。。异常消息,当我尝试在类上放置名称空间时:namespace\u ERR:试图创建或更改对象的方式与名称空间不符。@Gust2我正在搜索如何为该对象定义名称空间,但尚未找到方法。我相信这会帮我解决问题。。。
private SOAPMessage createSOAPRequest(GetReturnAnalysis request) throws SOAPException, JAXBException, IOException, ParserConfigurationException, SAXException {
MessageFactory messageFactory = MessageFactory.newInstance("SOAP 1.2 Protocol");
SOAPMessage message = messageFactory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("", "http://www.address.com/integration");
envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
message.getSOAPHeader().detachNode();
SOAPBody body = envelope.getBody();
String requestString = XmlHelper.toOutputString(request);
Document doc = convertStringToDocument(requestString);
body.addDocument(doc);
message.writeTo(System.out);
message.saveChanges();
message.writeTo(System.out);
return message;
}
<GetReturnAnalysis xmlns="">
<EntityCode>186D3CAD-0841</EntityCode>
</GetReturnAnalysis>ityCode>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "GetReturnAnalysis", namespace = "http://www.address.com/integration")
public class GetReturnAnalysisRequest {
@XmlElement(name = "entityCode", namespace = "http://www.address.com/integration")
protected String entityCode;
public GetReturnAnalysisRequest(String entityCode) {
this.entityCode = entityCode;
}
public GetReturnAnalysisRequest() { }
public String getEntityCode() {
return entityCode;
}
public void setEntityCode(String entityCode) {
this.entityCode = entityCode;
}
}
String requestString = toOutputString(request);
Document doc = convertStringToDocument(requestString);
body.addDocument(doc);
message.writeTo(System.out);
private Document convertStringToDocument(String xml) throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setNamespaceAware(true);
return docFactory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
}