Wednesday, July 25, 2012

BeanFace WebService - Dynamic Class Invocation Example

1.BeanFace Web Service Server Side
In this example, we will use BeanFace Object for the Web Service called BeanFaceWebServiceTransform.java
1.1 Open com.wwlee.beanface.webservice.server.BeanFaceWebServiceServer.java file.
Modify the codes to point BeanFaceWebServiceDynamicTransformationjava.

1.2 Review BeanFaceWebServiceDynamicTransformation.java code.
- This java class contains a couple of important features such as properties file, dynamic class invocation based on soapAction information.

- When initialize() method will be called, it will only once load properties file information to memory.

private void loadPropertyFile(boolean isInitialized) throws BeanFaceException {
        beanFaceWebServiceServerRouter = new BeanFaceWebServiceServerRouter(propertyFileName);
        if (isInitialized) {
            System.out.println("++++ Property File Was Intialized. " + beanFaceWebServiceServerRouter.getPropertyFileNameFullPath());
        } else {
            System.out.println("++++ Property File Was Re-Intialized. " + beanFaceWebServiceServerRouter.getPropertyFileNameFullPath());
        }
    }

- Once processRequest() method is called, it will invoke handleRequest() method which dynamically invoke the actual transformation class.

private void handleRequest(HttpServletRequest request, HttpServletResponse response) throws BeanFaceException, IOException {
        beanFaceWebServiceInfo = new BeanFaceWebServiceInfo(request, response);
        if (reloadProperties(request)) {
            int length = defaultSOAPEnvelope.createResponseForReload(response.getOutputStream());
            sendResponseCommon(response, HttpServletResponse.SC_OK, length);
            return;
        }
        System.out.println("+++++ SOAP Action : " + beanFaceWebServiceInfo.getSOAPAction() + " +++++");
        String routing = beanFaceWebServiceInfo.getSOAPRoutingInfo();
        System.out.println("+++++ SOAP Routing Info : " + routing + " +++++");
        /* Depending on getSOAPRoutingInfo(), you can dynamically call the implementation Class */
        WebServiceTransformation transformation = beanFaceWebServiceServerRouter.getInstance(routing);
        System.out.println("+++++ Dynamically Found Transformation Object : " + beanFaceWebServiceServerRouter.getDynamicInstanceName() + " +++++");
        transformation.setBeanFaceWebServiceInfo(beanFaceWebServiceInfo);
        transformation.receive();
        transformation.transform();
        int length = transformation.reply();
        sendResponseCommon(response, HttpServletResponse.SC_OK, length);
    }

When client will send SOAP with soapAction value '"http://bfws.wwlee.com/DynamicTransformation", this routing value will be 'DynamicTransformation'. When  beanFaceWebServiceServerRouter.getInstance(routing) is called, it will lookup the properties value and return 'com.wwlee.beanface.webservice.transform.example.DynamicTransformation' object instance which is actual WebServiceTransformation implementation class.


1.3. com.wwlee.beanface.webservice.server.impl.example.DynamicTransformation Class
- It extends abstract WebServiceTransformation class, which needs to implement receive(), reply(), and transform() method. 
- This class generates the exactly same results as we have seen in the previous example with  BeanFaceWebServiceTransform class. 

Build and Deploy the Server Program.


2.BeanFace Web Client Server Side called com.wwlee.beanface.webservice.examples.BeanFaceWebServiceClientDynamicTransformation
- This example are the exactly same as BeanFaceWebServiceClientTransformation which we used in the previous example. Only the different one is soapAction value, which is "http://bfws.wwlee.com/DynamicTransformation". 'DynamicTransformation' in soapAction will be used for dynamic class invocation in the server side.

Let's execute this program with countLooping = 10. If you have an issue, do troubleshoot. I think most of cases are related with properties information.

In the second try, let's use countLooping=1500000 (1.5 Million records) and execute it.
My glassfish heap size configuration is '-Xms512m -Xmx512m'. If you have 'OutOfMemoryError' in client side, you need to increase jvm heap size.
Here is my result.

