SOAP – Invoking Web Services Without Using the WSDL File. [JAX-WS & Apache CXF]

Through this article I will guide you through the steps for developing a sample web services client application and a server (SOAP) and tips for how to invoke web services without using the WSDL File. Think you have the basic understanding of SOAP web services and the WSDLs.

Overview

Jax-WS

Following are some of the key things we are going to use throughout this article.

1) JAX-WS [Java API for XML Web Services]
A set of APIs for creating web services in XML format (SOAP).JAX-WS provides many annotation to make the development on both web service client and servers in a simple and an effective manner.

2) Apache CXF
Apache CXF is a framework that helps to develop services using JAX-WS APIs.

3) Configure secure transaction for HTTPS Requests using javax.net.ssl.TrustManager

This article cover following sections.

1) Developing a SOAP-based Document style web service endpoint by using JAX-WS API.

When creating web services using SOAP protocol, we have to follow,

  • RPC messaging style                                                                                                                                                                                                                   SOAP message body contains an XML representation of a method call and uses the names of the method and its parameters to generate XML structures that represent a method’s call stack.
  • Document messaging style                                                                                                                                                                                                      The SOAP body contains a XML document which can be validated against pre-defined XML schema document.

Here we are using document messaging style.

Server

1) Creating Web Service Endpoint Interface – ClientTransaction Interface

 import javax.jws.WebMethod;
 import javax.jws.WebService;
 import javax.jws.soap.SOAPBinding;
 import javax.jws.soap.SOAPBinding.Style;
 import javax.jws.soap.SOAPBinding.Use;

@WebService
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL)

public interface ClientTransaction {

@WebMethod String getOrderDetails(String orderNo);

}

2) Creating Web Service Endpoint ImplementationClientTransactionImpl Class

import com.expr.ws.server.controller.ClientTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jws.WebService;


@WebService(endpointInterface = "com.expr.ws.server.controller.ClientTransaction")
public class ClientTransactionImpl implements ClientTransaction {

    private static final Logger logger = LoggerFactory.getLogger(ClientTransactionImpl.class);

    @Override
    public String getOrderDetails(String orderNo) {
        logger.debug("Received Order No : [{}]", orderNo);
        return "Paid Amount 25.00 LKR | Transaction Ref No - 25669321  for order No - " + orderNo;
    }

}

3) Configure Server Endpoint
Apache CXF JAX-WS configurations used as server configurations.

expr_ws_config.xml

<bean id="exprWsServer" class="com.expr.ws.server.controller.impl.ClientTransactionImpl">
 </bean>
<jaxws:endpoint id="exprWsUrl" address="${service.url}">
 <jaxws:implementor>
 <ref local="exprWsServer"/>
 </jaxws:implementor>
 </jaxws:endpoint>

 

4) Run the Application – Starter.java

ApplicationContext context = new ClassPathXmlApplicationContext("expr_ws_config.xml");

Running Server

1) Build app from home directory

 Run - mvn clean install

2) Run app

Unzip - unzip /target/jax-ws-app.zip
Go to - /jax-ws-app/bin
Run   - ./startServer console

3) Verify

Access URL to
http://127.0.0.1:65024/exprws?wsdl

You can download the Sample Application from Github

Client

1) Creating Client – ExprWsClient.java

import com.expr.ws.server.controller.ClientTransaction;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;

public class ExprWsClient extends AbstractSecureWsHandler {

    private static final Logger logger = LoggerFactory.getLogger(ExprWsClient.class);
    private static final String SERVICE_URL = "http://127.0.0.1:65024/exprws";

    public static void main(String[] args) throws Exception {

        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(ClientTransaction.class);
        factory.setAddress(SERVICE_URL);
        ClientTransaction clientTransaction = (ClientTransaction) factory.create();

        Client client = ClientProxy.getClient(clientTransaction);
        client.getInInterceptors().add(new LoggingInInterceptor());
        client.getOutInterceptors().add(new LoggingOutInterceptor());

        // Configure secure services for HTTPS
        configureSecureTransaction(clientTransaction);

        // Request for Order Details
        String orderDetails = clientTransaction.getOrderDetails("445677");
        logger.debug("Result : [{}]", orderDetails);

    }


}

As in the above code JaxWsProxyFactoryBean factory created to avoid invoking the web services using the WSDL File. SERVICE_URL – used according to the server we configured.

