javaee

Spring Portlet MVC Implicit Model

under

Do you use Spring Portlet MVC? Have you ever noticed the ImplicitModel request parameter in your URL? It looks something like:

org.springframework.web.portlet.mvc.ImplicitModel=true

Well, it’s a Spring Portlet MVC 2.5 feature and I was scratching my head trying to figure out what it does. It’s set by Spring under the covers, so I dug into their source code to understand it and thought I would share.

The ImplicitModel is defined in Spring’s AnnotationMethodHandlerAdapter (which I describe in another post on annotation-driven portlet development w/Spring). In short, the AnnotationMethodHandlerAdapter is primarily responsible for scanning the @RequestMapping annotations on a given controller and executing the best matching method. It also sets and retrieves the ImplicitModel on portlet requests.

So what does the ImplicitModel do? Well, because most portal implementations redirect to the render phase after an action request (applying the post-redirect-get pattern), request attributes set in the action can’t be used in the subsequent render phase.

Spring Portlet MVC uses the ImplicitModel to overcome this limitation. On an action request, if the request’s model (see ModelMap class) isn’t empty, the AnnotationMethodHandlerAdapter will automatically store the ModelMap in portlet’s session for use on the upcoming render request. It also sets the render parameter (org.springframework.web.portlet.mvc.ImplicitModel), to tell the render phase to pre-load its model from the ImplicitModel stored in the session.

One additional tip: after a successful action method call, you may want to manually clear the model to prevent the action model data from being stored in the ImplicitModel. As an example, say you submit a form in an action request and render the same form with a success message after a successful submission. If you don’t want to display the originally submitted data on the success view - call ModelMap.clear() to prevent it from being stored as an ImplicitModel.

Annotation-based Spring Portlet MVC Lifecycle

under

Jared Richardson spoke at a Richmond Java Users Group meeting I attended last week; his topic was about investing in yourself and your career - what he called career 2.0. At one point during the presentation, he noted that “if you can’t draw something, you don’t understand it”, which motivated me to finish a blog post I started a while back about Spring Portlet MVC.

I gave a presentation at CapTech’s Feed Your Brain series about using Spring Portlet MVC’s annotation-driven development style, and I wanted to diagram how the lifecycle works under the covers.

The following diagram never made it into the presentation so I wanted to post it here.

Sorry if the graphic doesn’t blow you away; I have an older version of OmniGraffle - but want to get one of these.

So, in short the graphic depicts:

  1. like most implementations of the Front Controller pattern, the DispatcherPortlet sits in front of all PortletRequests
  2. if a DefaultAnnotationHandlerMapping is set as the default HandlerMapping implementation in your Portlet’s Spring application context, the DispatcherPortlet will use it to find a @Controller
  3. the DefaultAnnotationHandlerMapping itself searches your application context for the best matching class annotated as a @Controller
  4. the DefaultAnnotationHandlerMapping then passes control back to the DispatcherServlet, which then needs a AnnotationMethodHandlerAdapter to determine which method to call on your controller
  5. the AnnotationMethodHandlerAdapter then checks for methods annotated with @RequestMapping and, again, finds the “best match” method to handle the PortletRequest
  6. the request is served, and control is passed back to the DispatcherPortlet - voila!

Hope this is helpful to those looking to use Spring Portlet MVC’s nifty annotation model.

Compress your JBoss Portal Theme with pack:tag

under

The goal of this article is to show you how to use pack:tag to optimize the performance of your JBoss Portal theme. I’ve used this approach on a production JBoss Portal 2.6 implementation and tested the approach out in version 2.7.

JBoss Portal has a feature-rich theme framework where CSS and javascript resources are included in the Portal; building a custom theme is easy. Pack:tag is an open source project that optimizes performance for java-based web apps; it provides a JSP tag library that automatically minifies, compresses, and combines CSS and javascript resources.

As more rich features and dynamic components reach your portal, larger AJAX frameworks and CSS libraries are required to support them. Large downloads will not only make your Portal load slower, but will also take longer to execute when using the Portal. Also, Portals are no longer accessed solely inside the firewall, many companies use them to power external facing sites - so few assumptions should be made about client bandwidth. Compressing your Portal theme with pack:tag will lead to faster downloads and page response time.

Building a custom Portal theme is covered in depth elsewhere, so we won’t get into that here. Instead, let’s look at the steps necessary to get your theme working with pack:tag:

Install pack:tag

  • Place the packtag-X.X.jar in the WEB-INF lib of your theme. To use pack:tag with one of the out of the box themes, place the packtag JAR at: [PS_HOME]/server/default/deploy/jboss-portal.sar/portal-core.war/WEB-INF/lib
  • You’ll also want to place the packtag.properties file in WEB-INF

Pack Your Theme

  • By default, you should have theme resources defined in a *-themes.xml file - because pack:tag uses a tag library, we have to move these resources from the XML file and put them into your layout JSP page.
  • Add the pack:tag tld reference to your layout JSP:
    
    <%@ taglib prefix="pack" uri="http://packtag.sf.net" %> 
    
  • Wrap the resource references in the pack:tag; for our custom theme this looks something like:
    
    <pack:style>
    	<src>/styles/extjs/css/ext-all.css</src>
    	<src>/styles/extjs/css/xtheme-gray.css</src>
    	<src>/styles/app.css</src>
    </pack:style>
    
    
    <pack:script>
    	<src>/scripts/jquery/jquery.js</src>
    	<src>/scripts/extjs/adapter/jquery/ext-jquery-adapter.js</src>
    	<src>/scripts/extjs/ext-all-debug.js</src>
    </pack:script>
    

Limitations and Gotchas

  • In JBoss Portal themes, layouts and themes are loosely coupled: layouts are used to generate markup, while themes include CSS and javascript references to style the layout. If you’ve written a JBoss Portal theme before, you’re probably thinking that we just tightly coupled the layout and theme.
  • Well, this is true - but, it turns out that the mechanism that provides the loose coupling has some problems out of the box. For one thing, Portal reorders your script and CSS references in the worst possible way (placing all the links after the scripts). This violates Yahoo’s best practices for website performance.
  • So, we can work around the tight coupling we’ve added by creating an additional JSP include file that will store the css/js references for your custom theme(s). You can then dynamically reference the active theme to load the appropriate theme files. The following snippet will do the trick for JBoss Portal 2.6.X:
    
    <jsp:include page="includes/theme-${requestScope['RENDERCONTEXT'].themeContext.theme.themeInfo.name}.jsp" />
    
  • Additionally, introducing pack:tag can also cause unexpected issues with your theme. Because pack:tag combines all your resource requests into a single request (see the first Yahoo performance rule), image references in CSS files can break. So if you get 404s on resource requests after enabling pack:tag, you’ll know what to debug.

Example

Check out the following Firebug screen shots depicting the actual file size savings in our custom theme:

tag

Custom Theme CSS Before pack:tag

tag

Custom Theme CSS After pack:tag

tag

Custom Theme JS Before pack:tag

tag

Custom Theme JS After pack:tag

Results

That’s right! Adding pack:tag resulted in:

  • Total CSS file size downloaded went from 141KB to 21KB - ~15% the original size
  • 6 HTTP requests for CSS reduced to 2
  • Total javascript file size downloaded went from 2MB to 188KB - ~10% the original size
  • 21 HTTP requests for javascript reduced to 1

References and Tools

Subscribe to Feed