Matt RaibleMatt Raible is a writer with a passion for software. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.
You searched this site for "struts". 659 entries found.

You can also try this same search on Google.

Dependency Injection with SiteMesh

Let me start off by saying I think that both SiteMesh and Tiles are great frameworks. I was a long time user and fan of Tiles, and I think it's appropriate for certain situations. However, I've been a heavy user of SiteMesh since it passed the 10 minute test. While most heavy users of SiteMesh (the Atlassian guys come to mind) say that it can do everything that Tiles can do, these features are largely undocumented. This is my attempt to document a cool feature.

In a site I recently helped develop, we needed a couple of features:

  • A tabbed menu that highlighted the current tab based on which page you were on.
  • A bunch of "panels" on the right sidebar that changed according to the page.

To make this work, we used the meta tag functionality that SiteMesh provides.

Funny side/related note, I just googled for this tag and found this howto, which is similar to this one.

In our pages, we added the meta tags to set the active menu, as well as which panels to show in the sidebar:

<head>
    <title><fmt:message key="authorList.title"/></title>
    <meta name="menu" content="Authors"/>
    <meta name="panels" content="administration,blogs,events"/>
</head>

Then, in our decorator, we interpret these separately. First, we used Struts Menu (with Velocity) for the navigation system:

<c:set var="currentMenu" scope="request">
    <decorator:getProperty property="meta.menu"/>
</c:set>
<c:import url="/WEB-INF/pages/menu.jsp">
    <c:param name="template" value="/template/menu/tabs.html"/>
</c:import>

The menu.jsp page takes "template" as a parameter so we display the same menu links using a different Velocity template (for example, links at the bottom of the page).

<menu:useMenuDisplayer name="Velocity" config="${param.template}" permissions="rolesAdapter">

Then our tabs.html Velocity template uses the "currentMenu" attribute to determine which menu to highlight.

## displayMenu is defined in WEB-INF/classes/globalMacros.vm
#macro( menuItem $menu $level )
  #set ($title = $displayer.getMessage($menu.title))
  #if ($menu.url)
    #if ($menu.name == $currentMenu)
      <span class="current">
    #end
      <a href="$!menu.url" title="$title"><span>$title</span></a>
    #if ($menu.name == $request.getAttribute('currentMenu'))
      </span>
    #end
  #end
#end

#if ($displayer.isAllowed($menu))
    #displayMenu($menu 0)
#end

As far as the panel injection goes, that's processed using the following logic in our decorator:

<c:set var="panels"><decorator:getProperty property="meta.panels"/></c:set>
<!-- No panels set, use default set of panels -->
<c:if test="${empty panels}"><c:set var="panels" value="different,partners"/></c:if>
<c:forEach var="panel" items="${panels}">
    <c:import url="/WEB-INF/pages/panels/${panel}.jsp"/>
</c:forEach>    

Since this site used WebWork, the <ww:action> tag made it easy to give each panel independence. That is, each panel could load on its own, supply its own data, and not worry about the data being prepared beforehand. Here's an example:

<%@ include file="/common/taglibs.jsp"%>

<h2>Author Blogs</h2>

<ww:action name="'authors'" id="authors" namespace="default"/>

<div class="item">
    <ww:iterator value="#authors.authors" status="index">
        <a href="<ww:property value="blog.feedUrl"/>">
            <img src="${ctxPath}/images/icons/xml.gif" alt="XML Feed" 
                style="margin-right: 5px; vertical-align: middle"/></a>
        <a href="<ww:property value="blog.url"/>"><ww:property value="name"/></a>
        <br />
    </ww:iterator>
</div>

Of course, now that you can use Tiles with WebWork, Struts, Spring MVC and JSF - you could use Tiles for the injection and SiteMesh for the decoration.

Now if we could just get someone to write a JSF Decorator for SiteMesh, like Erik Hatcher did for Tapestry.

Posted in Java at Feb 16 2006, 09:57:23 AM MST 6 Comments

How to use Tiles with WebWork

This evening, I created a TilesResult for WebWork that allows you to use Tiles with WebWork. For the following to work in your application, you'll need a nightly build of Tiles, commons-digester (which Tiles requires) and this patch for WebWork. For your convenience, I've posted a patched webwork-2.2.2.jar (with TilesResult).

I also posted a webwork-tiles.war that you can try and download yourself. It's based on Equinox, so you will need to setup PostgreSQL and an "equinox" database - or you can just change the database settings in WEB-INF/lib/jdbc.properties.

On to the instructions:

1. In your web.xml file, you need to add a servlet entry for TilesServlet to load the tiles definitions into the ServletContext.

    <servlet>
        <servlet-name>tiles</servlet-name>
        <servlet-class>org.apache.tiles.servlets.TilesServlet</servlet-class>
        <init-param>
            <param-name>definitions-config</param-name>
            <param-value>/WEB-INF/tiles-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