SOAPAction,http://bfws.wwlee.com/DynamicTransformation
Invoking Time : 39172
Response : <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/">
    <ns2:Header>
        <ns3:bfwsHeader xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsHeader">Response Header</ns3:bfwsHeader>
    </ns2:Header>
    <ns2:Body>
        <ns3:bfwsResponse xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsResponse">ReceivedTotalCount[1500000],BodySize[60388896 bytes],Process Time[38624], LastEmployeeName[Emp1500000]</ns3:bfwsResponse>
    </ns2:Body>
</ns2:Envelope>

The Server side will calculate how many records are there, what the soap body size is, and how long it take to process. See the fantastic performance which just took '42 seconds' with soap body size 60M bytes. If you convert this message to xml format, it will be about 10 times bigger.

Combined with other technlogies such as Message Driven Bean, EJB, SOA, this BeanFace API will give huge benefits for your application integration. I am in the middle of JCAPS migration processes to other SOA tool. If you use Oracle SOA, the BeanFace API will be used in Spring Component. 


My next plan for BeanFace extension will be including SAAJ(SOAP with Attachments API) in the near features. If you register my future blog, you will get the new BeanFace API features.
If you have any question or feedback, you can post this blog or send email to me with wwlee0825@gmail.com.

Wonwoo

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

BeanFace WebService - Dynamic Class Invocation

Before we go further, I will cover a couple of important things for the dynamic class invocation in BeanFace Web Service.

1. com.wwlee.utils.DynamicClassInstanceInvocation Class in BeanFace.jar file   
    public Object getInstance(String objectKey) throws BeanFaceException
  - This utility class returns Java Object instance based on objectKey. The information should be defined in the properties file as the key and value format. 


2. Property File for DynamicClassInstanceInvocation 
This properties file contains the Business Logic Transformation Implementation java information. The format will be like the below sample with key=value pair.
DynamicTransformation=com.wwlee.beanface.webservice.transform.example.DynamicTransformation
key can be any meaningful string. In the example, I use key as part of soapAction value.
value will be the actual implementation java class name with full package.

Where to place the property file?

 There are two simple ways to place this property files.
One is to find where the current directory location is. Use the following example to find it.
File file = new File(".");
System.out.println("Current Directory Location Full Path : " + file.getAbsolutePath());
--> For the glassfish server, this path is '~/appserver/domains/$DomainName/config'. Depending on your runtime sever, this value will be different.
In this example, I created BeanFaceProperties directory under config directory and placed DynamicTransformationInvocation.properties file which is in com.wwlee.beanface.webservice.transform.example package.
The second way is just to provide absolute property file name path, just like '/a/b/c/BeanFaceProperties/DynamicTransformationInvocation.properties'.

If you want to change this property file location, open 'BeanFaceWebServiceDynamicTransformation.java' in  com.wwlee.beanface.webservice.server.impl.example package, and change it.

3. Abstract Class : com.wwlee.beanface.webservice.server.WebServiceTransformation
    public abstract void receive() throws BeanFaceException;
    public abstract int reply() throws BeanFaceException;
    public abstract void transform() throws BeanFaceException;
-Every actual implementation class for Dynamic Invocation, need to implement these three methods.
In our examples, DynamicTransformation.java in com.wwlee.beanface.webservice.transform.example package has the sample. I think if you want to add more implmentation classes, just modify transform() method based on your requirement.

4. com.wwlee.beanface.webservice.server.impl.example.BeanFaceWebServiceServerRouter
   public WebServiceTransformation getInstance(String objectKey) throws BeanFaceException 
- This class extends DynamicClassInstanceInvocation  class and return actual implemented transformation class instance which implements WebServiceTransformation class instance.

5.com.wwlee.beanface.webservice.server.BeanFaceWebServiceInfo Class in BeanFace.jar file
- This class provides all of convenient methods to get or set request and response SOAP message. 


In the next blog, I will cover the actual sample to utilize the above concepts including Dynamic Class Instance Invocation and properties file. 


To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

BeanFace WebService - Transformation Example

1.BeanFace Web Service Server Side
In this example, we will use BeanFace Object for the Web Service called BeanFaceWebServiceTransform.java
1. Open com.wwlee.beanface.webservice.server.BeanFaceWebServiceServer.java file. 
Modify the codes to point BeanFaceWebServiceTransform java.

2. Review the  BeanFaceWebServiceTransform .java code. 
This program will use BeanFaceSampleDelimited which has ',' delimiter. You already created this java file in the previous blogs. I will use the same file. Let's see the transform() method.

