Warp :: Servlet + Wicket

Integrating warp-servlet with Apache Wicket.

Guice and Wicket

Apache Wicket is a neat component-oriented web framework. Wicket already has a thin Guice integration module, which allows wicket pages to be wired with Guice-managed objects. Notice that I did not say injected. Wicket's integration does not allow Guice to manage its pages, however it allows Guice to wire them up via setter and field injection with other Guice-managed objects and services (much like guice-servlet and InjectedHttpServlet does with Servlets).

Wiring Wicket up with Warp-servlet

First, read the guide on how to get warp-servlet running as a filter and using the WarpServletContextListener. Now, in your Wicket Application class override the init() method and add the following line:

	@Override
	protected void init() {
		addComponentInstantiationListener(Wicket.integrate(this));

That's it! The Wicket.integrate() call is provided by warp-servlet; internally it registers an instance of Wicket's GuiceComponentInjector that hooks into the warp-servlet's injector (typically, created in your WarpServletContextListener). This requires the wicket-guice and wicket-ioc modules (jars) to be available on the classpath. Don't forget guice-1.0.jar and warp-servlet.jar!

Well that was easy. 

A word about web.xml and WicketFilter

Unfortunately, WicketFilter itself cannot be managed by warp-servlet, this is because of some extra validation Wicket seems to do when it boots up (checking against the servlet configuration, and finding no WicketFilter there). However, your Wicket applications still benefit from all of warp-servlet's functionality (scopes, conversations, other managed-filters, etc.) so long as you ensure that WebFilter is registered above WicketFilter. Here is an example:

    <!-- warp :: servlet -->
<listener>
<listener-class>my.domain.SubclassOfWarpServletContextListener</listener-class>
</listener>

<filter>
<filter-name>warp-servlet</filter-name>
<filter-class>com.wideplay.warp.servlet.WebFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>warp-servlet</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- end warp :: servlet -->



<filter>
<filter-name>WicketApplication</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>

<init-param>
<param-name>applicationClassName</param-name>
<param-value>my.domain.MyWicketWebApp</param-value>
</init-param>
</filter>


<filter-mapping>
<filter-name>WicketApplication</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
 

Important things to remember

Remember that,

  • Wicket Pages are not created by guice, only wired by it. This means:
    • Wicket pages' methods cannot be intercepted by Guice AOP
    • Wicket pages cannot be constructor-wired by Guice
    • However, anything injected into a Wicket page *is* created & managed by Guice and can take advantage of AOP and constructor-wiring
  • Warp-servlet's WebFilter *must* appear above WicketFilter
  • WicketFilter cannot be managed by Warp-servlet in the Servlets.configure() call.

Conversation Scope with Wicket

TBD.