Send file using Axis2 1.7.4 from java client - java

I want to send a file using Axis2 1.7.4 to this endpoint https://cel.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantes?wsdl
Part of this code look like this:
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace ns = factory.createOMNamespace("http://ec.gob.sri.ws.recepcion", "RecepcionComprobantesService");
OMElement validarComprobante = factory.createOMElement("validarComprobante", ns);
ConfigurableDataHandler dataHandler = new ConfigurableDataHandler(new FileDataSource("file.xml"));
dataHandler.setTransferEncoding("UTF-8");
dataHandler.setContentType("txt/xml");
OMText textData = factory.createOMText(dataHandler, false);
validarComprobante.addChild(textData);
...
ServiceClient client = new ServiceClient();
...
OMElement response = client.sendReceive(validarComprobante);
I have a response from the server but the file is not accepted, because i get this message"FILES SUBMITTED DO NOT MEET THE SPECIFICATIONS ESTABLISHED: EXTENSION, CODIFICATION"
I read the documentation and the file is sent as Base64 encoded string, so i think that is the problem the content of the file is serialized and i dont know if is possible resolve that.

As per the WSDL description soap request body xml tag expecting base64 encoded string. So you have to read the file content,convert into base64 encoded string and try to pass that string value to xml tag.
You SOAP request should be similar to this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ec="http://ec.gob.sri.ws.recepcion">
<soapenv:Header/>
<soapenv:Body>
<ec:validarComprobante>
<!--Optional:-->
<xml>VGhpcyBpcyB0ZXN0IGRvY3VtZW50</xml>
</ec:validarComprobante>
</soapenv:Body>
</soapenv:Envelope>

Related

SOAP: How to Make Call to CountryInfoService WSDL file in Java e.g. use CapitalCity SOAP Operation

Hi so I managed to generate WSDL Java Classes using Java-WS with the "wsimport" command. The WSDL file is from:
http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?wsdl
The problem is that Im not familiar on how to use this.
How do I make a SOAP call to the CapitalCity SOAP method.
In SOAPUI, you would just pass the CountryISOCode like:
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.oorsprong.org/websamples.countryinfo">
<soapenv:Header/>
<soapenv:Body>
<web:CapitalCity>
<web:sCountryISOCode>UKR</web:sCountryISOCode>
</web:CapitalCity>
</soapenv:Body>
</soapenv:Envelope>
How to do this in Java?
This is my code that I've started.
CountryInfoService countryInfoService = new CountryInfoService();
I dont know what follows next. Again Im trying to use the "CapitalCity" SOAP Operation.
Here's a sample answer:
CountryInfoService countryInfoService = new CountryInfoService();
CountryInfoServiceSoapType countryInfoServiceSoapType = countryInfoService.getCountryInfoServiceSoap();
System.out.println(countryInfoServiceSoapType.capitalCity("RUS"));
//output is 'Moscow'
That's how to use it.

how to retrieve specific web service response from the server