private void transform(HttpServletResponse response) throws BeanFaceException, IOException {
        Envelope requestEnvelope = beanFaceWebServiceInfo.getRequestEnvelope();
        beanFaceWSSOAP.setEnvelope(requestEnvelope);
        int bodyLength = beanFaceWSSOAP.getBodyValueLength();
        ReadLineUtil readLineUtil = new ReadLineUtil();
        readLineUtil.setMessage(beanFaceWSSOAP.getBodyValue());
        String record = "";
        int count = 0;
        BeanFaceSampleDelimited beanFace = new BeanFaceSampleDelimited();
        while ((record = readLineUtil.readLine()) != null) {
            beanFace.unmarshalFromString(record);
            count++;
        }
        readLineUtil.close();
        /* Prepare Response SOAP Message */
        String responseHeaderMessage = "Response Header";
        String responseBodyMessage = "ReceivedTotalCount[" + count + "],BodySize[" + bodyLength + " bytes], Process Time[" + TimeUtil.getElapsedTime(inTime, TimeUtil.getDateTime()) + "], LastEmployeeName[" + beanFace.getEmployeeName() + "]";
        int length = defaultSOAPEnvelope.createResponse(response.getOutputStream(), responseHeaderMessage, responseBodyMessage);
        sendResponseCommon(response, HttpServletResponse.SC_OK, length);
    }

Like BufferedReader Class, ReadLineUtil Class provide readLine() method. You can do unmarshallFromString() and do actual transformation based on your requirement.

Build and Deploy the Server Program.

2.BeanFace Web Client Server Side called com.wwlee.beanface.webservice.examples.BeanFaceWebServiceClientTransformation

public String transformForBody(int count) throws BeanFaceException {
        String employeeName = "Emp";
        String departmentName = "IT Dept";
        String companyName = "Bean Face Company";
        String countryCode = "123";
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 1; i <= count; i++) {
            beanFaceSampleDelimited.setEmployeeName(employeeName + i);
            beanFaceSampleDelimited.setDepartmentName(departmentName);
            beanFaceSampleDelimited.setCompanyName(companyName);
            beanFaceSampleDelimited.setCountryCode(countryCode);
            stringBuffer.append(beanFaceSampleDelimited.marshalToString() + "\n");
        }
        return stringBuffer.toString();
    }
This method will create actual transformed messages based on ',' delimiter and this message will be used in the soap body message. Let's execute the main() method with the count 100 and the response will be.

SOAPAction,http://bfws.wwlee.com/BeanFaceWebServiceTransformation
Invoking Time : 140
Response : <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/">
    <ns2:Header>
        <ns3:bfwsHeader xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsHeader">Response Header</ns3:bfwsHeader>
    </ns2:Header>
    <ns2:Body>
        <ns3:bfwsResponse xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsResponse">ReceivedTotalCount[100],BodySize[3592 bytes], Process Time[89], LastEmployeeName[Emp100]</ns3:bfwsResponse>
    </ns2:Body>
</ns2:Envelope>

Through the response SOAP message, you can see how many messages were processed and how long it took to process.

Next example will be the highlight of BeanFace Web Service.

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

BeanFace Web Service - Simple Example

1.BeanFace Web Service Server Side
If you don't copy the example java files, you need to extract 'BeanFaceWebServiceServer.zip' file and copy them into BeanFaceWebServiceServer project which contains servlet program called 'BeanFaceWebServiceServer.java'.

Let's start Web Service Server Template program called 'BeanFaceWebServiceServer.java'.
1. Open com.wwlee.beanface.webservice.server.BeanFaceWebServiceServer.java file. 
2. Import the following two lines. 
    import com.wwlee.beanface.webservice.server.impl.example.*;
    import com.wwlee.beanface.exception.BeanFaceException;
3. Modify the codes as the followings.
    private BeanFaceWebServiceSimple beanFaceWebService;
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        beanFaceWebService.processRequest(request, response);
    }
    public void init() throws ServletException {
        try {
            beanFaceWebService = new BeanFaceWebServiceSimple();
        } catch (BeanFaceException ex) {
            throw new ServletException(ex);
        }
    }