2) Enable service for HTTPS Requests – AbstractSecureWsHandler.java

import com.expr.ws.server.controller.ClientTransaction;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public abstract class AbstractSecureWsHandler {

    private static final Logger logger = LoggerFactory.getLogger(AbstractSecureWsHandler.class);

    /**
     * Enable Services for HTTPS Requests
     * @param clientTransaction
     */
    public static void configureSecureTransaction(ClientTransaction clientTransaction) {
        Client client = ClientProxy.getClient(clientTransaction);
        HTTPConduit http = (HTTPConduit) client.getConduit();
        String targetAddress = http.getTarget().getAddress().getValue();
        logger.info("Received Target Address [{}]", targetAddress);

        if (targetAddress.toLowerCase().startsWith("https:")) {
            logger.info("Execute TrustManager for  HTTPS");
            TrustManager[] simpleTrustManager = new TrustManager[] { new X509TrustManager() {
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            } };
            TLSClientParameters tlsParams = new TLSClientParameters();
            tlsParams.setTrustManagers(simpleTrustManager);
            tlsParams.setDisableCNCheck(true);
            http.setTlsClientParameters(tlsParams);
        }
    }

}

As stated above javax.net.ssl.TrustManager used to accept HTTPS requests and handle them without causing any issue.

Okay! So we are almost done in the development of Client for our Web service. You can test it by just running the ExprWsClient.java.

You will get the following result as per your configuration if you succeeded.

Result : Paid Amount 25.00 LKR | Transaction Ref No - 25669321  for order No - 445677

You can download the Sample Application from Github

So think it is helpful and please let me know if you any clarifications or details.

Happy Coding 🙂

FTP – Sample Application & How To Avoid File Corruption When Transfer [Binary vs ASCII]

Through this article I will walk you through a sample FTP client and how to avoid file corruption when transfer.

Recently I came across this issue where some files transferred through FTP got corrupted. After I got to know that some binary files transferred got corrupted when sending through the FTPclient. So I gave a thought to share the findings since it would be more helpful for those who still searching for the solution.

File transfers over FTP handle different forms, basically Binary and ASCII. The main issue is binary file in ASCII mode will corrupt the binary file’s structure and it will convert and encode some characters while transfer.Some FTP clients do not support auto detecting the transfer mode based on the type of the files. But enables manual specification of the mode.

In order to avoid that we need to specify the transfer mode manually when we creating the corresponding FTPClient. So what happen to the ASCII files formats when sending though the binary mode?? Guess what there wont be any issue when transfer because both ASCII and binary files can be sent in binary mode.

ASCII [American Standard Code for Information Interchange] File types

  • HTML files
  • Text files
  • CGI scripts

Ex- .txt .html .shtml .php .pl .cgi .js .css .map .pwd .txt .grp .ctl

Binary File Types

  • zip, tar.gz packages
  • Images
  • File formats such as .doc, .xls

Ex – .jpg .gif .png .tif .exe .zip .sit .rar .class .mid .wav .mp3, .doc, .xls

Sample Application

  •  FTP Server – Apache-Ftpserver-1.0.6
  •  FTP Client – Apache Commons-Net – 2.0

FTPClient


 FTPClient ftpClient = new FTPClient();
 

Connect to the FTP Server


ftpClient.connect(hostname, port);

Check logged in status


boolean isLoggedIn = ftpClient.login(username, password);

To avoid file corruption handle Binary files


ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

Create FileInputStream from created file.


FileInputStream fileInputStream = new FileInputStream(fileEntry);

Transfer File


boolean isSuccessfullyUploaded = ftpClient.storeFile(upload_path, fileInputStream);

Logout


ftpClient.logout();

Now we have almost completed the FTPClient. Lets check on the FTP Server.

FTP Server

Configure FTP Server

1) Extract the given apache-ftpserver-1.0.6.zip
2) Go to /apache-ftpserver-1.0.6/res/conf
3) Add username and password as available configurations in users.properties (Currently I have configured the username 'local' )

Start FTP server

1) Go to apache-ftpserver-1.0.6/bin/
2) Run ./ftpd.sh res/conf/ftpd-typical.xml

Okay! So now you can test the application by configuring any file type and transfer using Apache FTPClient.

