Fork me on GitHub

WAR Tutorial

This tutorial demonstrates embedding a web archive (WAR) application into OfficeFloor.

The reason for embedding the WAR, is to enable a phased migration to OfficeFloor. Forcing a rewrite of the application into OfficeFloor is typically expensive (plus falls under the anti-pattern of "big bang"). Therefore, the WAR application can be embedded in OfficeFloor and functionality slowly migrated out of it to take advantage of OfficeFloor's IoCC.

Tutorial Source

WAR Application

The example WAR application to embed for this tutorial is located here.

It consists of two servlets. The first is a simple servlet:

@WebServlet(urlPatterns = "/simple")
public class SimpleServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().write("SIMPLE");
	}
}

The second servlet has an injected dependency:

@WebServlet(urlPatterns = "/inject")
public class InjectServlet extends HttpServlet {

	@Inject
	private ServletDependency dependency;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String value = this.dependency != null ? this.dependency.getMessage() : "NO DEPENDENCY";
		resp.getWriter().write(value);
	}
}

with the dependency as follows:

public class ServletDependency {

	public String getMessage() {
		return "INJECTED";
	}
}

Embedding the WAR

To embed a WAR application into OfficeFloor, include the following maven dependency:

		<dependency>
			<groupId>net.officefloor.jee</groupId>
			<artifactId>officeservlet_war</artifactId>
		</dependency>

Once included, the location of the WAR file must be specified. This is typically undertaken as a system property defined by OfficeFloorWar, i.e. -DOFFICE.war.path="/path/to/war"

Servlet Dependencies

Dependencies for the servlets are provided by OfficeFloor. This may either be through OfficeFloor directly. Or by incorporating a third party dependency injection library, such as Spring.

In the case of this tutorial, OfficeFloor is directly providing the dependency in application.objects:

<objects>
	<managed-object class="net.officefloor.tutorial.warhttpserver.InjectServletDependency" />
</objects>

with a custom dependency:

public class InjectServletDependency extends ServletDependency {

	@Override
	public String getMessage() {
		return "INJECT";
	}
}

Note that at runtime, the WAR classes are automatically included on the class path. However, for IDE development, the classes of the WAR need to be referenced:

		<dependency>
			<groupId>net.officefloor.tutorial</groupId>
			<artifactId>WarApp</artifactId>
			<version>${revision}</version>
			<classifier>classes</classifier>
			<scope>provided</scope>
		</dependency>

This is made available by flagging the WAR project to produce the classes artifact:

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<archiveClasses>true</archiveClasses>
					<attachClasses>true</attachClasses>
				</configuration>
			</plugin>

Testing

The following tests demonstrate embedding the WAR and invoking each servlet.

	@RegisterExtension
	public final MockWoofServerExtension server = new MockWoofServerExtension().property(OfficeFloorWar.PROPERTY_WAR_PATH,
			getWarPath()); // gets location of war file

	@Test
	public void simpleServlet() {
		MockWoofResponse response = this.server.send(MockWoofServer.mockRequest("/simple"));
		response.assertResponse(200, "SIMPLE");
	}

	@Test
	public void injectServlet() {
		MockWoofResponse response = this.server.send(MockWoofServer.mockRequest("/inject"));
		response.assertResponse(200, "INJECT");
	}

Next

The next tutorial covers using Servlets / Filters as procedures.