4. Review the BeanFaceWebServiceSimple.java code. 
In processRequest() method, it called handleRequest() method.

    private void handleRequest(HttpServletRequest request, HttpServletResponse response) throws BeanFaceException, IOException {

        beanFaceWebServiceInfo = new BeanFaceWebServiceInfo(request, response);

        System.out.println("SOAP Action : " + beanFaceWebServiceInfo.getSOAPAction());
        String routing = beanFaceWebServiceInfo.getSOAPRoutingInfo();
        System.out.println("SOAP Routing Info : " + routing);
        transform(response);
    }
transform() method will create response message and reply back to Web Service Client.
Response SOAP message doesn't have Header. Body contents will be "Response Body Message for Simple".

    private void transform(HttpServletResponse response) throws BeanFaceException, IOException {
        System.out.println("Input Message : " + beanFaceWebServiceInfo.getReqestXMLString());
        int length = defaultSOAPEnvelope.createResponse(response.getOutputStream(), "Response Body Message for Simple");
        sendResponseCommon(response, HttpServletResponse.SC_OK, length);
    }

Build and Deploy the Server Program.

2.BeanFace Web Client Server Side called com.wwlee.beanface.webservice.examples.BeanFaceWebServiceClientSimple

public byte[] invokeWebService(Object soap, String endpointURL, String soapAction, int timeoutSeconds) throws BeanFaceException {
        BeanFaceWebService webservice = new BeanFaceWebServiceJAXB();
        if (soap instanceof Envelope) {
            webservice.setRequestMessage((Envelope) soap, soapAction);
        } else if (soap instanceof File) {
            try {
                webservice.setRequestMessage(new FileInputStream((File) soap), soapAction);
            } catch (FileNotFoundException ex) {
                throw new BeanFaceException(ex);
            }
        }
        webservice.invoke(endpointURL, timeoutSeconds);
        byte responses[] = webservice.getResponseBytesXML();
        System.out.println("Invoking Time : " + webservice.getElapsedInvokingTime());
        return responses;
    }

    public Envelope createSOAPEvelope(String headerMessage, String bodyMessage) throws BeanFaceException {
        Envelope envelope = beanFaceWSSOAPFactory.createEnvelope();
        beanFaceWSSOAP.setEnvelope(envelope);
        if (!StringUtil.isNullOrEmpty(headerMessage)) {
            beanFaceWSSOAP.setHeader(headerMessage);
        }
        beanFaceWSSOAP.setRequestBody(bodyMessage);
        return envelope;
    }

    public static void main(String[] argv) throws Exception {
        String headerMessage = "Simple Bean Face Web Service Message";
        String bodyMessage = "EmployeeName,DepartmentName,CompanyName,CountryCode";
        String endpointURL = "http://localhost:18001/BeanFaceWebService/";
        String soapAction = "http://bfws.wwlee.com/BeanFaceWebServiceSimple";
        int timeoutSeconds = 30;
        BeanFaceWebServiceClientSimple beanFaceWebServiceClientSimple = new BeanFaceWebServiceClientSimple();
        Envelope envelope = beanFaceWebServiceClientSimple.createSOAPEvelope(headerMessage, bodyMessage);
        byte responses[] = beanFaceWebServiceClientSimple.invokeWebService(envelope, endpointURL, soapAction, timeoutSeconds);
        System.out.println("Response : " + new String(responses));
    }

In general, soapAction information is used for 'Operation'. In BeanFace Web Service, it will be used for Routing. You will see this example in Dynamic Transformation Invocation.

Execute this program and you will get the following response from server side. The result is.

Invoking Time : 63
Response : <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/">
    <ns2:Body>
        <ns3:bfwsResponse xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsResponse">Response Body Message for Simple</ns3:bfwsResponse>
    </ns2:Body>
</ns2:Envelope>

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

BeanFace Web Service Server Template

To test BeanFace Web Service, you need Web Service client and server.
In this blog, I will mainly cover how to create BeanFace Web Service Server Templates.
Later on, you will see how this simple single template can extend Web Service Server to dynamically transform any interface messages through "Dynamic Transformation Invocation".

I use Netbean and glassfish for Servlet container. If you use any other Java UI and container, you need to slightly change the configuration.

Create Project call 'BeanFaceWebServiceServer'
1. Create New Project --> Java Web --> Web Application
2. Provide Project Name and its Location. As a project name, use 'BeanFaceWebServiceServer'
3. Choose J2EE container and provide name for 'Context Path'
    I select 'GlassFish' and as a context path, use '/BeanFaceWebService'
