Thursday, August 7, 2014

SOAP With Attachment with Java, working example

This code actually works , and produces a SOAM message with attachment of type application/octet-stream - which is totally acceptable, even if I would have preferred application/pdf.


import javax.xml.soap.*;
import java.net.URL;
import java.io.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import javax.activation.*;


// now all the SOAP code
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader header = envelope.getHeader();

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder builder = dbFactory.newDocumentBuilder();
// add the SOAP body as from text
StringReader sr = new StringReader(textToSend);
InputSource is = new InputSource(sr);
Document document = builder.parse(is);
SOAPBody body = envelope.getBody();
SOAPBodyElement docElement = body.addDocument(document);
// add attachment from file          

String filename = theBUSINESSIDVALUE.split("\\^")[0];
File fileAttachment = new File(rootFolderForMSS + filename + ".pdf");
FileDataSource fds = new FileDataSource(fileAttachment);
DataHandler dh = new DataHandler(fds);
out.write("content-type=" + dh.getContentType() + "
"); AttachmentPart attachment = message.createAttachmentPart(dh); String contentId = "<" + filename + ".pdf>"; attachment.setContentId(contentId); message.addAttachmentPart(attachment); SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection connection = soapConnectionFactory.createConnection(); java.net.URL endpoint = new URL(POSTTOURL); SOAPMessage soapResponse = connection.call(message, endpoint);


I had tried this one before:

AttachmentPart attachment = message.createAttachmentPart();

String filename = theBUSINESSIDVALUE.split("\\^")[0];
File fileAttachment = new File(rootFolderForMSS + filename + ".pdf");
byte[] fileData = new byte[(int) fileAttachment.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(fileAttachment));
dis.readFully(fileData);
dis.close();
  
String contentId = "<" + filename + ".pdf>";
attachment.setContent(new ByteArrayInputStream(fileData), "application/pdf");
attachment.setContentId(contentId);
message.addAttachmentPart(attachment);


but it was failing with this error
 javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/pdf
        at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:877)
        at javax.activation.DataHandler.writeTo(DataHandler.java:302)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:874)
        at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:444)
        at weblogic.xml.saaj.SOAPMessageImpl.writeMimeMessage(SOAPMessageImpl.java:959)
        at weblogic.xml.saaj.SOAPMessageImpl.writeTo(SOAPMessageImpl.java:832)
        at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:237)
        at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:144)



For more info see:

http://docs.oracle.com/javaee/5/tutorial/doc/bnbhr.html
http://docs.oracle.com/javase/6/docs/api/javax/activation/FileDataSource.html
http://docs.oracle.com/javase/6/docs/api/javax/activation/DataHandler.html


I would rather say that it could be all a LOT simpler.... Java Java...too verbose...

Wednesday, August 6, 2014

Java SOAP with Attachment in WebLogic

This is some code which more or less works:

import javax.xml.soap.*;
import java.net.URL;

String POSTTOURL = "http://yourhost:yourport/yourservice";

MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();
...
set the body content here
...
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConnectionFactory.createConnection();
java.net.URL endpoint = new URL(POSTTOURL);
SOAPMessage soapResponse = connection.call(message, endpoint);
out.write("soapResponse=" + soapResponse.getSOAPBody().toString());


The above code without any "body content" will generate this:
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"/>"
 operation="null"
 attachments="<con:attachments xmlns:con="http://www.bea.com/wli/sb/context"/>"
 outbound="null"
 fault="null"
 inbound="<con:endpoint name="BLA" xmlns:con="http://www.bea.com/wli/sb/context">
  <con:service/>
  <con:transport/>
  <con:security/>
</con:endpoint>"
 header="<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"/>




I got this error message:
This class does not support SAAJ 1.1

Adding this in the setDomainEnv.sh for JAVA_OPTIONS seems to fix it:
-Djavax.xml.soap.MessageFactory=weblogic.xml.saaj.MessageFactoryImpl


See also document "Receive the Error "This Class Does Not Support SAAJ 1.1" when Running a P6 Web Services Application (Doc ID 1297252.1)" where they recommend:
JAVA_OPTIONS="${SAVE_JAVA_OPTIONS} 
-Djavax.xml.soap.MessageFactory=com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl 
-Djavax.xml.soap.SOAPConnectionFactory=weblogic.wsee.saaj.SOAPConnectionFactoryImpl"




Tuesday, August 5, 2014

stakeholders



this is becoming a popular term in IT.... let's see what Google says...

stake1
stāk/
noun
noun: stake; plural noun: stakes; noun: the stake
  1. 1.
a strong wooden or metal post with a point at one end, driven into the ground to support a tree, form part of a fence, act as a boundary mark, etc.


  1. 2.
historical
a wooden post to which a person was tied before being burned alive as a punishment.