You can download the Sample Application from Github

Hope its helpful for you to implement FTPClient and avoid file corruptions while transfer.

Happy Coding 🙂

How to Install RockMongo – MongoDB Administration Tool

Hey guys, think you all know about the popular NoSQL Database “MongoDB” and if you are looking for an easy way to manipulate the data through a GUI, Rockmongo is the best administration tool that can be used so far. Following is a step by step guide for the installation of Rockmongo in Ubuntu.

Prerequisites
MongoDB
Apache Server
PHP – 5.1.6 or newer

Installation
1) Check Installed Packages (Check Php Installation)
aptitude – Text-based front-end for the APT package management system.
OR
Get the list of installed packages
Ubuntu – dpkg –get-selections | grep php

2) Install Apache Server
sudo apt-get install apache2

To check whether Apache Installed and running
Start apache server – sudo service apache2 start
Go To – http://localhost/
If it’s installed successfully you can view the screen with (It Works!!).

3) Install PHP with Apache
sudo apt-get install php5 libapache2-mod-php5 install

4) Install PHP Pear
sudo apt-get install php-pear

5) Check that the PEAR and PECL Versions
pear version
pecl version

6) Install php MongoDB Driver
sudo pecl install mongo

7) Download the latest Rockmongo from – http://rockmongo.com/downloads
Extract it to /var/www/

8) Add Extention to php.ini
locate php.ini
(/etc/php5/apache2/php.ini)
Add – “extension=mongo.so” to the “Dynamic Extensions” section.

9) Then Restart Apache server.
sudo service apache2 restart

10) Go to – http://localhost/rockmongo
Login with –
Username – admin
Password -admin

Image

For More Info Please visit – http://rockmongo.com

Android – Save Images into Database (SQLite Database)

Android provides several ways to store the app data and SQLite (inbuilt DB) is one way of storing this data.  It is important to get to know  the mechanism of storing images in the database.  The following post describes how to save images to the database and retrieve saved images from the database to display.

//

Let’s create “ImageHelper.java” model class first.

public class ImageHelper {
private String imageId;
private byte[] imageByteArray;
public String getImageId() {
 return imageId;
 }
public void setImageId(String imageId) {
 this.imageId = imageId;
 }
public byte[] getImageByteArray() {
 return imageByteArray;
 }
public void setImageByteArray(byte[] imageByteArray) {
 this.imageByteArray = imageByteArray;
 }
}

The following “DatabaseHelper.java” class contains  all CRUD Operations (Create, Read, Update and Delete) and we have to  extend  SQLiteOpenHelperto enable SQLite Database functionalities.  Before go into more details let’s check some important methods in this DatabaseHelper.java class.

The following method insetImage() will insert the image to the database.

public void insetImage(Drawable dbDrawable, String imageId)  {
 SQLiteDatabase db = this.getWritableDatabase();
 ContentValues values = new ContentValues();
 values.put(IMAGE_ID, imageId);
 Bitmap bitmap = ((BitmapDrawable)dbDrawable).getBitmap();
 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
 values.put(IMAGE_BITMAP, stream.toByteArray());
 db.insert(TABLE_IMAGE, null, values);
 db.close();
 }

According to the above code Drawable image is converted to a Byte Array to save in the database.

We can retrieve the image from the database from  getImage() method which will return ImageHelper Object including the image Byte Array.

public ImageHelper getImage(String imageId)  {
 SQLiteDatabase db = this.getWritableDatabase();
 Cursor cursor2 = db.query(TABLE_IMAGE,
 new String[] {COL_ID, IMAGE_ID, IMAGE_BITMAP},IMAGE_ID
 +" LIKE '"+imageId+"%'", null, null, null, null);
 ImageHelper imageHelper = new ImageHelper();
 if (cursor2.moveToFirst()) {
 do {
 imageHelper.setImageId(cursor2.getString(1));
 imageHelper.setImageByteArray(cursor2.getBlob(2));
 } while (cursor2.moveToNext());
 }
 cursor2.close();
 db.close();
 return imageHelper;
 }

Let’s see the complete DatabaseHelper.java class.