4. Finish

Create Servlet call 'BeanFaceWebServiceServer'
In Source Package, right click and choose 'Servlet'. Class Name will be 'BeanFaceWebServiceServer' and  package name is 'com.wwlee.beanface.webservice.server'. It will create BeanFaceWebServiceServer.java file.

Configure web.xml file. 
Instead of index.jsp in welcome-file element, use BeanFaceWebServiceServer.
Now your web.xml file will be similar with the following.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>BeanFaceWebServiceServer</servlet-name>
        <servlet-class>com.wwlee.beanface.webservice.server.BeanFaceWebServiceServer</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>BeanFaceWebServiceServer</servlet-name>
        <url-pattern>/BeanFaceWebServiceServer</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
    <welcome-file-list>
        <!--<welcome-file>index.jsp</welcome-file>-->
        <welcome-file>BeanFaceWebServiceServer</welcome-file>
    </welcome-file-list>
</web-app>

Now you are ready to have the template for BeanFace Web Service Server. 
Let's test the servlet program after adding the following lines in processRequest() method. 

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String defaultDirectory = ".";
            File file = new File(defaultDirectory);
            System.out.println("+++++ Absolute File Path for Default Directory : " + file.getAbsoluteFile());
        } finally { 
            out.close();
        }
    }

After deploying it, you can simply test through your browser. 
http://localhost:18001/BeanFaceWebService/
And check your log file to see the following message "++++++ Absolute File Path for Default Directory .....". If you cannot see it, troubleshoot your self. 

Next couple of blogs, you will see how to use BeanFace Web Service in Server and Client modes.
In addition, you will see how to dynamically invoke transformation logic in Server side and how to handle the big messages. I will use the simple delimiter messages with about 60M bytes. Guess if you convert it to xml message, how its size will be.

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

BeanFace SOAP Example

This blog will show you how to create SOAP messages through BeanFace API.

1.com.wwlee.beanface.soap.examples.BeanFaceSOAPSimple
In general, to create SOAP and marshal/unmarshal to SOAP, you will import the following classes.

import com.wwlee.beanface.jaxb.BeanFaceJAXB;
import com.wwlee.beanface.soap.envelope11.Envelope;
import com.wwlee.beanface.soap.messages.BeanFaceWSSOAP;
import com.wwlee.beanface.soap.messages.BeanFaceWSSOAPFactory;

Let's see the createSOAPEvelope() method.

public Envelope createSOAPEvelope(String headerMessage, String bodyMessage) throws BeanFaceException {
        Envelope envelope = beanFaceWSSOAPFactory.createEnvelope();
        beanFaceWSSOAP.setEnvelope(envelope);
        if (!StringUtil.isNullOrEmpty(headerMessage)) {
            beanFaceWSSOAP.setHeader(headerMessage);
        }
        beanFaceWSSOAP.setRequestBody(bodyMessage);
        return envelope;
    }

It expects headerMessage and bodyMessage and create SOAP object called Envelope.
Let's run main() method and see the result.
public static void main(String[] args) throws Exception {
        BeanFaceSOAPSimple beanFaceSOAPSimple = new BeanFaceSOAPSimple();
        Envelope envelope = beanFaceSOAPSimple.createSOAPEvelope("Request Header", "Request Body");
        String soapXML = beanFaceSOAPSimple.marshalToString(envelope);
        System.out.println(soapXML);
        envelope = (Envelope) beanFaceSOAPSimple.unmarshalFromString(envelope, soapXML);
        String bodyInformation = beanFaceSOAPSimple.getBodyInfo(envelope);
        System.out.println("+++++ Body Information +++++");
        System.out.println(bodyInformation);
    }
Result]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/">
    <ns2:Header>
        <ns3:bfwsHeader xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsHeader">Request Header</ns3:bfwsHeader>
    </ns2:Header>
    <ns2:Body>
        <ns3:bfwsRequest xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsRequest">Request Body</ns3:bfwsRequest>
    </ns2:Body>
</ns2:Envelope>

+++++ Body Information +++++
BodyLocalPart : bfwsRequest
BodyNamespaceURI : http://beanface.wwlee.com/bfws/bfwsRequest
BodyPrefix : ns3
BodyValueLength : 12
BodyValue : Request Body

