import org.tempuri.ServiceClient;
import org.tempuri.ServiceSoap;
import javax.xml.soap.*;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
public class WSTest {
/**
* @param args
* @throws SOAPException
* @throws UnsupportedOperationException
* @throws IOException
* @throws TransformerException
*/
public static void main(String[] args) throws UnsupportedOperationException, SOAPException, IOException, TransformerException {
// TODO Auto-generated method stub
test();
}
private static void test() throws UnsupportedOperationException, SOAPException, IOException, TransformerException
{
//TODO test TODO
FileInputStream fin = null;
try {
fin = new FileInputStream("d:\\login_top1.jpg");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = new File("d:\\login_top1.jpg");
byte[] content = new byte[(int)f.length()];
fin.read(content);
String scont = new sun.misc.BASE64Encoder().encode(content);
SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
SOAPConnection con = factory.createConnection();
URL url = new URL("http://localhost:2052/WebSite2/Service.asmx?WSDL");
SOAPMessage message = MessageFactory.newInstance().createMessage();
SOAPPart soap = message.getSOAPPart();
SOAPEnvelope envelope = soap.getEnvelope();
SOAPHeader soapHeader = envelope.getHeader();
//soapHeader.detachNode();
//soapHeader.setAttribute("POST", "/WebSite2/Service.asmx HTTP/1.1");
//soapHeader.setAttribute("Host", "localhost");
//soapHeader.setAttribute("Content-Type", "text/xml; charset=utf-8");
//soapHeader.setAttribute("SOAPAction", "http://tempuri.org/HelloWorld");
message.getMimeHeaders().addHeader("SOAPAction","http://tempuri.org/UploadFile");
SOAPBody body = envelope.getBody();
SOAPElement bodyElement =
body.addChildElement(envelope.createName("UploadFile" ,
"",
"http://tempuri.org/"));
//Add content
bodyElement.addChildElement("fileName").addTextNode("abccc.jpg");
bodyElement.addChildElement("file").addTextNode(scont);
//Add content
//bodyElement.addChildElement("isbn").addTextNode("0672324229");
//Save the message
message.saveChanges();
//Check the input
System.out.println("\\nREQUEST:\\n");
message.writeTo(System.out);
System.out.println();
/*
out.println("POST " + WebServicePath + " HTTP/1.1");
out.println("Host: localhost:80");
out.println("Content-Type: text/xml; charset=utf-8");
out.println("Content-Length: " + String.valueOf(length));
out.println("SOAPAction: \"" + SoapAction + "\"");
out.println("Connection: Close");
out.println();
*
*/
//soapHeader.setAttribute("Content-Type:", "text/xml; charset=utf-8");
SOAPMessage result = con.call(message, url);
//String sss = result.getSOAPPart().getContent().toString();
//System.out.print(sss);
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer =
transformerFactory.newTransformer();
Source sourceContent = result.getSOAPPart().getContent();
//Set the output for the transformation
StreamResult result1 = new StreamResult(System.out);
transformer.transform(sourceContent, result1);
System.out.println();
con.close();
}
}
The Java API for XML Messaging (JAXM) is a new Java application programming interface (API) that provides a standard way for Java applications to send and receive Simple Object Access Protocol (SOAP) messages. The basic idea is to allow developers to spend more time building, sending, receiving, and deconstructing messages for their applications and less time programming low-level XML communications routines. Developed through the Java Community Process, JAXM provides a simple yet flexible standard API for developing and deploying SOAP-based applications that can be truly interoperable with applications developed on other platforms. JAXM will be available as an optional package for the Java 2 platform, Standard Edition and may also be included in future releases of J2SE and Java 2, Enterprise Edition (J2EE).
JAXM is intended to be a messaging API for the development of XML-based business applications that occur primarily, although not exclusively, at the edge of organizations. The need for generating such messages is growing rapidly as corporations begin to do more business over the Internet. What's needed is the ability to communicate not only with a single hub or exchange that is driving the company's move towards e-commerce but with a wide range of business partners. While some hubs such as Wal-Mart and Home Depot have created their own e-commerce standards, the industry as a whole seems to be moving toward the development of industry-wide standards that will expedite e-business interoperability.
SOAP, one of the most important of these new standards, addresses critical transport and packaging issues. SOAP can be thought of as a successor to the XML-RPC standard in that it provides an RPC transport mechanism for XML over HTTP. As stated in the W3C SOAP 1.1 draft: "SOAP is a lightweight protocol, for exchange of information in a decentralized, distributed environment." The SOAP protocol has three parts: an envelope that defines a framework for describing what is in a message and how to process it, a set of encoding rules for expressing instances of application-defined datatypes, and a convention for representing remote procedure calls and responses. SOAP has received considerable acceptance in the industry as the de facto way of exchanging data between applications in an interoperable fashion.
Lightweight but Adaptable to More Complex Protocols
The minimum requirement to support JAXM is to be able to use a simple set of APIs for sending, receiving, and parsing of SOAP messages. The on-the-wire protocol of a JAXM message is vanilla SOAP over HTTP. Hence a JAXM-enabled application may communicate with any other application that knows how to speak SOAP - including those built on platforms that have nothing to do with Java, such as Microsoft's BizTalk server.
In an all-Java environment the simplest deployment configuration would be to use the Sun reference implementation (RI) as the JAXM "provider." The sending client uses the JAXM APIs to send a SOAP message over HTTP. The receiving client is registered as a servlet, as illustrated in Figure 1.
While the base architecture of JAXM is very simple, it can be extended to work in a more complex messaging infrastructure such as ebXML through the notion of a base "profile." A JAXM profile is an extension to the JAXM specification that allows a JAXM implementation to take on a certain predefined personality. For example, an ebXML profile would cause a JAXM MessageFactory object to create an ebXML SOAPMessage object instead of a vanilla SOAPMessage object.
The SOAP Packaging
JAXM is based on the SOAP 1.1 and SOAP with Attachments specifications. JAXM offers two different packaging models for SOAP messages, one that includes attachments and one that does not. The SOAPMessage class is the root class for all SOAP messages. If the SOAP message includes AttachmentPart objects, then the message is encoded as a MIME message. A message that contains attachments must have a MIME envelope which contains both the SOAP part of the message and the MIME attachment. All JAXM clients must be capable of reading SOAP 1.1 messages with attachments.
Creating and Sending Messages
The example below shows how JAXM uses a ProviderConnectionFactory object to create a connection with a messaging provider. The same object can be used later to send the message. The first two lines use the JNDI API to retrieve the appropriate ProviderConnectionFactory object from the naming service where it was registered with MyExchange. This logical name is passed as an argument, then the method lookup returns the ProviderConnectionFactory object that the logical name was bound to. The returned value must be narrowed to a ProviderConnectionFactory object in order to use it to make the connection. A JAXM method is invoked to actually start the connection instance connect1 in the final line of the code.
Context ctx = getInitialContext ();
ProviderConnectionFactory cf =
(ProviderConnectionFactory)ctx.lookup("MyExchange");
ProviderConnection connect1 =cf.createConnection();
The MessageFactory class is used to create SOAPMessage objects. A JAXM client may create a new instance of the MessageFactory object for request response messaging using the SOAPConnection newInstance method. On the other hand, when one-way asynchronous messaging is required, the createMessageFactory method of the ProviderConnection object must be used. The following example shows how MessageFactory objects are used to create SOAPMessage objects.
MessageFactory MessageFactory1 =
connect1.createMessageFactory() SOAPMessage transact1 =
MessageFactory1.createMessage();
JAXM Profiles
It's important to note that SOAP specifies that messages will contain the necessary addressing information but does not define a standard way for this information to be represented within a message. For that reason, JAXM relies on industry-standard usages of SOAP, called profiles, for interoperable addressing conventions. For example, the profile may stipulate the specifications of the SOAP header, such as the sender, recipient, message ID and correlation information. The way in which this information is mapped onto a given message is defined by the Profile String. Profiles represent a usage of SOAP by a particular standards group or industry. The getSupportedProfiles()method retrieves a list of the messaging profiles that are supported by the messaging provider to which the ProviderConnection object is connected. For example, ebXML or BizTalk profiles can be built on top of SOAP messaging. ebXML is an emerging standard based on the vision of creating a single global electronic marketplace where companies of any size and geographical location can meet and conduct business through the exchange of XML messages. SOAP is integrated into the ebXML messaging specification in order to provide the underpinnings for its messaging requirements.
When profiles are being used, an application may not need to specify an address when it sends a message because destination information will be contained in the profile-specific header. If profiles are not used, destinations are specified with an Endpoint object that represents the mapping of a logical name, such as a URI, to a physical location, such as a URL. Typically, an Endpoint object represents a business entity but it may represent a destination of any sort. Conceptually, an Endpoint object is the mapping of a logical name, such as a URI, to a physical location, such as a URL.
In the example above, the method MessageFactory was given no argument so it returned the transact1 object that produces messages using the basic SOAP profile. The code example below shows how to create a MessageFactory object that supports a particular profile. Message objects produced by such a message factory are specific to the named profile. In order to assure interoperability, much scrutiny must be given to the development of profiles.
MessageFactory messagefactory2 =
connect1.createMessageFactory (<profile1>); SOAPMessage
transact2 = messagefactory2.createMessage();
Multipart Messages
The next step is adding content to the message. SOAP messages are designed to send XML documents in the body of the message. But if the message is to include anything that is not an XML document, then it must have an attachment part. The packaging model for a message without attachments is much simpler, consisting only of a message package with an envelope containing a header and body. A SOAP message with attachments adds the concept of a SOAP part that contains an envelope similar to the one described above. In addition, the message can contain multiple attachment parts that along with the SOAP part are contained in a MIME envelope. There may be any number of attachments and they can contain any type of file.
The following example demonstrates how to build the body of the message. The SOAPMessage contains the SOAPPart, which in turn is used to obtain the SOAPEnvelope. The SOAPEnvelope is then used to obtain the body of the message.
SOAPpart spart = transact2.getSOAPPart ();SOAPEnvelope envelope = spart.getEnvelope ();
SOAPBody sbody = envelope.getBody();
Once the message body is obtained, the SOAPBody.addBodyElement() and SOAPBodyElement.addChildElement() methods are used to create any level of nested elements within the SOAP body, as illustrated in the following code:
SOAPBodyElement gltp
= sbody.addBodyElement (envelope.createName
("GetLastTradePrice", "ztrade", "http://wombat.ztrade.com"));gltp.addChildElement (envelope.createName ("symbol",
"ztrade", "http://wombat.ztrade.com")).addTextNode ("PRGS");
The following code shows how to create an attachment part. In this example, the content is an image in a GIF file whose url is used to initialize the javax.activation.DataHandler object data handler1. The SOAPMessage object message1 creates the AttachmentPart object attachmentpar1t which is initialized with the data handler containing the url for the image. Finally, attachmentpar1t is added to the message.
URL url = new URL("http://main/picture.gif");
DataHandler datahandler1 = new DataHandler(url);
AttachmentPart attachmentpart1 =
message1.createAttachmentPart(datahandler1);
message1.addAttachmentPart(attachmentpart1);
The last step to be covered here is sending the message using a Provider Connection object which, as described earlier, is a connection to a messaging provider. If asynchronous messaging is being done in the context of a container, such as a servlet or J2EE container, the send method is used. The send method sends the given SOAPMessage object and returns immediately after handing the message over to the messaging provider. No assumptions are made regarding the ultimate success or failure of message delivery at the time this method returns. The ProviderConnection send method requires one parameter, the SOAPMessage object that's being sent.
SOAPMessage reply = connect1.send(transact1);
The call method on the SOAPConnection object is used to send a synchronous message. The call method will block until a SOAPMessage object is received. A JAXM application may use the call method to implement the client side of a simple point-to-point synchronous one-way message exchange. Two parameters are required for the call method, the SOAPMessage object that is being sent and the Endpoint object representing the destination. For point-to-point plain SOAP messaging, where no profile is used, an application must supply an Endpoint object to the call method to indicate the intended destination of the message. The default identification for an Endpoint object is a URI. At a minimum, this is what JAXM messaging providers are required to support to identify a destination. Endpoint objects can be created using the constructor, or they can be looked up in a naming scheme. The Endpoint subclass URLEndpoint can be used to send a message directly to a remote party without using a messaging provider.
The following code example creates an Endpoint object called endpoint1 from a URL for the intended recipient and passes it along with the SOAPMessage object message1 to the SOAPConnection call method, creating a synchronous transmission.
Endpoint endpoint1 = new Endpoint ("http://myexchange.com/transactions"); con.call(message1, endpoint1);
The JAXM 'Provider'
In lieu of actually supplying the more detailed profiles, the base API is very light on "Messaging" and heavy on SOAP content. The majority of the API is built around how to construct and deconstruct SOAP messages. However, there is much allusion to the JAXM "provider" woven throughout the specification.
In distributed application communications among enterprises and across business entities, the use of SOAP over vanilla HTTP just doesn't cut it. Parties are often unreachable, yet reliability of communications is crucial. This gap may be filled in the future by more powerful JAXM messaging providers based on protocols, such as JMS, that provide a simple, robust way of addressing these issues. The JMS specification offers a robust messaging model that supports a variety of asynchronous and synchronous communication mechanisms.
JMS comprises an API and semantics for a middleware messaging system that helps insulate the application from the issues posed by loosely coupled systems by providing services, such as persistence, verification, and transaction support. It has all the semantics of failure scenarios built in via a loosely coupled disconnected operation, persistent messaging, internal acknowledgment of message receipt and rules of engagement regarding transactional recovery and message redelivery. The very minimum required for the two technologies (JAXM and JMS) to work together is the ability for a JMS provider to be able to bridge to SOAP/ HTTP.
By providing a standard way to send messages over the Internet from the Java platform, JAXM is almost guaranteed a successful launch. This new standard will provide a major impetus to the creation of many-to-many B2B e-commerce applications using industry standard technology. Perhaps the most important feature of JAXM is its extensibility - its messaging provider and profile concepts will allow it to easily support new interoperability concepts in the future.