public class DatabaseHelper extends SQLiteOpenHelper {
private Context context;
private final String TAG = "DatabaseHelperClass";
private static final int databaseVersion = 1;
private static final String databaseName = "dbTest";
private static final String TABLE_IMAGE = "ImageTable";
// Image Table Columns names
private static final String COL_ID = "col_id";
private static final String IMAGE_ID = "image_id";
private static final String IMAGE_BITMAP = "image_bitmap";
public DatabaseHelper(Context context) {
super(context, databaseName, null, databaseVersion);
this.context = context;
}
 @Override
 public void onCreate(SQLiteDatabase sqLiteDatabase) {
 String CREATE_IMAGE_TABLE = "CREATE TABLE " + TABLE_IMAGE + "("
 + COL_ID + " INTEGER PRIMARY KEY ,"
 + IMAGE_ID + " TEXT,"
 + IMAGE_BITMAP + " TEXT )";
 sqLiteDatabase.execSQL(CREATE_IMAGE_TABLE);
 }
 @Override
 public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
 // Drop older table if existed
 sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_IMAGE);
 onCreate(sqLiteDatabase);
 }

 public void insetImage(Drawable dbDrawable, String imageId) {
 SQLiteDatabase db = this.getWritableDatabase();
 ContentValues values = new ContentValues();
 values.put(IMAGE_ID, imageId);
 Bitmap bitmap = ((BitmapDrawable)dbDrawable).getBitmap();
 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
 values.put(IMAGE_BITMAP, stream.toByteArray());
 db.insert(TABLE_IMAGE, null, values);
 db.close();
 }
 public ImageHelper getImage(String imageId) {
 SQLiteDatabase db = this.getWritableDatabase();
 Cursor cursor2 = db.query(TABLE_IMAGE,
 new String[] {COL_ID, IMAGE_ID, IMAGE_BITMAP},IMAGE_ID
 +" LIKE '"+imageId+"%'", null, null, null, null);
 ImageHelper imageHelper = new ImageHelper();
 if (cursor2.moveToFirst()) {
 do {
 imageHelper.setImageId(cursor2.getString(1));
 imageHelper.setImageByteArray(cursor2.getBlob(2));
 } while (cursor2.moveToNext());
 }
 cursor2.close();
 db.close();
 return imageHelper;
 }
}

After that Let’s make this functional through the MainActivity.java class.  Save image through onCreate()  method as follows.

 Drawable dbDrawable = getResources().getDrawable(R.drawable.db);
 databaseHelper.insetImage(dbDrawable, IMAGE_ID);

Then  use the AsyncTask to load the image through the database in a separate thread.

 private class LoadImageFromDatabaseTask 
                             extends AsyncTask<Integer, Integer, ImageHelper> {
 private final ProgressDialog LoadImageProgressDialog = 
                             new ProgressDialog(MainActivity.this);
 protected void onPreExecute() {
 this.LoadImageProgressDialog.setMessage("Loading Image from Db...");
 this.LoadImageProgressDialog.show();
 }
 @Override
 protected ImageHelper doInBackground(Integer... integers) {
 Log.d("LoadImageFromDatabaseTask : doInBackground", "");
 return databaseHelper.getImage(IMAGE_ID);
 }
 protected void onProgressUpdate(Integer... progress) {
 }
 protected void onPostExecute(ImageHelper imageHelper) {
 Log.d("LoadImageFromDatabaseTask : onPostExecute - ImageID ", imageHelper.getImageId());
 if (this.LoadImageProgressDialog.isShowing()) {
 this.LoadImageProgressDialog.dismiss();
 }
 setUpImage(imageHelper.getImageByteArray());
 }
 }

Then set the image to a imageview by converting it to a bitmap from the byteArray.

 private void setUpImage(byte[] bytes) {
 Log.d(TAG, "Decoding bytes");
 Bitmap bitmap = BitmapFactory.decodeByteArray(bytes , 0, bytes .length);
 imageView.setImageBitmap(bitmap);
 }

Check
Continue reading

Auto Deploy Web Application In Tomcat

How to auto deploy web application in Tomcat ?? Here is the solution… The deployment of the web application is automated using maven Cargo plugin.

Tomcat – 6.0.36
Maven – 2.2.1
java – 1.6

Add the following code to pom.xml in your project and replace the project name, path to web directory, package name as highlighted in the code.

<build>
  <finalName>{your.project.name}</finalName>