2. In xwork.xml, use type="tiles" on your <result>.

    <action name="editUser" class="userAction" method="edit">
        <result name="success" type="tiles">userForm</result>
        <result name="input" type="tiles">userList</result>
    </action>

I'm sure WebWork has a way of making this result type the default, I just haven't found it yet.

Hat tip to Spring's TilesView (source) for showing how to make this work.

Update: While I'm a happy SiteMesh user, I've recently had some clients who were more interested in Tiles. This largely inspired me to see if WebWork + Tiles was possible.

Update 2: It looks like TilesResult will be included in WebWork 2.2.2. Now if we could just get the Tiles team to cut a release.

Posted in Java at Feb 16 2006, 01:08:42 AM MST 3 Comments

Large sites powered by Java web frameworks and Tiles + WebWork

Yesterday, I delivered a Comparing Web Frameworks seminar that included Struts, Spring MVC, WebWork, JSF and Tapestry. This was for a client that's in the process of re-working an extremely high traffic site (50+ servers currently) from Servlets + JSPs to a web framework. They love the idea of Tiles (and know how to use it) as well as plan on integrating many Ajax features.

We quickly eliminated Struts because of ActionForms since they're planning on moving to persisted POJOs. Spring MVC and JSF had a notch up because they work with Tiles. However, JSF has reportedly had scalability issues. Furthermore, it's the most-complained about framework out there. One attendee noted how she was impressed with the low number of complaints about WebWork.

WebWork doesn't integrate with Tiles (but probably will soon) and they were concerned about SiteMesh performance with large pages (1MB + of text). While I believe SiteMesh can do almost everything that Tiles can do, I also agree that Tiles is a good technology. Furthermore, the "advanced features" of SiteMesh to be largely undocumented, which can be a barrier for adopting it as a "development standard".

Spring MVC was dinged because it doesn't have built-in Ajax support like WebWork and Tapestry (via Tacos). However, it's support for Tiles might just make it the one they choose - especially since they plan on using Spring in the middle-tier/backend. While they loved the idea of Tapestry, they didn't think they could afford the learning curve and I don't know enough about the @Border component to verify if it has all of Tile's functionality.

One interesting thing that came up was the list of high-volume sites using these various web frameworks. Tapestry seems to come out on top when you look at the list of well-known sites. However, I'm sure there are plenty I don't know about. If you know of high-volume sites using any of these five frameworks, please let me know. I'm looking for major sites with millions of hits per day. Here's my current list (extra points for fancy templating with SiteMesh/Tiles + Ajax widgets):

  • Struts: None that I know of off the top of my head, but I'm sure there are plenty.
  • Spring MVC: None that I know of.
  • WebWork: JavaBlogs (don't know if this exactly qualifies as high-volume, there aren't that many Java developers). WebWork also has a few products based on it (i.e. Jive, JIRA, Confluence), but these companies also employ WebWork committers.
  • JSF: None that I know of.
  • Tapestry: NHL.com, TheServerSide.com (similar comments to JavaBlogs) and Zillow.com.

Thanks!

Related: How To use Tiles like SiteMesh and SourceLab's Web application technologies comparison (with performance numbers!).

Update: FWIW, I figured out How to use Tiles with WebWork and wrote a short howto for doing dependency injection with SiteMesh.

Posted in Java at Feb 15 2006, 11:55:57 AM MST 30 Comments

This week at Apache with Ted Husted

Ted Husted gives a nice review of what's happening at Apache with Struts and Roller. Pretty cool to see him offering Struts Training as well. I wonder if most Struts 1.x users will upgrade to Struts Action 2.0 (a.k.a. WebWork)?

Posted in Java at Jan 27 2006, 07:13:09 AM MST 1 Comment

Learn about WebWork 2.2 and Tapestry 4.0 via Podcasts

podcastI've said in the past that Podcasts are boring. I still think this is true for the most part, but that's largely because most of them aren't appealing to me. However, this week I've found a couple of good ones. Tapestry 4.0 and WebWork 2.2 have recently been released, and now you can listen to interviews with both project's primary developers: Patrick Lightbody of WebWork and Howard Lewis Ship of Tapestry/Hivemind. The easiest way I've found to subscribe and listen to podcasts is to download iTunes. You also may want to checkout The Java Podcasters article on ONJava.com.

I hope to upgrade both Equinox and AppFuse to these releases in the near future, I just need to find the time. I also hope to change the default web framework in AppFuse to Struts Action 2 as part of AppFuse 2.0. This will allow us to ditch Struts and WebWork and only support 4 web frameworks (SA2, Spring MVC, Tapestry and JSF).

