2006-01-26

Make Perl speak JMS (2)

Now the WSDL is ready, I can start to implement the WS server in Java. The tool of choice is Apache Axis 1.2.1.

With the wsdl2java tool, it is straight forward to generate the codes from the WSDL file. Because we will only use the server code, so we only need to change one class HttpBindingImpl.java.
private MessageRouter mRouter = new MessageRouter();

public code.simple.www.router._2005._11._7.RouteResponseType routeMessage
(code.simple.www.router._2005._11._7.RouteRequestType document)
throws java.rmi.RemoteException
{
try
{
return mRouter.routeMessage(document);
}
catch(Exception ee)
{
throw new RemoteException("Failed to route the message", ee);
}
}

Here we just forward the request to the MessageRouter class and let it handle the details.

Axis provides several different ways to deploy the web services. The most convenient way is to use JWS file but it has certain limitations. Here I choose to use the WSDD file and embed the Axis engine in the Tomcat servlet container. As of how to integrate Axis with a servlet container, I could not find a good documentation. Eventually I figured it out and here is the code
protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException
{
PrintWriter pw = null;
try
{
pw = resp.getWriter();
resp.setContentType(CONTENT_TYPE);

String reqMsg = readContent(req.getReader());
mLogger.info("Got WS request:\n" + reqMsg);
MessageContext msgContext = new MessageContext(mAxisServer);
msgContext.setRequestMessage(new Message(reqMsg));
msgContext.setTargetService("MessageRouterPort");

String respMsgStr = null;
try
{
mAxisServer.invoke(msgContext);
respMsgStr = msgContext.getResponseMessage().getSOAPPartAsString();
}
catch (AxisFault fault)
{
Message respMsg = msgContext.getResponseMessage();
if (respMsg == null)
{
respMsg = new Message(fault);
((org.apache.axis.SOAPPart)respMsg.getSOAPPart()).
getMessage().setMessageContext(msgContext);
}
respMsgStr = respMsg.getSOAPPartAsString();
}

mLogger.info("Got WS response:\n" + respMsgStr);
pw.write(respMsgStr);
}
catch (Exception me)
{
mLogger.error(me);
throw new ServletException(me);
}
finally
{
if (pw != null)
{
pw.close();
}
}
}

public void init(ServletConfig cfg) throws ServletException
{
super.init(cfg);
EngineConfigurationFactory factory =
EngineConfigurationFactoryFinder.newFactory(cfg);
EngineConfiguration config = factory.getServerEngineConfig();
mAxisServer = new AxisServer(config);
}

The deployment descriptor for the servlet is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app >
<servlet>
<servlet-name>MessageRoutingServlet</servlet-name>
<servlet-class>code.simple.MessageRoutingServlet</servlet-class>
<init-param>
<param-name>servletId</param-name>
<param-value>defaultServlet</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>MessageRoutingServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

No comments: