Apache CXF And Embedded Tomcat

In this tutorial we are going to test a webservice using embedded Tomcat instance and JUnit. Here we are testing a simple REST service implemented by CXF framework, It works as a standalone application.
Apache CXF And Embedded Tomcat
Apache Tomcat is an open source software implementation of the Java Servlet and JavaServer Pages technologies. The Java Servlet and JavaServer Pages specifications are developed under the Java Community Process.
Reference -> http://tomcat.apache.org/
Required Libraries
For running minimal version of tomcat 7, You need to download
- hamcrest-core-1.3.jar (Required for JUnit)
- tomcat-embed-core-7.0.27.jar
- tomcat-embed-jasper-7.0.27.jar
- tomcat-juli-7.0.27.jar
- CXFRestfulTutorial.war [generating war, please check -> http://www.javatips.net/blog/cxf-restful-tutorial]
Project Structure
Testing REST service with an embedded Tomcat
Here we are using JUnit and embedded Tomcat instance for testing different rest methods (getName-> GET & changeName-> POST). We are attaching CXFRestfulTutorial.war programmatically and this war contains all the rest methods(getName & changeName) we are going to test.
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import org.apache.catalina.core.AprLifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.Tomcat;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class EmbeddedTomcatIT {
protected static Tomcat tomcat;
@BeforeClass
public static void setUp() throws Exception {
tomcat = new Tomcat();
tomcat.setPort(9000);
tomcat.setBaseDir(".");
tomcat.getHost().setAppBase(".");
// Add AprLifecycleListener
StandardServer server = (StandardServer) tomcat.getServer();
AprLifecycleListener listener = new AprLifecycleListener();
server.addLifecycleListener(listener);
tomcat.addWebapp("/CXFRestfulTutorial", "CXFRestfulTutorial.war");
tomcat.start();
}
@Test
public void testGetMethod() throws InterruptedException, ExecutionException {
try {
URL url = new URL(
"http://localhost:9000/CXFRestfulTutorial/rest/getName");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "application/json");
Scanner scanner;
String response;
if (conn.getResponseCode() != 200) {
scanner = new Scanner(conn.getErrorStream());
response = "Error From Server \n\n";
} else {
scanner = new Scanner(conn.getInputStream());
response = "Response From Server \n\n";
}
scanner.useDelimiter("\\Z");
System.out.println(response + scanner.next());
scanner.close();
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testPostMethod() throws InterruptedException,
ExecutionException {
try {
URL url = new URL(
"http://localhost:9000/CXFRestfulTutorial/rest/changeName");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String input = "{\"Student\":{\"name\":\"Tom\"}}";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
Scanner scanner;
String response;
if (conn.getResponseCode() != 200) {
scanner = new Scanner(conn.getErrorStream());
response = "Error From Server \n\n";
} else {
scanner = new Scanner(conn.getInputStream());
response = "Response From Server \n\n";
}
scanner.useDelimiter("\\Z");
System.out.println(response + scanner.next());
scanner.close();
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@AfterClass
public static void tearDown() throws Exception {
if (tomcat != null) {
tomcat.stop();
tomcat.destroy();
tomcat = null;
}
}
}
Output
INFO: Root WebApplicationContext: initialization completed in 1042 ms Oct 24, 2014 10:03:45 AM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-bio-9000"] Response From Server {"Student":{"name":"HELLO Tom"}} Response From Server {"Student":{"name":"Rockey"}} Oct 24, 2014 10:03:46 AM org.apache.coyote.AbstractProtocol pause INFO: Pausing ProtocolHandler ["http-bio-9000"] Oct 24, 2014 10:03:46 AM org.apache.catalina.core.StandardService stopInternal INFO: Stopping service Tomcat Oct 24, 2014 10:03:46 AM org.apache.catalina.core.ApplicationContext log INFO: Closing Spring root WebApplicationContext Oct 24, 2014 10:03:46 AM org.springframework.context.support.AbstractApplicationContext doClose INFO: Closing Root WebApplicationContext: startup date [Fri Oct 24 10:03:44 IST 2014]; root of context hierarchy Oct 24, 2014 10:03:46 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1a7c21bb: defining beans [cxf,org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor,org.apache.cxf.bus.spring.Jsr250BeanPostProcessor,org.apache.cxf.bus.spring.BusExtensionPostProcessor,base,StudentService]; root of factory hierarchy Oct 24, 2014 10:03:46 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks SEVERE: The web application [/CXFRestfulTutorial] created a ThreadLocal with key of type [com.sun.xml.bind.v2.ClassFactory$1] (value [com.sun.xml.bind.v2.ClassFactory$1@7148f472]) and a value of type [java.util.WeakHashMap] (value [{class com.student.Student=java.lang.ref.WeakReference@39dc44b6}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. Oct 24, 2014 10:03:46 AM org.apache.coyote.AbstractProtocol stop INFO: Stopping ProtocolHandler ["http-bio-9000"] Oct 24, 2014 10:03:46 AM org.apache.coyote.AbstractProtocol destroy INFO: Destroying ProtocolHandler ["http-bio-9000"]