Hej
Próbuję za pośrednictwem soap'a pobrać dane z usługi DataStoreProvider (pobieranie danych z CEIDG) do której mam wygenerowany klucz api w aplikacji opartej o spring boota.
WSDL usługi umieszczony w katalogu resources:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="DataStoreProvider201901" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<wsp:Policy wsu:Id="BasicHttpBinding_IDataStoreProvider2019011_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
</wsp:Policy>
</sp:TransportBinding>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="https://datastore.ceidg.gov.pl/CEIDG.DataStore/services/DataStoreProvider201901.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="https://datastore.ceidg.gov.pl/CEIDG.DataStore/services/DataStoreProvider201901.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="https://datastore.ceidg.gov.pl/CEIDG.DataStore/services/DataStoreProvider201901.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IDataStoreProvider201901_GetID_InputMessage">
<wsdl:part name="parameters" element="tns:GetID"/>
</wsdl:message>
<wsdl:message name="IDataStoreProvider201901_GetID_OutputMessage">
<wsdl:part name="parameters" element="tns:GetIDResponse"/>
</wsdl:message>
<wsdl:message name="IDataStoreProvider201901_GetMigrationData201901_InputMessage">
<wsdl:part name="parameters" element="tns:GetMigrationData201901"/>
</wsdl:message>
<wsdl:message name="IDataStoreProvider201901_GetMigrationData201901_OutputMessage">
<wsdl:part name="parameters" element="tns:GetMigrationData201901Response"/>
</wsdl:message>
<wsdl:portType name="IDataStoreProvider201901">
<wsdl:operation name="GetID">
<wsdl:input wsaw:Action="http://tempuri.org/IDataStoreProvider201901/GetID" message="tns:IDataStoreProvider201901_GetID_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IDataStoreProvider201901/GetIDResponse" message="tns:IDataStoreProvider201901_GetID_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="GetMigrationData201901">
<wsdl:input wsaw:Action="http://tempuri.org/IDataStoreProvider201901/GetMigrationData201901" message="tns:IDataStoreProvider201901_GetMigrationData201901_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IDataStoreProvider201901/GetMigrationData201901Response" message="tns:IDataStoreProvider201901_GetMigrationData201901_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IDataStoreProvider201901" type="tns:IDataStoreProvider201901">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetID">
<soap:operation soapAction="http://tempuri.org/IDataStoreProvider201901/GetID" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetMigrationData201901">
<soap:operation soapAction="http://tempuri.org/IDataStoreProvider201901/GetMigrationData201901" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="BasicHttpBinding_IDataStoreProvider2019011" type="tns:IDataStoreProvider201901">
<wsp:PolicyReference URI="#BasicHttpBinding_IDataStoreProvider2019011_policy"/>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetID">
<soap:operation soapAction="http://tempuri.org/IDataStoreProvider201901/GetID" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetMigrationData201901">
<soap:operation soapAction="http://tempuri.org/IDataStoreProvider201901/GetMigrationData201901" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DataStoreProvider201901">
<wsdl:port name="BasicHttpBinding_IDataStoreProvider201901" binding="tns:BasicHttpBinding_IDataStoreProvider201901">
<soap:address location="http://datastore.ceidg.gov.pl/CEIDG.DataStore/services/DataStoreProvider201901.svc"/>
</wsdl:port>
<wsdl:port name="BasicHttpBinding_IDataStoreProvider2019011" binding="tns:BasicHttpBinding_IDataStoreProvider2019011">
<soap:address location="https://datastore.ceidg.gov.pl/CEIDG.DataStore/services/DataStoreProvider201901.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
POM uzupełniony o plugin, struktura klas na podstawie WSDL także wygenerowana.
Beany skonfigurowane:
@Configuration
public class BeanConfig {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("me.plich.cashregistersystem.generated");
return marshaller;
}
@Bean
public DataStoreProviderServiceAdapter soapConnector(Jaxb2Marshaller marshaller) {
DataStoreProviderServiceAdapter client = new DataStoreProviderServiceAdapter();
client.setDefaultUri("https://datastore.ceidg.gov.pl/CEIDG.DataStore/services/DataStoreProvider201901.svc");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
Klasa rozszerzająca WebServiceGatewaySupport również(nip na potrzeby posta wzięty z generatora, do usługi strzelam rzeczywistym, w miejscu myApiKey oczywiście doklejam swój klucz do api):
public class DataStoreProviderServiceAdapter extends WebServiceGatewaySupport {
public GetMigrationData201901Response getCompanyData(){
GetMigrationData201901 request = new GetMigrationData201901();
ObjectFactory factory = new ObjectFactory();
JAXBElement<String> key = factory.createGetMigrationData201901AuthToken("myApiKey");
ArrayOfstring check = new ArrayOfstring();
check.getString().add(0,"1075310455");
JAXBElement<ArrayOfstring> nip = factory.createGetMigrationData201901NIP(check);
System.out.println("NIP: "+nip.getValue().getString().toString());
System.out.println("key: "+key.getValue());
request.setNIP(nip);
request.setCity(factory.createGetMigrationData201901City(null));
request.setREGON(factory.createGetMigrationData201901REGON(null));
request.setNIPSC(factory.createGetMigrationData201901NIPSC(null));
request.setREGONSC(factory.createGetMigrationData201901REGONSC(null));
request.setName(factory.createGetMigrationData201901Name(null));
request.setProvince(factory.createGetMigrationData201901Province(null));
request.setCounty(factory.createGetMigrationData201901County(null));
request.setCommune(factory.createGetMigrationData201901Commune(null));
request.setStreet(factory.createGetMigrationData201901Street(null));
request.setPostcode(factory.createGetMigrationData201901Postcode(null));
request.setDateFrom(factory.createGetMigrationData201901DateFrom(null));
request.setDateTo(factory.createGetMigrationData201901MigrationDateTo(null));
request.setPKD(factory.createGetMigrationData201901PKD(null));
request.setStatus(factory.createGetMigrationData201901Status(null));
request.setUniqueId(factory.createGetMigrationData201901UniqueId(null));
request.setMigrationDateFrom(factory.createGetMigrationData201901DateFrom(null));
request.setMigrationDateTo(factory.createGetMigrationData201901MigrationDateTo(null));
request.setAuthToken(key);
GetMigrationData201901Response response = (GetMigrationData201901Response) getWebServiceTemplate().marshalSendAndReceive(request);
return response;
}
}
Po uzupełnieniu klucza do api oraz numeru nip.
Klasa startowa:
public class CashregistersystemApplication {
@PostConstruct
void init() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
public static void main(String[] args) {
SpringApplication.run(CashregistersystemApplication.class, args);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
DataStoreProviderServiceAdapter ds = context.getBean(DataStoreProviderServiceAdapter.class);
GetMigrationData201901Response response = ds.getCompanyData();
System.out.println("Wynik pobierania ="+response.toString());
}
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
W logach w terminalu dostaję komunikat:
Exception in thread "main" org.springframework.ws.soap.client.SoapFaultClientException: Komunikat o parametrze Action „” nie może zostać przetworzony w punkcie odbioru z powodu niezgodności parametru ContractFilter w EndpointDispatcher. Może to być spowodowane niezgodnością kontraktu (niezgodność czynności między nadawcą i odbiorcą) lub niezgodnością powiązania/zabezpieczeń między nadawcą i odbiorcą. Sprawdź, czy nadawca i odbiorca mają te same kontrakty i powiązania (w tym wymagania zabezpieczeń, np.: Message, Transport, None).
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373)
at aa.xyz.cashregistersystem.config.DataStoreProviderServiceAdapter.getCompanyData(DataStoreProviderServiceAdapter.java:45)
at aa.xyz.cashregistersystem.CashregistersystemApplication.main(CashregistersystemApplication.java:33)
Coś zrobiłem źle, tylko na podstawie samego WSDL'a nie jestem w stanie wywnioskować co (może czegoś nie przekazuję w requeście).
To moje pierwsze zetknięcie z soap'em także będę wdzięczny za poradę / wskazówkę :)
Update:
Zauważyłem, że mój request różni się od przykładowego z dokumentacji tagami ns.
Mój request:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:GetMigrationData201901 xmlns:ns2="http://tempuri.org/" xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns4="http://schemas.microsoft.com/2003/10/Serialization/">
<ns2:AuthToken>5WQKywVlcEBgbqzOmojzGFA+hKY9PfWZeW32Emel4O+BMcMbCZtfc7CbGTX+bIhP</ns2:AuthToken>
<ns2:Province xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</ns2:GetMigrationData201901>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Przykładowy request z dokumentacji:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<soapenv:Header/>
<soapenv:Body>
<tem: GetMigrationData201901>
<tem:AuthToken> Klucz dostępu użytkownika </tem:AuthToken>
<tem:Province>
<arr:string>podlaskie</arr:string>
</tem:Province>
<tem:MigrationDateFrom>2017-01-05</tem:MigrationDateFrom>
<tem:MigrationDateTo>2017-01-05</tem:MigrationDateTo>
</tem: GetMigrationData201901>
</soapenv:Body>
</soapenv:Envelope>
AKTUALIZACJA:
Udało się rozwiązać problem.
Brakowało nagłówka soapAction:
GetMigrationData201901Response response =
(GetMigrationData201901Response) getWebServiceTemplate().marshalSendAndReceive(request,
new SoapActionCallback("http://tempuri.org/IDataStoreProvider201901/GetMigrationData201901"));
Kolejny problem to fakt, że api nie zwraca xml'a jako takiego a długiego stringa w postaci:
<WynikWyszukiwania>
<InformacjaOWpisie>
<IdentyfikatorWpisu>9069a104dd12345d987c0cc36a2a614</IdentyfikatorWpisu>
<DanePodstawowe>
<Imie>Kamil</Imie>
<Nazwisko>Nowak</Nazwisko>
<NIP>5210342338</NIP>
<REGON>010456779</REGON>
<Firma>Kamil Nowak Nazwa Firmy</Firma>
</DanePodstawowe>
<DaneKontaktowe>
<AdresPocztyElektronicznej>oferty@ddsfsdf.pl</AdresPocztyElektronicznej>
<AdresStronyInternetowej/>
<Telefon/>
<Faks/>
</DaneKontaktowe>
</InformacjaOWpisie>
</WynikWyszukiwania>
Ale to już (domyślam się) kwestia opracowania odpowiedniego parsera :)