2. com.wwlee.beanface.soap.examples.BeanFaceSOAPWithBeanFaceObject
My motivation for BeanFace is from adding legacy format messages as part of SOAP body as it is.
For example, if the file contains the following messages with ',' delimiter, I would like to add it as a soap body.
EMP1,IT Dept,Bean Face Company,123
EMP2,IT Dept,Bean Face Company,123
EMP3,IT Dept,Bean Face Company,123
EMP4,IT Dept,Bean Face Company,123
....
EMP98,IT Dept,Bean Face Company,123
EMP99,IT Dept,Bean Face Company,123
EMP100,IT Dept,Bean Face Company,123

This example will show you how to do this scenario without creating any additional xsd and xml stuffs.
Let's see createSOAPBodyContents() method. It will create SOAP message with the Legacy SOAP Body based on BeanFace API. 

    public String createSOAPBodyContents(int count) throws BeanFaceException {
        String employeeName = "EMP";
        String departmentName = "IT Dept";
        String companyName = "Bean Face Company";
        String countryCode = "123";
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 1; i <= count; i++) {
            beanFaceSampleDelimited.setEmployeeName(employeeName + i);
            beanFaceSampleDelimited.setDepartmentName(departmentName);
            beanFaceSampleDelimited.setCompanyName(companyName);
            beanFaceSampleDelimited.setCountryCode(countryCode);
            stringBuffer.append(beanFaceSampleDelimited.marshalToString() + "\n");
        }
        return stringBuffer.toString();
    }
After running main() method, it will generate SOAP messages as the following.
Result]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/">
    <ns2:Body>
        <ns3:bfwsRequest xmlns:ns3="http://beanface.wwlee.com/bfws/bfwsRequest">EMP1,IT Dept,Bean Face Company,123
EMP2,IT Dept,Bean Face Company,123
EMP3,IT Dept,Bean Face Company,123
EMP4,IT Dept,Bean Face Company,123
EMP5,IT Dept,Bean Face Company,123
EMP6,IT Dept,Bean Face Company,123
EMP7,IT Dept,Bean Face Company,123
EMP8,IT Dept,Bean Face Company,123
EMP9,IT Dept,Bean Face Company,123
EMP10,IT Dept,Bean Face Company,123
</ns3:bfwsRequest>
    </ns2:Body>
</ns2:Envelope>

My client will be happy with this result. But he asked 'how I send this soap messages to server' and 'how web service server side can handle this BeanFace message?.'  'Do we need to create WSDL?'

To get these answers, the following blogs will cover the Web Service Client/Server side examples based on BeanFace Web Service. Through these example, you will learn 'true dynamic web service' including dynamic transformation. Let's see what I am talking about in the next couple of blogs.

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

BeanFace Example


1. BeanFaceGeneratorExample.java - Auto Generate BeanFace based on Legacy Message Formats such as Delimited, Fixed, CSV

In com.wwlee.beanface.examples package in BeanFaceExample, you will see 5 java files.
Delete all except BeanFaceGeneratorExample.java file.

Let's assume the message have four columns as the below
 - EmployeeName,DepartmentName,CompanyName,CountryCode
And it has four different formats with Fixed, Delimited(','), CSV format with ',', Character Delimiter('\t').
After running BeanFaceGeneratorExample, you will see four different types of java files, respectively. 

Let's only focus BeanFaceSampleDelimited.java file. The other java files are the exactly same for the function.
1)public class BeanFaceSampleDelimited extends BeanFaceImpl
Each one should extends BeanFaceImpl to have common methods such as unmarshalFromString(), unmarshalFromBytes(), marshalToString(), marshalToBytes(), getBeanFaceJAXB(), etc.
2)Java Bean - All of set() and get() methods are automatically generated based on Input Column Names.
3)Auto generated XML messages through getBeanFaceJAXB() method.