<plugins>
  <plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <version>2.1.1</version>
  <configuration>
  <webappDirectory>{your.project.webapp.directory}</webappDirectory>
  </configuration>
  </plugin>
  <plugin>
  <groupId>org.codehaus.cargo</groupId>
  <artifactId>cargo-maven2-plugin</artifactId>
  <configuration>
  <container>
  <containerId>tomcat6x</containerId>
  <type>remote</type>
  </container>
  <configuration>
  <type>runtime</type>
  <properties>
  <cargo.tomcat.manager.url>
  http://localhost:8080/manager
  </cargo.tomcat.manager.url>
  <cargo.remote.username>
  tomcat
  </cargo.remote.username>
  <cargo.remote.password>
  tomcat
  </cargo.remote.password>
  </properties>
  </configuration>
  <deployer>
  <type>remote</type>
  <deployables>
  <deployable>
  <groupId>
  {project.package}
  </groupId>
  <artifactId>
  {your.project.name}
  </artifactId>
  <type>war</type>
  </deployable>
  </deployables>
  </deployer>
  </configuration>
  </plugin>
</plugins>
</build>

Add following to  tomcat-users.xml in  tomcat/conf

<tomcat-users>
  <role rolename="manager"/>
  <user username="tomcat" password="tomcat" roles="manager"/>
</tomcat-users>

Maven Commands to deploy/redeploy the web application is,
deploy – mvn cargo:deploy
redeploy – mvn cargo:redeploy

Posted in Web

Tags:

Permalink 2 Comments

Android Drawable to byte Array.

Hey guys, add the following code segment  to get a Byte array from a Drawable in android. Hope this helps 🙂

Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.my_pic);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitMapData = stream.toByteArray();

Power of AWK {}

Recently I been working  on a file manipulation task as a part of a project where I have to filter huge set of records form 2 files according  to the first file’s specification.

As  an  example –

File A holds the records of all students in a class and File B consists of the students who passed the exam where we have to filter all the passed student details from File A  using File B.


File A :
00001,John,New York
00002,Peter,Mexico
00003,Sam,Barnet
00004,jenny,Leeds

File B  :
00002,Peter
00003,Sam

So the Filtered File C  :

File C :
00002,Peter,Mexico
00003,Sam,Barnet

So the preferred solution was to write a shell script for it.

Fileter_Records.sh

#!/bin/sh

MAIN_FILE='A.txt'
FILTER_FILE='B.txt'
OUPUT_FILE='C.txt'

LINES_MAIN=`wc -l < $MAIN_FILE`
LINES_FILTER=`wc -l < $FILTER_FILE`

echo “Records in the main file :”[$LINES_MAIN]
echo “Records in the filter file:”[$LINES_FILTER]
echo

for ((count=1; count<=$LINES_MAIN; count++ ))
do
record=`cat $MAIN_FILE| head -$count| tail -1`
stu_no_1=`echo $record | cut -d, -f1`
name=`echo $record | cut -d, -f2`
city=`echo $record | cut -d, -f3`
stu_no_2=`grep “$stu_no_1” $FILTER_FILE | cut -d, -f1`

if  ![ -z stu_no_2] && [ “$stu_no_1” == “stu_no_2” ];
then
echo $stu_no_1,$name,$city >> $OUPUT_FILE
fi

done

Script will read line by line from File A and split accordingly while assigning them to variables. Then it will search the student number in File B and if it matches and not a blank it will filter all data to the File C.

Even though it can be easily code in normal shell script, the challenge  was to rice up the performance of the process when it holds like 4 mil records. Currently this script will run like 33 hours to process 4 million records.

While I was searching for a solution ( Since I’new to shell scripting ) I got to know that ‘ AWK’  will the do the magic to complete the process like 100 times lesser than the normal shell script.

In brief  “AWK”  is  another cornerstone  of  UNIX Shell programming where it  act as a data extraction an a reporting tool. Basically it really helps on text  file manipulation. So the solution was withing a line of code where it only take 32 seconds to process 4 million records.

Fileter_Records.sh

awk -F , 'NR==FNR{_[$1];next}($1 in _)'  B.txt  A.txt  > C.txt

This script will recursively read lines of File A and split the first block of each line where it compare  that block with the first record of the File B and it will write them to File C if it matches successfully.

Think you enjoy the magic of  AWK!!  

Cheers.

Blog Stats

  • 38,679 hits