我试图通过Java连接Twinfield logon api。我试过的代码是
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.MimeHeaders;
import java.io.ByteArrayInputStream;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class SoapTest {
public static void main(String[] args) {
try {
SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
SOAPConnection connection = sfc.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage sm = mf.createMessage();
SOAPHeader sh = sm.getSOAPHeader();
SOAPBody sb = sm.getSOAPBody();
//sh.detachNode();
QName logonName = new QName("http://www.twinfield.com", "Logon");
SOAPBodyElement logonElement = sb.addBodyElement(logonName);
QName userTag = new QName("user");
SOAPElement user = logonElement.addChildElement(userTag);
user.addTextNode("myuser");
QName passwordTag = new QName("password");
SOAPElement password = logonElement.addChildElement(passwordTag);
password.addTextNode("mypassword");
QName organisationTag = new QName("organisation");
SOAPElement organisation = logonElement.addChildElement(organisationTag);
organisation.addTextNode("myorg");
System.out.println("\n Soap Request:\n");
sm.writeTo(System.out);
System.out.println();
URL endpoint = new URL("https://login.twinfield.com/webservices/session.asmx");
SOAPMessage response = connection.call(sm, endpoint);
connection.close();
//System.out.println(response.getContentDescription());
//System.out.println("--------------------------");
// Reading response
printSOAPResponse(response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
}
}
似乎一切都是正确的,但我经常收到回复<faultstring>Server did not recognize the value of HTTP Header SOAPAction: .</faultstring>
。以上程序的完整输出如下:
java SoapTest
Soap Request:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<Logon xmlns="http://www.twinfield.com">
<user>NLG001136</user>
<password>qura976yj</password>
<organisation>TWF-SAAS</organisation>
</Logon>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response SOAP Message =
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Server did not recognize the value of HTTP Header SOAPAction: .</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
相同的请求/凭据在Soapclient.com上正常运行。有人可以指出我的程序出错了吗?
答案 0 :(得分:2)
由于故障代码是客户端,因此您发送的soap消息导致问题。尝试使用SOAP UI传递相同内容,我尝试将WSDL导入到我的SOAP UI中,但是我收到了错误...
加载[https://login.twinfield.com/webservices/session.asmx?wsdl]时出错:org.apache.xmlbeans.XmlException:org.apache.xmlbeans.XmlException:错误:未关闭标记
由于Web服务已经被文件/文字包装,只需尝试使用wsimport创建客户端代码,您就可以获得所有需要的文件,并且可以轻松发送相同的请求。
如果您只对SAAJ方式感兴趣,那么我会尝试传递通过SOAP UI创建的消息。
希望这会有所帮助。
答案 1 :(得分:0)
最好使用Twinfield建议使用Twinfield Openid oAuth进行身份验证。要进行初始连接,请检查以下链接 https://stackoverflow.com/a/54652064
一旦您完成了初始连接设置并具有访问令牌,就可以继续获取公司列表。将Twinfield Web服务与访问令牌结合使用时,有必要在请求标头中提供公司ID或公司代码。 首先使用https://accounting.twinfield.com/webservices/processxml.asmx?wsdl
生成Java代码(twinfield的存根)您可以使用以下代码来请求获取公司列表
package example;
import com.user.defined.package.twinfield.Header;
import com.user.defined.package.twinfield.ObjectFactory;
import com.user.defined.package.twinfield.ProcessXml;
import com.user.defined.package.twinfield.ProcessXmlSoap;
import com.sun.xml.internal.ws.developer.WSBindingProvider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.soap.SOAPException;
public class HelloWorldClient {
public static void main(String[] argv) throws JAXBException, SOAPException {
ProcessXml processXmlService = new ProcessXml();
ProcessXmlSoap processXmlSoap = processXmlService.getProcessXmlSoap();
WSBindingProvider bp = (WSBindingProvider)processXmlSoap;
JAXBContext jaxbContext = JAXBContext.newInstance(Header.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
ObjectFactory objectFactory = new ObjectFactory();
Header header = new Header();
//active access token
header.setAccessToken("95cd6bb91a59751....................");
JAXBElement<Header> jaxbElement = objectFactory.createHeader(header);
//Just to check the soap header
jaxbMarshaller.marshal(jaxbElement, System.out);
//Set it to the bindingprovider
bp.setOutboundHeaders(
jaxbElement
);
String xmlRequest = "<list><type>offices</type></list>";
System.out.println(processXmlSoap.processXmlString(xmlRequest));
}
}