Posted in Java at Jan 26 2006, 08:22:02 AM MST 4 Comments

Spring Workshops from Virtuas

I'm pleased to announce that my company, Virtuas, has decided to start offering public workshops for many prominent open source projects. These include Spring, Geronimo, Tomcat, Hibernate and JSF/MyFaces.

I'll be teaching the first Spring course in Denver February 21st - 24th, followed by one in Boston in mid-March. It should be a fun class, especially since I'm adding a bunch of stuff regarding Spring 2.0. Since I know you're going to ask the price -- and it's not posted on virtuas.com -- it's $2,495 per person for 1-4 people from the same company/group/etc., $1,995 per person for five or more people.

In other Virtuas news, we've recently signed partnership agreements with IBM and Covalent. We also re-worked our site with Andreas Viklund's "andreas08" theme from Open Source Web Design. Thanks to the power of Drupal, all we had to do to change the whole site was modify one PHP template and one CSS file. Thanks to both Andreas and Drupal for vastly simplifying our new look-n-feel.

Update: It looks like Andreas's theme has been made into a Drupal theme. Nice.

Posted in Java at Jan 24 2006, 05:06:14 PM MST 10 Comments

The future of the DisplayTag Library

From the displaytag-devel mailing list:

I am sorry if I am asking a stupid question but is there any activity going on in the project? There are no new releases for almost a year... Neither are there any news on the project page. In our project we have modified the 1.0 version a bit and would like to share these changes with the community.

Fabrizio's response:

See http://displaytag.sourceforge.net now ;)

the website was frozen to the last 1.0 release, also due an extensive refactoring to the build/documentation system (migration to maven 2, splitting of optional modules and examples, ...) but activity on the project never stopped.

1.1 is now near, and I switched the default homepage to the 1.1 documentation. Warning: it's not released yet, but nightly builds are up.

The biggest feature of 1.1 has to be the ability to do external sorting and paging.

If you're looking for Ajax support in the displaytag, look no further than AjaxTags. I haven't been able to get ajax:displayTag working in my projects because I'm using a newer version of Prototype. However, it looks like the next version of AjaxTags supports the latest version of Prototype.

In addition to AjaxTags, you can also use AjaxAnywhere. Here's the code you'll need to do that (after adding AjaxAnywhere to your project):

<aa:zone name="userTable">

<display:table name="users" class="list" requestURI="" id="userList" export="true" 
    excludedParams="*" pagesize="5" sort="list">
    <display:column property="id" sort="true" href="editUser.html"
        paramId="id" paramProperty="id" titleKey="user.id"/>
    <display:column property="firstName" sort="true" titleKey="user.firstName"/>
    <display:column property="lastName" sort="true" titleKey="user.lastName"/>
    <display:column titleKey="user.birthday" sort="true" sortProperty="birthday">
        <fmt:formatDate value="${userList.birthday}" pattern="${datePattern}"/>
    </display:column>
</display:table>

</aa:zone>

<script type="text/javascript">
    ajaxAnywhere.getZonesToReaload = function() { return "userTable" }
    ajaxAnywhere.onAfterResponseProcessing = function() { replaceLinks() }
    function replaceLinks() {
        // replace all the links in <thead> with onclick's that call AjaxAnywhere
        var sortLinks = $('userList').getElementsByTagName('thead')[0]
                                     .getElementsByTagName('a');
        ajaxifyLinks(sortLinks);
        if (document.getElementsByClassName('pagelinks').length > 0) {
            var pagelinks = document.getElementsByClassName('pagelinks')[0]
                                    .getElementsByTagName('a');
            ajaxifyLinks(pagelinks);
        }
    }
    function ajaxifyLinks(links) {
        for (i=0; i < links.length; i++) {
            links[i].onclick = function() {
                ajaxAnywhere.getAJAX(this.href); 
                return false;
            }
        }
    }
    replaceLinks();
</script>

Libraries used in above code: AjaxAnywhere 1.0.2, DisplayTag 1.0 and Prototype 1.4.0_pre4. You can also see a demo online or download the code.

Posted in Java at Dec 29 2005, 10:46:56 AM MST 26 Comments

[ANN] Equinox 1.5 Released

This release's major new feature is dependency downloading using Maven 2's Ant tasks. The main reason I used Maven 2 over Ivy is because I've heard rumors that Ant 1.7 will include dependency downloading - and they're planning on integrating the work that Maven has already done.

One of the nice things about using Maven 2's Ant Tasks, is you can download Maven 2 and generate your Eclipse or IDEA (possibly even Netbeans) project files using "mvn eclipse:eclipse" or "mvn idea:idea". You can also use Maven 2 to build and test things if you like. The only thing that doesn't currently when using Maven to test Equinox is the web tests with Cargo. I can try to get those working if there's enough demand. For now, you'll have to use Ant if you want to test the UI.