Web service provider has provided us(Client) a wsdl to use their service and consume data. Our requirement is, we just need specific node value called "CHASE", see below test data. We don't want to get all records of info and corresponding nodes in the response.
Here is an example that we have tested in SOAPUI tool. Please suggest and help us how can we frame the web service request technically from the URL provided(http://host:port/ValueMappingInService/ValueMappingInImplBean)? Is it at all possible to drill down the request and get specific response from client side?
Web service Request:-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:bas="http://sap.com/xi/BASIS">
<soapenv:Header/>
<soapenv:Body>
<bas:ValueMappingReadRequest>
<!--Optional:-->
<ReadContext>User</ReadContext>
<!--Zero or more repetitions:-->
<ValueMappingID>c44f541f-c8ac-11e8-86e5-0050569d98cc</ValueMappingID>
</bas:ValueMappingReadRequest>
</soapenv:Body>
</soapenv:Envelope>
Web service Response:-
<SOAP-ENV:Envelope xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns2:ValueMappingReadResponse xmlns:ns2="http://sap.com/xi/BASIS">
<ValueMapping>
<MasterLanguage>EN</MasterLanguage>
<AdministrativeData>
<ResponsibleUserAccountID>gdonna</ResponsibleUserAccountID>
<LastChangeUserAccountID>gdonna</LastChangeUserAccountID>
<LastChangeDateTime>2018-10-05T09:47:38.237-05:00</LastChangeDateTime>
<FolderPathID>/</FolderPathID>
</AdministrativeData>
<ValueMappingID>c44f541f-c8ac-11e8-86e5-0050569d98cc</ValueMappingID>
<GroupName>Mercedes</GroupName>
<Representation schemeAgencyID="LOC_BANK" schemeID="BANK">CHASE</Representation>
<Representation schemeAgencyID="LOC_SITE" schemeID="DIR">comm/as2/chase/receive/</Representation>
<Representation schemeAgencyID="LOC_COUNTRY" schemeID="CODE">US</Representation>
</ValueMapping>
<LogMessageCollection/>
</ns2:ValueMappingReadResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Try using a Groovy Script. I really like the features of the XMLSlurper, which lets me ignore the namespaces if/when they change.
Just add a new Groovy Script teststep, and put this into it. You just need to adjust the name of your Soap Request teststep, which should be placed just before this teststep.
/** The name should be modified to match the request/response you want to validate */
def holder = new com.eviware.soapui.support.GroovyUtils( context ).getXmlHolder("The Name Of Your Soap Request TestStep#Response")
def response = new XmlSlurper().parseText(holder.getXml())
for (def element : response.Body.ValueMappingReadResponse.ValueMapping.Representation)
{
log.info element
log.info element.#'schemeAgencyID'
}

From WDSL to java

I've been tasked with querying a soap client in java and i'm a bit confused as how to move forward.
The first thing i did was use the Wizdler chrome plugin to prototype my SOAP request. The soap "envelop" must be of this format I believe for it to work.
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope">
<Body>
<GetMyProjectCharges xmlns="http://COMPANY.IWWeb.Data.Service.ProjectCharges">
<Employee>[string?]</Employee>
<FiscalYear>[string?]</FiscalYear>
<ApiKey>[string?]</ApiKey>
<AppName>[string?]</AppName>
</GetMyProjectCharges>
</Body>
</Envelope>
Next I've gone through some various tutorial as how to build a soap envelop in java but i keep getting into a strange situation where i'm getting <SOAP-ENV: prefixes on everything and when i take the generated envelop and try to paste it into the chrome plugin it doesn't work.
So I'm wondering where I go from here? I realize soap is a pretty heavy protocol and so maybe that is what is confusing me but what I'm looking to do (for now) is:
1) Generate a soap request in java that matches the format above, and print out the results.
I understand i "might" have the option of Maven or some program to generate some class files for me from the WDSL but I'm not exactly sure what i do with that either. Thanks!
Any help would be appreciated.
You have two way to do a soap request.
Solution 1
If you use netbeans as code IDE, you have to create a project, right click on a package and choose New >> Web Service Client. Insert the url of the soap endpoint and click ok. If you have jax-ws/Metro extension installed in your ide netbeans will generate all necessary classes to invoke the service programmatically. (ask me if you have troubles)
Solution 2
you could realize a soap request using simply javax.xml
private SOAPMessage invoke(QName serviceName, QName portName,
String soapActionUri) throws Exception {
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);
Dispatch dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE);
dispatch.getRequestContext().put(Dispatch.SOAPACTION_USE_PROPERTY, new Boolean(true));
dispatch.getRequestContext().put(Dispatch.SOAPACTION_URI_PROPERTY, soapActionUri);
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody body = envelope.getBody();
Source source = new DOMSource(getQueryString());
soapPart.setContent(source);
message.saveChanges();
System.out.println(message.getSOAPBody().getFirstChild().getTextContent());
SOAPMessage response = (SOAPMessage) dispatch.invoke(message);
return response;
}
private Node getQueryString() throws SAXException, IOException, ParserConfigurationException {
StringBuilder builder = new StringBuilder();
builder.append("<soapenv:Envelope");
// create your body
builder.append("</soapenv:Body>");
builder.append("</soapenv:Envelope>");
DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docbuilder = docfactory.newDocumentBuilder();
Document stringDocument = docbuilder.parse(new InputSource(new StringReader(builder.toString())));
return stringDocument;
}
and to call the service use
String targetNameSpace = "your target namespace";
QName serviceName = new QName(targetNameSpace, "your service name");
QName portName = new QName(targetNameSpace, "Your port name");
String SOAPAction = "your soap action";
SOAPMessage response = invoke(serviceName, portName, SOAPAction);
if (response.getSOAPBody().hasFault()) {
System.out.println(response.getSOAPBody().getFault());
}
P.S. forgive me for my english :(
I am not sure if I got the point. Anyway I think you need to have the correct namespace for your soap messages. A blank SOAP message would look like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
So in your case I think this should work:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<GetMyProjectCharges xmlns="http://COMPANY.IWWeb.Data.Service.ProjectCharges">
<Employee>[string?]</Employee>
<FiscalYear>[string?]</FiscalYear>
<ApiKey>[string?]</ApiKey>
<AppName>[string?]</AppName>
</GetMyProjectCharges>
</soapenv:Body>
</soapenv:Envelope>
But normally you use a namespace in the payload as well (which means GetMyProjectCharges would be something like jeef:GetMyProjectCharges).
Watch the 2nd namespace in the root tag
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jeef="http://COMPANY.IWWeb.Data.Service.ProjectCharges">
<soapenv:Header/>
<soapenv:Body>
<jeef:GetMyProjectCharges>
<jeef:Employee>[string?]</jeef:Employee>
<jeef:FiscalYear>[string?]</jeef:FiscalYear>
<jeef:ApiKey>[string?]</jeef:ApiKey>
<AppName>[string?]</jeef:AppName>
</jeef:GetMyProjectCharges>
</soapenv:Body>
</soapenv:Envelope>
To parse the SOAP messages it would be a good choice to use some wsdl to objects conversion tool. There are maven plugins for this as you already found out. To process the SOAP messages it would be worth to take a look at Apache Camel.
Note: namespaces are defined by xmlns:whatever="http://some.url.to.a.model/".
#Jeff you have to do something like this :
MyWebService service = new MyWebService(new Url(wsdlStringEndpoint));
Port port = service.getHttpsoap11port();
port.makerequest();
I've wroted a genericall call to make you understand how it should look. If you have some problems ask again (the code is a sample code)

Parsing SOAP request sent from SOAPUI - using Axis2 Servlet

Here's the SOAP request that I am submitting using SOAPUI
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:My namespace="My Package">
<soapenv:Header>
<Username>q</Username>
<Password>q</Password>
</soapenv:Header>
<soapenv:Body>
<Op:Op>
<Op:int>2134</Op:int>
</Op:Op>
</soapenv:Body>
</soapenv:Envelope>
Now I have created a maven project in eclipse and have generated a wsdl file, aar file (for deploying using Tomcat 7) and a jar file from the Java code (java2wsdl). When the request is submitted, the code must authorize the user with credentials provided under the header element. However, I am not able to parse the SOAP request. When I tried parsing with,
SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
SOAPEnvelope envelope = fac.getDefaultEnvelope();
SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();
Iterator it = header.getChildElements();
Iterator bodyIt = body.getChildElements();
while (it.hasNext()) {
OMElement e = (OMElement) it.next();
System.out.println(e.getText().toString());
}
while (bodyIt.hasNext()) {
OMElement e = (OMElement) bodyIt.next();
System.out.println(e.getText().toString());
}
whereby SOAPFactory and other objects are imported from axiom, none of the print statements where executed. So the question is how do I parse this request so that I have the ability to read the header and body?
I apologize if anything is vague; I am still new to Java web services.
From the Javadoc of the SOAPFactory#getDefaultEnvelope() method:
Create a default SOAP envelope with an empty header and an empty body.
So your Java code behaves as expected.

Error getting response from a web service Non-default namespace can not map to empty URI

I'm trying to make a java webservice client. It's a very simple service that receives a String and return another String. I'm testing the service with soapUI and works perfectly but when I try to code it in java it fails.
Here is the code I'm using to call the service
QName QNAME_TYPE_STRING = new QName(nameSpaceURI,"string");
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName(nameSpaceURI, webServiceMethod));
call.addParameter("buil:arg0", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(QNAME_TYPE_STRING, String.class);
String ret = (String) call.invoke(new Object[]{"PARAMETER VALUE"});
The endPoint variable points correctly to the URL of the service, and:
nameSpaceURI = "http://build.response.service/";
webServiceMethod = "buildResponse";
The thing is that the webService gets the parameter correctly but something happens on the response:
Caused by: com.ctc.wstx.exc.WstxParsingException: Non-default namespace can not map to
empty URI (as per Namespace 1.0 # 2) in XML 1.0 documents
at javax.xml.stream.SerializableLocation#6fee8ce6
This is a sample of my request on soapUI
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:buil="http://build.response.service/">
<soapenv:Header/>
<soapenv:Body>
<buil:buildResponse>
<buil:arg0>PARAMETER VALUE</buil:arg0>
</buil:buildResponse>
</soapenv:Body>
</soapenv:Envelope>
And this is a sample of the response on soapUI
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:buildResponse xmlns:ns1="http://build.response.service/">
<return xmlns="http://build.response.service/">
RESPONSE1,RESPONSE2,RESPONSE3
</return>
</ns1:buildResponse>
</soap:Body>
</soap:Envelope>
¿Ideas? I think this has something to do with the response, but I'm really a novice with webServices (I know... I know... the 21th century...).
Some more information: I'm not authorized to use wsdl2java nor publish the wsdl of the service (it's autogenerated anyway, I have nothing to do with it and it won't change). Sorry about this, I hope can help me despite this limitations.
Thanks!
God... it was so simple, made this little change on the call parameters:
call.addParameter(new QName(nameSpaceURI, "buil:arg0"),XMLType.XSD_STRING,ParameterMode.IN);
call.addParameter(new QName(nameSpaceURI, "return"), XMLType.XSD_STRING, ParameterMode.OUT);
Now it works like a charm, hope this helps someone.

Categories

Resources