| Join wMUsers | Blog at wMUsers | User Control Panel | Site Map | webMethods Jobs |For Employers |
![]() |
![]() |
IntroductionIgor Androsov discussed Content Handlers in a previous webMethods Ezine article. They do come into play with legacy systems integrations or integrations with systems that rely on other non-standard data formats. This article will demonstrate how to use the webMethods API and Java stream filters to introduce these non-standard documents to Trading Networks. Defining the ProblemTrading Networks is designed to manage XML documents. When a partner is not able to post XML documents to Trading Networks, however, a workaround must be found. This simple (and frequently encountered) business problem will be the basis of this webMethods Ezine article. Extending the read() MethodA common thought is to transform the inbound text-based flat file document to XML using a webMethods service and then push the document to Trading Networks. This approach -- although an alternative -- is not always advisable because it may introduce extraneous parsing. It also bypasses the inherent strengths and features built-in to the webMethods platform. For example, if a large flat file is first parsed to its XML representation and then posted to Trading Networks, the large document handling features of TN may not be utilized. Additionally, it may not be always possible to create a document node in a service since there are memory constraints that limit the A content handler becomes essential in such scenarios. Typically, a content handler would read the data from the input stream, parse it and convert it into either a node or a Record. The drawback in such a solution is that it is constrained by the memory resources on the system unless a more robust approach is applied, such as disk-swapping. An alternative that does not have these constraints build on the fact that the webMethods ContentHandler interface uses a java.io.InputStream object to read the contents of the document. We can extend the InputStream class to implement the read() method. Our overridden read() method performs data conversion in a sequential parse mode and we achieve transparent data conversion. Solving the ProblemLet's assume that the partner's text flat file contains employee records that needs to be used to update a backend system. The flat file's records are comma-delimited with the following format: Name, ID, SSN, Location, Manager, UpdateType Our goal is to convert this Employee Update record to a XML document. The XML document is represented as: <EmployeeUpdates>
<Employee>
<Name></Name>
<ID></ID>
<SSN></SSN>
<Location></Location>
<Manager></Manager>
<UpdateType></UpdateType>
</Employee>
</EmployeeUpdates>
We should also assume the following:
To achieve this goal, all that must be done is to create a content handler and implement the getInputValues method as: public Values getInputValues(InputStream is, InvokeState state)
throws IOException
{
String contentType = getContentType();
int index = contentType.lastIndexOf("/");
if (index > 0)
{
docType = contentType.substring(index+1);
}
XMLWrapperInputStream xmlStream
= new XMLWrapperInputStream(is, docType);
return ServerAPI.getContentHandler("text/xml")
.getInputValues(xmlStream, state);
}
This implementation is only slightly different from the webMethods default XML content handler. Instead of using a conversion mechanism that reads data and converts it into a document node or a record structure, the input stream is wrapped in an extended class of the java.io.InputStream, called XMLWrapperInputStream. And then this stream is used to feed the default XML Handler that is built into the webmethods Integration Server. The default content handler needs the input stream to provide an XML stream. Thanks to the strength of the java.io.InputStream, filtering an InputStream to a XMLInputStream is easier than it seems. It can be done by creating a class named XMLWrapperInputStream which would extend java.io.InputStream. The core of the class would be the constructor and the read() method. import java.io.*;
import java.util.*;
public class XMLWrapperInputStream extends InputStream
{
// A few housekeeping and state variables
private String docType;
private String xmlHeader = "<?xml version=\"1.0\" ?>";
private BufferedReader reader;
private boolean eof = false;
private String nodeName = "Employee";
byte[] buffer = new byte[1024];
private String[] fieldnames = new String[]
{"Name", "ID",
"SSN", "Location",
"Manager", "UpdateType"};
private String newLine = System.getProperty("line.separator");
private int pos = 0;
//Constructor
public XMLWrapperInputStream(InputStream stream, String docType)
{
this.docType = docType;
buffer = (xmlHeader + newLine + "<" + docType + ">").getBytes();
this.reader = new BufferedReader(new InputStreamReader(stream));
}
Go Deeper on the Subject: The wMUsers Discussion Forums Rupinder Singh has been working in the IT arena for about 10 years with experience in real-time defense systems, SGML parsers and application integration. He has worked on several integration projects in various roles using webMethods and J2EE application servers.
Rupinder is a consultant for Atos Origin and can be reached via email at |
| © All Rights Reserved, 2001-2008. |