All of the frameworks used in Equinox, as well as its build/test system is explained in Spring Live. A summary of the changes are below (detailed release notes can be found in JIRA):

  • Removed packaged JARs in favor of Maven 2's Ant Tasks. Dependencies are now downloaded on-demand, greatly reducing the size of Equinox-based applications.
  • By specifying compile, test and runtime dependencies in a pom.xml file, Equinox applications can now be built with Maven 2. The only difference between building with Maven 2 and Ant (at this time) is that the M2 build does not support testing with Cargo. However, there is an M2 Cargo plugin so this shouldn't be hard to fix if you have that itch.
  • Added DWR, Script.aculo.us and Prototype to simplify Ajax development.
  • Added Beandoc support - simply run "ant beandoc" to see javadoc-style documentation of Spring context files.
  • Refactored UserManagerTest to be UserManagerImplTest; renamed UserManagerIntegrationTest to UserManagerTest.
  • Changed BaseDAOTestCase to extend AbstractTransactionalDataSourceSpringContextTests.
  • [Hibernate] Added example ehcache.xml to web/WEB-INF/classes for default cache settings.
  • [JSF] Removed client-side validation because corejsf-validator.jar causes issues with Spring's Ant-style path matching.
  • [Spring] Fixed number editor and edit logic in UserFormController.
  • [Struts] Fixed issue with installation where ContextLoaderPlugin was loading ApplicationContext a 2nd time b/c the listener was not being commented out.
  • Dependent packages upgraded:
    • Cargo 0.6
    • Hibernate 3.1
    • iBATIS 2.1.6
    • JPOX 1.1.0 Beta 4
    • MyFaces 1.1.1
    • PostgreSQL JDBC Driver 8.1 Build 404
    • Spring 1.2.6
    • Struts 1.2.8

Download. For more information about installing the various options, see the README.txt file.

Demos:

The basic Equinox download contains all the various web and persistence framework options in the "extras" folder. If you have issues replacing the web framework or persistence engine, please enter an issue in JIRA and I'll build and upload a customized version for you.

Posted in Java at Dec 28 2005, 07:14:43 AM MST 4 Comments

Struts 1.2.8 has client-side validation issues just like 1.2.7

This weekend, I upgraded AppFuse from Struts 1.2.4 to 1.2.8. After failing to upgrade to 1.2.7, I was a little leary of this release - for good reason. It turns out, the 1.2.8 release has the same client-side validation issue as 1.2.7. The good news is it's a Commons Validator issue this time, and you can fix it by upgrading to Commons Validator 1.2.0 (it ships with 1.1.4).

If you're using custom client-side validators, you might have to patch your functions. Here's what I did to mine:

- oTwoFields = eval('new ' + formName.value + '_twofields()');
+ oTwoFields = eval('new ' + retrieveFormName(form) + '_twofields()');

Also, if you'd like to use Spring MVC with Commons Validator 1.2.0, you'll need to patch springmodules-validator. Or you can just download the one from AppFuse's CVS.

Posted in Java at Dec 19 2005, 04:55:37 PM MST 2 Comments

The Ajax Experience

The Ajax Experience looks like it's going to be an excellent show.

We will have the website for the conference launched just after christmas, but here is a taste of the quality speakers that we have confirmed for the event:

  • Scott Dietzen, CTO of Zimbra
  • Alex Russell and Dylan Schiemann of the Dojo Toolkit
  • Thomas Fuchs of Script.aculo.us
  • Sam Stephenson of Prototype and 37 Signals
  • Bob Ippolito of MochiKit
  • Joe Walker of DWR
  • Douglas Crockford of JSON-RPC, and Yahoo!
  • Jonathan Hawkins of Microsoft Atlas
  • Patrick Lightbody of WebWork/Struts Ti
  • Bill Scott of Rico and Yahoo!
  • Eric Pascarello of Ajax in Action
  • Glenn Vanderburg, JavaScript expert
  • Brent Ashley, noted Ajax expert
  • Michael Mahemoff of Ajax Patterns
  • Greg Murray of the JavaServer Faces team at Sun

This is a show I'd love to attend. However, it ends the day before Mother's Day - WTF is up with that?! For those of us who happen to be family men and are planning on attending JavaOne, this sucks. If I want to attend The Ajax Experience, I'd have to fly back on Sunday and then fly back to San Fran on Monday for JavaOne. Booo hisss. Looks like I'll be missing this show.

Posted in Java at Dec 19 2005, 01:12:15 PM MST 4 Comments