“Alice came to a fork in the road. 'Which road do I take?' she asked.'Where do you want to go?' responded the Cheshire Cat.'I don't know,' Alice answered.'Then,' said the Cat, 'it doesn't matter.”
“The sun is simple. A sword is simple. A storm is simple. Behind everything simple is a huge tail of complicated.”
Embedded Jetty
Embedding Jetty 1.9.5 in your application is simple and in fact encouraged by it's creators. That there is a whole bunch of complexity behind the scenes is for moment irrelevant. We create a class that extends AbstractHandler, attach it to the server and start the server. The only requirement is the jetty.jar, which is easily found with maven.HelloHandler.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
public class HelloHandler extends AbstractHandler {
final String _greeting;
final String _body;
public HelloHandler() {
_greeting = "Hello World";
_body = null;
}
public HelloHandler(String greeting) {
_greeting = greeting;
_body = null;
}
public HelloHandler(String greeting, String body) {
_greeting = greeting;
_body = body;
}
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("<h1>
" + _greeting + "<h1>
");
if (_body != null) response.getWriter().println(_body);
}
}
And then adding the Handler to a Jetty server.
SimplestServer.java
import org.eclipse.jetty.server.Server;
public class SimplestServer {
public static void main(String[] args) throws Exception {
Server server = new Server(1111);
HelloHandler root = new HelloHandler();
server.setHandler(root);
server.start();
server.join();
}
}
Easy as two pies!
Run the application and test the server:
http://localhost:1111/
Embedded Axis
Running an Axis 1.6.2 HTTP server is almost as easy. Axis allows us to expose a POJO as a webservice and it takes care of the wsdl and xsd generation. This makes writing services very easy, but the trade-off is that the server configuration is a bit more tricky. Here we will create an Axis Server configuration from scratch (no axis2.xml). We only need a few jars: org.apache.axis2 - axis2 - 1.6.2, axis2-transport-http, axis2-transport-local and log4j - log4j - 1.2.17.First we create our POJO. It's a simple service that can say "Hello" and subtract two numbers.
HelloPojo.java
public class HelloPojo {
public String sayHello(String name) {
return "Hello " + name;
}
public int subtract(int a, int b) {
return a - b;
}
}
Now we need to create an axis2 context from scratch. Remember we did not install axis.
Axis2SimpleServer.java
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.engine.AxisConfiguration;
public class Axis2SimpleServer {
public static void main(String[] args) throws Exception {
// create empty config context
ConfigurationContext context = ConfigurationContextFactory
.createDefaultConfigurationContext();
AxisConfiguration cfg = context.getAxisConfiguration();
// add a POJO to it
AxisService service = AxisService.createService(
HelloPojo.class.getName(), cfg);
cfg.addService(service);
}
}
and now we need to use this configuration to start our server.
// Use the SimpleHTTPServer to specify a port
HttpFactory f = new HttpFactory(context);
f.setPort(1111);
SimpleHTTPServer server = new SimpleHTTPServer(f);
server.start();
If you run the application now and test the server you will not notice the problem immediately:
http://localhost:1111/
forwards to:
http://localhost:1111/axis2/services
and displays the POJO as a service. Click on the service an you get the WSDL.
All good so far!
The problem comes in when you execute the service:
http://localhost:1111/axis2/services/HelloPojo/subtract?a=99&b=12
No output is generated and a NullPointerException is generated at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:172) !
This happens because there is no output transport defined.
Axis2 generates a default http input transport when we send it an empty configuration, but does not do the same for the output. This is easily fixed by adding a TransportSender to the configuration before we pass it to the server:
TransportOutDescription transportOut = new TransportOutDescription("http");
CommonsHTTPTransportSender sender = new CommonsHTTPTransportSender();
sender.init(context, transportOut);
transportOut.setSender(sender);
cfg.addTransportOut(transportOut);
and now our class looks like this:
Axis2SimpleServer.java
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.transport.http.CommonsHTTPTransportSender;
import org.apache.axis2.transport.http.SimpleHTTPServer;
import org.apache.axis2.transport.http.server.HttpFactory;
public class Axis2SimpleServer {
public static void main(String[] args) throws Exception {
// create empty config context
ConfigurationContext context = ConfigurationContextFactory
.createDefaultConfigurationContext();
AxisConfiguration cfg = context.getAxisConfiguration();
// add a POJO to it
cfg.addService(AxisService.createService(
HelloPojo.class.getName(), cfg));
// create a sender
TransportOutDescription transportOut = new TransportOutDescription("http");
CommonsHTTPTransportSender sender = new CommonsHTTPTransportSender();
sender.init(context, transportOut);
transportOut.setSender(sender);
cfg.addTransportOut(transportOut);
// deploy on an Axis2 server on default port 6060
// new AxisServer().deployService(HelloPojo.class.getName());
// Use the SimpleHTTPServer to specify a port
HttpFactory f = new HttpFactory(context);
f.setPort(1111);
SimpleHTTPServer server = new SimpleHTTPServer(f);
server.start();
}
}
Adding services is now as easy as creating a POJO and adding it with:
cfg.addService(AxisService.createService(
GoodbyePojo.class.getName(), cfg));
Running an axis2 servlet inside Jetty
JettyAxisServer.java
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.transport.http.AxisServlet;
import org.apache.axis2.transport.http.AxisServletListener;
import org.apache.axis2.transport.http.CommonsHTTPTransportSender;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
public class JettyAxisServer {
public static void main(String[] args) throws Exception {
// create an empty configuration
ConfigurationContext context = ConfigurationContextFactory
.createDefaultConfigurationContext();
AxisConfiguration cfg = context.getAxisConfiguration();
// create a receiver
TransportInDescription transportIn = new TransportInDescription("http");
AxisServletListener receiver = new AxisServletListener();
receiver.init(context, transportIn);
receiver.setPort(1111);
transportIn.setReceiver(receiver);
cfg.addTransportIn(transportIn);
// create a sender
TransportOutDescription transportOut = new TransportOutDescription("http");
CommonsHTTPTransportSender sender = new CommonsHTTPTransportSender();
sender.init(context, transportOut);
transportOut.setSender(sender);
cfg.addTransportOut(transportOut);
// add a group and a service
AxisServiceGroup group = new AxisServiceGroup(cfg);
group.setServiceGroupName("POJOs");
AxisService service = AxisService.createService(
HelloPojo.class.getName(), cfg);
group.addService(service);
cfg.addServiceGroup(group);
cfg.addToAllServicesMap(service);
// deploy as a servlet in Jetty
Server server = new Server(1111);
WebAppContext root = new WebAppContext();
// pass the axis context to the servlet context
root.setAttribute(AxisServlet.CONFIGURATION_CONTEXT, context);
// create a servlet
AxisServlet s = new AxisServlet();
ServletHolder holder = new ServletHolder(s);
root.addServlet(holder, "/axis2/*");
root.setResourceBase("./src/main/webapp");
server.setHandler(root);
server.start();
server.join();
}
}