Servlet

As well as running as a standalone server, a queue manager can be encapsulated in a servlet to run inside a Web server . A servlet queue manager has nearly the same capabilities as a server queue manager. MQeServlet provides an example implementation of a servlet. As with the server, servlets use ini files to hold start up parameters. A servlet uses many of the same WebSphere MQ Everyplace components as the server.

The main component not required in a servlet is the connection listener, this function is handled by the Web server itself. Web servers only handle http data streams so any WebSphere MQ Everyplace client that wishes to communicate with an WebSphere MQ Everyplace servlet must use the http adapter (com.ibm.mqe.adapters.MQeTcpipHttpAdaper). When you configure connections to queue managers running in servlets, you must specify the name of the servlet in the parameters field of the connection. The following definitions configure a connection on servlet /servlet/MQe with queue manager PayrollQM:

Connection name
PayrollQM
Channel
com.ibm.mqe.communications.MQeChannel
Note:
The com.ibm.mqe.MQeChannel class has been moved and is now known as com.ibm.mqe.communications.MQeChannel. Any references to the old class name in administration messages is replaced automatically with the new class name.
Channel Adapter
com.ibm.mqe.adapters.MQeTcpipAdapter:192.168.0.10:80
Parameters
/servlet/MQe
Options

Alternatively, if the relevant aliases have been set up, you can configure the connection as follows:

Connection name
PayrollQM
Channel
DefaultChannel
Adapter
Network:192.168.0.10:80
Parameters
/servlet/MQe
Options

Web servers can run multiple servlets. It is possible to run multiple different WebSphere MQ Everyplace servlets within a Web server, with the following restrictions:

The WebSphere MQ Everyplace servlet extends javax.servlet.http.HttpServlet and overrides methods for starting, stopping and handling new requests. The following code fragment starts a servlet:

/**
 * Servlet initialization......
 */
public void init(ServletConfig sc) throws ServletException
{
  // Ensure supers constructor is called.
  super.init(sc);

  try
  {
    // Get the the server startup ini file
    String startupIni;
    if ((startupIni = getInitParameter("Startup")) == null)
      startupIni = defaultStartupInifile;

    // Load it
    MQeFields sections = MQeQueueManagerUtils.loadConfigFile(startupIni);

    // assign any class aliases
    MQeQueueManagerUtils.processAlias(sections);

    // Uncomment the following line to start trace before the queue 
    // manager is started
    //      MQeQueueManagerUtils.traceOn("MQeServlet Trace", null);

    // Start connection manager
    channelManager = MQeQueueManagerUtils.processChannelManager(sections);

    // check for any pre-loaded classes
    loadTable = MQeQueueManagerUtils.processPreLoad(sections);

    // setup and activate the queue manager
    queueManager = MQeQueueManagerUtils.processQueueManager(sections,
	   channelManager.getGlobalHashtable( ));

    // Start ChannelTimer  (convert time-out from secs to millisecs)
    int tI =   
      sections.getFields(MQeQueueManagerUtils.Section_Listener).getInt
																			("TimeInterval");
    long timeInterval = 1000 * tI;
    channelTimer = new MQeChannelTimer(channelManager, timeInterval);

    // Servlet initialization complete
    mqe.trace(1300, null);
  }
  catch (Exception e)
  {
    mqe.trace(1301, e.toString());
    throw new ServletException(e.toString());
  }
}

The main differences compared to a server startup are:

A servlet relies on the Web server for accepting and handling incoming requests. Once the Web server has decided that the request is for an WebSphere MQ Everyplace servlet, it passes the request to WebSphere MQ Everyplace using the doPost() method. The following code handles this request:

/**
 * Handle POST......
 */
public void doPost(HttpServletRequest request,
                   HttpServletResponse response) 
							throws IOException
{
  // any request to process ?
  if (request == null)
    throw new IOException("Invalid request");
  try
  {
    int max_length_of_data = request.getContentLength();     
		// data length
    byte[] httpInData = new byte[max_length_of_data];        
		// allocate data area
    ServletOutputStream httpOut = response.getOutputStream();
		// output stream
    ServletInputStream  httpIn  = request.getInputStream();  
		// input stream

    // get the request
    read( httpIn, httpInData, max_length_of_data);

    // process the request
    byte[] httpOutData = channelManager.process(null, httpInData);

    // appears to be an error in that content-
			length is not being set
    // so we will set it here
    response.setContentLength(httpOutData.length);
    response.setIntHeader("content-length", httpOutData.length);

    // Pass back the response
    httpOut.write(httpOutData);
  }
  catch (Exception e)
  {
    // pass it on ...
    throw new IOException( "Request failed" + e );
  }
}

This method:

  1. Reads the http input data stream into a byte array. The input data stream may be buffered so the read() method is used to ensure that the entire data stream is read before continuing.
    Note:
    WebSphere MQ Everyplace only handles requests with the doPost() method, it does not accept requests using the doGet() method
  2. The request is passed to WebSphere MQ Everyplace through a connection manager. From this point, all processing of the request is handled by core WebSphere MQ Everyplace classes such as the queue manager.
  3. Once WebSphere MQ Everyplace has completed processing the request, it returns the result wrapped in http headers as a byte array. The byte array is passed to the Web server and is transmitted back to the client that originated the request.