Friday 30 September 2011

Add Handler to ColdFusion web services



Well first of all lets understand what does adding Handler to ColdFusion web services mean. As the name suggests, you can create and add your class/function in such a way that whenever there is a request/response to ColdFusion soap based web service, your class/function will be called.

Lets understand it from an example.
You created a service in ColdFusion, but you want your program 'Logger' to be called for every request/response so that you can log the service in your own way. Well as the ColdFusion already gives you logging handlers so lets take a good example.

What if you want to digitally sign your soap messages before sending them through ColdFusion. Its easy, I would suggest to use Apache xml security library and write a simple program in Java to do that. But the twist is how to call that java class everytime you send a soap response in ColdFusion. Well there is the need to add the handlers in ColdFusion web service. So here we go trying our hand at it.

Just follow few easy steps.


  1. Create a simple web service in ColdFusion and try to invoke it. See if its working fine and you are getting the expected result. Now open client-config.wsdd kept in {coldfusion_webroot}\WEB-INF\ folder. Take a back-up of this .wsdd and keep it safe. Open this wsdd in notepad and if you will notice, this .wsdd file is in xml format.
  2.  I will give you a snippet of wsdd file which I have modified.

  3. 
     
    
     
      
      
    
      
     
       
      
      
     
    
      
    .
    .
    .
    
    
    

  4. Check out what all has been mofified in this client-config.wsdd file. First of all look for <requestFlow> tag element in this file(usually this will be the child element of <globalConfiguration> element and will be commented by default). If <requestFlow> is commented then remove the comments around it and add this line in between <requestFlow> opening and closing tags: <handler type="myClass"/>
  5. Also notice that there will be one handler already present in it: <handler type="log"/>. This is ColdFusion's handler to log the requests. You can remove this log handler if you do not want your services to be logged(specially in production servers). Just comment this particular handler eg: <!-- <handler type="log"/> -->
  6. After doing this much there just one more line to be added in this wsdd file.  Notice that there is a <deployment> element tag in the beginning of file and its child is <handler> element tag. This handler is provided by ColdFusion for the very same purpose of logging. We will add our handler somewhat similar to ColdFusion's handler: <handler name="myClass" type="java:myClassName"/>. You can add this just beneath handler provided by ColdFusion. 
  7. Save this client-config.wsdd file and we are half way done. Now lets create one sample class for testing this and we will keep its name as myClassName.java, as we have given this very same name in wsdd file. You can choose whatever name you like but make sure to give the same name in handler. You can also make package but you need to keep it in similar manner in wsdd too eg: <handler name="myClass" type="java:myPackageName.myClassName"/>.
  8. Just as I explained the steps to add the handler in <requestFlow> in client-config.wsdd file, similarly you can also add a handler for <responseFlow> so that you can catch the reponses as well.
I will share a very simple code of java which creates one file in local directory so that we can keep a check that this method is getting called everytime web service is hit, by looking at the timetsamp of file created.


//java code
import java.io.*;
import org.apache.axis.handlers.*;
import org.apache.axis.*;

public class myClassName extends BasicHandler
{
 public void init()
 {
  super.init();
  System.out.println("init is called");
 }

 public void createFile() {
  try{
  File f;
  f=new File("D:\\sample.txt");
  if(!f.exists())
  {
   f.createNewFile();
   //New file has been created to the specified directory
  }
  }catch(IOException e)
  {e.printStackTrace();}
 }

 public void invoke(MessageContext mCtx) throws AxisFault {
  try {
   this.createFile();
  } 
  catch (Exception e) {
   e.printStackTrace();
  }
 }

}
Compile this program and keep the class file in {ColdFusion_documentroot}\lib\
Usually it will be C:\ColdFusion9\lib\

Understanding myClassname.java
  1. First of all I have imported few axis classes which are required for handler
  2. I have also extended the class with BasicHandler class of axis. This class is present in org.apache.xml.handlers.* in axis.jar (found in {ColdFusion_documentroot}\lib folder)
  3. This BasicHandler is an abstract class with invoke(MessageContext) as abstract method which is why its necessary to implement this method. This method throws AxisFault Exception. You can use this method for whatever you have to implement, 
  4. Other than this we have also written init() method. This method will be called first time when your handler(myClassName) will be called.
  5. You can extend this program's functionality to whatever you want.


Well that is it.
Just restart the server(as we have added myClassname.class in lib folder) and access the web service created by you, you will see the file created successfully. 


This way you can add whatever handler you want and as ColdFusion web services are based on Axis, you can take strong benefits of Axis library and do whatever you want with your web services in ColdFusion.


Feel free to post any queries.

ColdFusion Rocks!!!

4 comments:

  1. Thanks for this post, Milan! I have to implement a custom web service handler in ColdFusion 11 and I didn't know where to start.

    ReplyDelete
  2. Milan,

    I've been able to compile a class (same code as myClass above) and call it with the following in a standard .cfm template:




    However, the createFile() method does not run when my web service is invoked. I have modified my wsdd file as instructed above. Any ideas?

    Thanks,
    Sam

    ReplyDelete
    Replies
    1. Hi Sam,

      Sorry for the delay.
      Is your problem solved?

      Milan.

      Delete
  3. I am happy to find this post useful for me, as it contains lot of information. I always prefer to read the quality content and this thing I found in you post. Thanks for sharing.
    video and blog marketing

    ReplyDelete