I want to connect to a webservice (WS). However, a cookie must be provided in order to interact with this webservice.
So far, here is what I have:
String requiredCookieName = "requiredCookieName";
String requiredCookieValue = getRequiredCookieValue();
// Prepare SOAP message
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
soapMessage.getMimeHeaders().addHeader("SOAPAction", getSoapAction());
soapMessage.saveChanges();
// Send SOAP message
SOAPConnection soapConnection = buildSoapConnection();
SOAPBody soapBody = soapConnection
// How to add required cookie here before calling WS?
.call(soapMessage, getOperationLocation("operationName"))
.getSOAPBody();
// Process response...
How can I add the required cookie to the underlying HTTP request to WS?
You can do that by adding the corresponding Cookie HTTP header to the message (exactly as you are already doing for the SOAPAction header):
soapMessage.getMimeHeaders().addHeader(
"Cookie", requiredCookieName + "=" + requiredCookieValue);
Related
I want to consume Business Central Web service so I can add it to an existing web application.
I have tried:
Testing with Postman using Authorization header (works)
Testing SoapUI (works)
But I am getting this error:
com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnection post
SEVERE: SAAJ0008: Bad Response; Unauthorized
Exception in thread "main" com.sun.xml.messaging.saaj.SOAPExceptionImpl: java.security.PrivilegedActionException: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Bad response: (401Unauthorized
at com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:171)
Code:
String webPage = "https://api.businesscentral.dynamics.com/v2.0/<tenant>/...";
String name = "username";
String password = "password";
String authString = name + ":" + password;
String authEncBytes = new String(Base64.getEncoder().encode(authString.getBytes(StandardCharsets.UTF_8)));
String authStringEnc = new String(authEncBytes);
URL url = new URL(webPage);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.getHeader().detachNode();
envelope.addHeader();
MimeHeaders hd = soapMessage.getMimeHeaders();
hd.addHeader("Authorization", "Basic " + authEncBytes);
SOAPBody soapBodytxaber = envelope.getBody();
envelope.addNamespaceDeclaration("myNamespace", "uri");
SOAPElement soapBodyElem0txa = soapBodytxaber.addChildElement("Read", "myNamespace");
SOAPElement soapBodyElem1txa = soapBodyElem0txa.addChildElement("No", "myNamespace");
soapBodyElem1txa.addTextNode("00000058");
SOAPConnectionFactory soapConnectionFactory = OAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
soapMessage.saveChanges();
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
You need to make sure that the user you are trying to authenticate with has a Web Services Access Key.
Then you must use the Web Services Access Key as the password when authenticating.
It does also appear that you are missing a space after Basic in this line of code:
hd.addHeader("Authorization", "Basic" + authEncBytes);
It should probably be
hd.addHeader("Authorization", "Basic " + authEncBytes);
SOLUTION
Okay so after receiving a course, they told me that Basic Authorization is deprecated and they use now OAuth 2...
Thanks for replying
Greetings
I'm sending a SOAP call to a server, and the server insists on a certain Content-Type. I'm trying to set the content type but it doesn't seem to be transmitted properly.
I get a response from the server:
415 Cannot process the message because the content type 'text/xml;
charset=utf-8' was not the expected type 'application/soap+xml;
charset=utf-8'
My rough code:
val soapConnectionFactory = SOAPConnectionFactory.newInstance()
val soapConnection = soapConnectionFactory.createConnection()
val url = "https://secure.com"
val messageFactory = MessageFactory.newInstance()
val soapMessage = messageFactory.createMessage()
// (create envelope)
val headers = soapMessage.mimeHeaders
headers.setHeader("Content-Type", "application/soap+xml; charset=utf-8")
soapMessage.saveChanges()
val soapResponse = soapConnection.call(soapMessage, url)
soapConnection.close()
Debugging through, the content type appears to be set properly up to the soapConnection.call(). Any ideas?
You are creating a default MessageFactory:
val messageFactory = MessageFactory.newInstance()
As doc states this method
Creates a new MessageFactory object that is an instance of the default implementation (SOAP 1.1)
SOAP 1.2 message content type is "application/soap+xml", whereas SOAP 1.1 is "text/xml" (http://www.w3.org/TR/soap12-part0/#L4697).
Try to create a message factory instance providing the SOAP 1.2 as protocol
val messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL)
I'm attempting to make a SOAP request to an end point programmatically through Java. I'm relatively new to Java and web services so I'm not sure what I'm doing wrong here.
Also I print out the SOAP message and can paste that into a tool like postman and enter the end point and a post is successful. So i think something with my request is not correct here.
Here is my code:
System.out.println("hey now!!!!");
try {
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = scf.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage message = mf.createMessage();
SOAPBody body = message.getSOAPBody();
SOAPHeader header = message.getSOAPHeader();
SOAPElement getOpenPOs = body.addChildElement("GetOpenPOs", "", "https://www.autocrib.net");
SOAPElement U = getOpenPOs.addChildElement("U");
U.addTextNode("u");
SOAPElement P = getOpenPOs.addChildElement("P");
P.addTextNode("p");
SOAPElement N = getOpenPOs.addChildElement("N");
N.addTextNode("n");
SOAPElement Processed = getOpenPOs.addChildElement("Processed");
Processed.addTextNode("false");
SOAPElement StationEnd = getOpenPOs.addChildElement("StationEnd");
StationEnd.addTextNode("");
SOAPPart sp = message.getSOAPPart();
SOAPEnvelope envelope = sp.getEnvelope();
//MimeHeaders headers = message.getMimeHeaders();
//header.setHeader("Content-Type", "text/xml");
//message.getMimeHeaders().addHeader("SOAPAction", "GetOpenPOs");
message.getMimeHeaders().addHeader("Content-Type", "text/xml");
header.setAttribute("Content-Type", "text/xml");
message.saveChanges();
System.out.println("Envelope Body");
message.writeTo(System.out);
System.out.println();
SOAPMessage reply = connection.call(message,
"https://www24.autocrib.net/WebServices/AutoCribWS.asmx");
//String reply2 = connection.call(message, "https://www24.autocrib.net/WebServices/AutoCribWS.asmx").toString();
//sp = reply.getSOAPPart();
//envelope = sp.getEnvelope();
//body = envelope.getBody();
//System.out.println(body.toString());
System.out.println("Done!!!!!!!!!!!!!!!!!!!");
} catch (Throwable t) {
System.out.println("Something went wrong!!! " + t.toString());
}
}
I get this error when I run this code:
Oct 24, 2016 1:56:57 PM com.sun.xml.internal.messaging.saaj.soap.MessageImpl identifyContentType
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
Something went wrong!!! com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
I'm guessing I need to add the Content-Type header. Am I doing this incorrectly? Any guidance would be great.
Thanks,
Tim
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid
Content-Type:text/html.
The SAAJ API throws an exception because it considers that you web service returns as response text/html content instead of soap/xml content.
So, one advise : study the content returned by postman. Are you sure it is soap/xml format ? It you notice that is not soap/xml content, work on the implementation of your WS and if needed adapt the return to be compliant with the SOAP norm.
Wilco I would like to give you credit for the answer but I don't think I can do that for comments. Your tip helped me figure out that it was indeed returning text/html because of the user agent header I had.
THanks again!!
I'm trying to call a webservice which expects an array as parameter but I've no idea how to do that, I have no wsdl and I'd like to use javax to do that.
String operation = "TheOperationName";
String urn = "TheWebService";
String destination = "http://my-server/something.php";
// First create the connection
SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnFactory.createConnection();
// Next, create the actual message
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/");
// Create and populate the body
SOAPBody body = envelope.getBody();
// Create the main element and namespace
SOAPElement operationItem = body.addChildElement(
envelope.createQName(operation, "ns1"));
//Here I'm lost, I should create an array
param0 SOAP-ENC:arrayType="SOAP-ENC:Struct[1]" xsi:type="SOAP-ENC:Array"
which contains my items array
SOAPElement itemElement = myarray.addChildElement("item");
// Add parameters
itemElement.addChildElement("ID_Bug").addTextNode("ID");
itemElement.addChildElement("ID_Release").addTextNode("RELEASE");
// Save the message
message.saveChanges();
// Send the message and get the reply
SOAPMessage reply = connection.call(message, destination);
reply.toString();
// Close the connection
connection.close();
any suggestions on how to achieve that?
I am creating a Java client for a SOAP service that takes an attachment. I'm using java.xml.soap classes, which I have uses before, but not with attachments. The server claims that my attachment is not included.
I used SoapUI, which works, and wireshark to compare my SOAP message to a working SOAP message. One big difference is that my header does not include "start=".
The working Content-Type looks like this:
Content-Type: multipart/related; type="text/xml"; start=""; boundary="----=_Part_23_6341950.1286312374228"
The Content-Type I get from my Java code is like this:
Content-Type: multipart/related; type="text/xml"; boundary="----=_Part_23_6341950.1286312374228"
No start= even when the content ID is set on the root element. The working and failing SOAP messages are otherwise nearly identical. How can I get the start tag generated, or what are other reasons the server might not see the attachment?
Thanks
SOAPMessage soapMessage =
MessageFactory.newInstance().createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPBody body = soapEnvelope.getBody();
SOAPHeader header = soapMessage.getSOAPHeader();
soapPart.setContentId("<rootpart#here.com>");
MimeHeaders mimeHeaders = soapMessage.getMimeHeaders();
mimeHeaders.addHeader("SOAPAction", "addDocument");
mimeHeaders.addHeader("Accept-Encoding", "gzip,deflate");
Name bodyName = soapEnvelope.createName("Document", "doc",
"http://ns/Document");
SOAPBodyElement document = body.addBodyElement(bodyName);
Name filenameName = soapEnvelope.createName("Filename", "doc",
"http://ns/Document");
SOAPElement filename = document.addChildElement(filenameName);
filename.setValue("filename.txt");
AttachmentPart attachment = soapMessage.createAttachmentPart();
attachment.setContent("Some text", "application/octet-stream");
attachment.setMimeHeader("Content-Transfer-Encoding", "binary");
soapMessage.addAttachmentPart(attachment);
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = scf.createConnection();
URL url = new URL("http://host/Service");
SOAPMessage reply = soapConnection.call(soapMessage, url);
This works for me:
soapMessage.getMimeHeaders().setHeader("Content-Type",
soapMessage.getMimeHeaders().getHeader("Content-Type")[0]+
"; start=\"<rootpart#here.com>\"");