Let's see the main method and run it.

 public static void main(String[] args) throws Exception {
        String inputMessage = "EmployeeName,DepartmentName,CompanyName,CountryCode";
        BeanFaceSampleDelimited beanFace = new BeanFaceSampleDelimited();
        beanFace.unmarshalFromString(inputMessage);
        System.out.println("Before Changing getEmployeeName : " + beanFace.getEmployeeName());
        beanFace.setEmployeeName("ABC");
        System.out.println("After  Changing getEmployeeName : " + beanFace.getEmployeeName());
        System.out.println(beanFace.marshalToString());    
        /* JAXB Unmarshal and Marshal */
        BeanFaceJAXB beanFaceJAXB = beanFace.getBeanFaceJAXB();
        String xml = beanFaceJAXB.marshalToString(beanFace);
        System.out.println(xml);
        beanFaceJAXB.unmarshalFromString(beanFace, xml);
}
Result]
Before Changing getEmployeeName : EmployeeName
After  Changing getEmployeeName : ABC
ABC,DepartmentName,CompanyName,CountryCode
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beanFaceSampleDelimited>
    <employeeName>ABC</employeeName>
    <departmentName>DepartmentName</departmentName>
    <companyName>CompanyName</companyName>
    <countryCode>CountryCode</countryCode>
</beanFaceSampleDelimited>

2. com.wwlee.beanface.examples.transformation.FixedToDelimtedTransformation.java
   - This example will show you how to transform fixed message format to Delimited format. 
   - After converting it to delimited format, you can also automatically generate XML messages by through BeanFaceJAXB object. Here is the snippet code for this same and its result.

public String transformByJAXBXML(String inputMessage) throws BeanFaceException{
        inputBeanFace.unmarshalFromString(inputMessage);
        int inputColumnNumbers = inputBeanFace.getInputColumnNumbers();
        for(int i=0; i < inputColumnNumbers; i++){
            /*
           outputBeanFace.setEmployeeName(inputBeanFace.getEmployeeName());
           outputBeanFace.setDepartmentName(inputBeanFace.getDepartmentName());
           outputBeanFace.setCompanyName(inputBeanFace.getCompanyName());
           outputBeanFace.setCountryCode(inputBeanFace.getCountryCode());
           */
            outputBeanFace.set(i, inputBeanFace.get(i));
        }
        BeanFaceJAXB beanFaceJAXB = outputBeanFace.getBeanFaceJAXB();
        return beanFaceJAXB.marshalToString(outputBeanFace);
}

Result]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beanFaceSampleDelimited>
    <employeeName>111111</employeeName>
    <departmentName>22</departmentName>
    <companyName>3333333333</companyName>
    <countryCode>44444</countryCode>
</beanFaceSampleDelimited>

Enjoy the above two samples and we will move to SOAP message through BeanFace in the next blog.

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  

What is BeanFace and BeanFace Web Service?


One of my clients asked me, "Is there any easy way to directly use legacy formatted messages such as delimited, fixed, etc as part of Web Service messages? My data with delimited format is about 10 Mbytes. After converted to XML, its size becomes more than 100 Mbytes. No way through Web Service."
This question intrigues my interests. If you have any similar requirement, BeanFace API is the right solution for your business.

Here are brief explanations about what BeanFace and BeanFace Web Service are.
1. BeanFace
   - Automatic Java Generations for Java Bean Classes for Delimited, Fixed, and CSV formats
   - Marshal and Unmarshal from/to Legacy format
   - JAXB Marshal and Unmarshal from/to XML message.
2. BeanFace Web Service client
   - Dynamic Web Service Invocation
   - Use Bean Face for SOAP Body including Legacy format messages
   - JAXB-Based Marshal and Unmarshal Support
   - No need to have WSDL format to generate Web Service
   - Dynamic Web Service Invocation
   - Easily handle Big legacy message.
3. BeanFace Web Service Server
   - Generic Web Service Server to handle any kinds of SOAP messgaes including BeanFace Legacy messages
   - No need ot expose WSDL for Web Service client
   - Dynamic Transformation Invocations

Through a seriese of my blogs, you will see all of BeanFace examples.

To fully use BeanFace and its Web Service, you need to download the followings.
1. BeanFace.jar - BeanFace Core API
2. BeanFaceExample.zip - Include all of the example source codes including Web Service Clients
3. BeanFaceWebService.zip - Include all of the sample java source for Web Service Server sides.  


To execute BeanFace, you need to have Java 1.6 version. With java 1.5, you can run all of sample programs, but you need to add a couple of jar files such as JAXB 2.x jar.


Keep enjoying the continuous BeanFace Blogs.