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 "mvc". 279 entries found.

You can also try this same search on Google.

There's a new sorting and paging taglib in town

From the Apache News Blog, I found there's a new sorting and paging taglib in town. We already have the Display Tag and the Value List Handler, but now we have the Data Grid. It looks pretty good too - although it doesn't seem to support/enforce XHTML. For your viewing pleasure, I've setup a demo. To be fair, you can also checkout the Value List Handler Demo and the Display Tag Demo.

Posted in Java at Sep 16 2004, 09:15:54 PM MDT 19 Comments

Going to ApacheCon?

Are you heading to ApacheCon this year? I am.

Thank you for your recent session proposals for ApacheCon US 2004.

The following session has been accepted and scheduled.

  (1010) 'Comparing Web Frameworks: Struts, Spring MVC, WebWork, Tapestry & JSF'

You will receive more information about this soon,
if you haven't already.

Vegas baby. :-P

Posted in Java at Aug 27 2004, 03:48:48 PM MDT 5 Comments

My Tiles to SiteMesh Migration

I spent a few hours last night replacing Tiles with SiteMesh in AppFuse. I had the Struts version done in 2 hours, and most of the Spring version done in an additional hour. Then I spent another 3 hours today twiddling with things and getting it just right. During this process, I discovered a few things I thought I'd share. Keep in mind that I'm pretty much a SiteMesh rookie. Hopefully, implementing and using it in AppFuse will help me to fully understand its power.

  • SiteMesh lacks injection. Tiles allows you to inject JSP fragments into your base layout on a per-page basis. I didn't use this feature much, but I did use it to determine which menu should show up on what pages. For example, the login page would get a "projects used" menu, the signup page wouldn't have a menu, and all other pages would get the standard site menu. With SiteMesh, all of this seems to be done best with JSP includes and some <c:if> logic in your decorator. I ended up using <c:import> in my login.jsp for the login menu, importing nothing for signup, and using <c:if> statements in my decorator to see if the user was logged in. If they were, then I import the site menu and its necessary scripts and styles. In the end, this worked fine and it's probably easier for new AppFuse users to understand - so that's a good thing.
  • Injecting scripts and stylesheets. With Tiles, I was able to easily control which scripts and stylesheets were shown on each page. With SiteMesh, this is pretty easy to do by putting them in the <head> element of your page. However, what I would've really liked to see is the ability to put these in an included JSP and have them end up in the <head> of the final document. I know it's virtually impossible, but it would be cool.
  • Headings. Adding a <title> title element per-page works great using the <title> tag. However, if you want to add a heading (which I specify with an <h1> tag), you have to use a <content> tag. It would be cool if I could somehow use <h1> or <heading> in my page to indicate a heading. I ended up going with the following in each page to specify the title and heading:
    <title><fmt:message key="mainMenu.title"/></title>
    <content tag="heading"><fmt:message key="mainMenu.heading"/></content>
    There's probably an easier way to do this, but this works for now.
  • Injecting <body> ids. Using body ids to set styles on a per-page basis is a great way to control CSS. With Tiles, I set this as an attribute in tiles-config.xml and then grabbed/used it with the following JSTL code:
        <c:set var="bodyId" scope="request">
            <tiles:getAsString name="body.id" ignore="true"/>
        </c:set>

    <body<c:if test="${not empty bodyId}"> id="<c:out value="${bodyId}"/>"</c:if>>
    Yeah, it's ugly, but it works. With SiteMesh, you can easily set a body id by using <body id="name">. In fact, you don't even need to wrap your content with it, you can simpley do <body id="name"/>. I'm grabbing and using this in my decorator with the following code. This works, but it would be cool if I could check for the existence of the attribute first - so I could eliminate id="" when no body id is set.
    <body id="<decorator:getProperty property='body.id'/>">
  • Inheritance. With Tiles, you could extend page definitions and override attributes. This feature seems to be completely lacking in SiteMesh. I don't know how you could implement it, but it would be nice to have something where you could specify the parent - for instance, to use the same <head> content.
  • Error page decoration. SiteMesh seems to be incapable of decorating error pages (i.e. 404) in Tomcat 5.0.x (even if I add <dispatcher>ERROR</dispatcher> to the filter-mapping). A workaround is to use wrap the error page with a <page:applyDecorator> tag. This works, but if you specify elements in <head>, they will end up in the body of page, rather than in the decorator's header.
  • SiteMesh simplifies. Switching from Tiles to SiteMesh allowed me to delete somewhere around 8 JSPs. AppFuse has 34 after committing everything. Most of these were JSPs that sat in the root folder and had a one-liner to pull in a Tiles definition. However, it also eliminated 11 JSPs from the Spring MVC install - allowing reduction of duplication. The Spring MVC install now has 17 JSPs.

So there you have it. AppFuse now uses SiteMesh instead of Tiles! I'm sure the implementation will get cleaner and more refined as more folks use it. I'm looking forward to deleting some chunks out of AppFuse's tutorials because SiteMesh makes page development so much easier. The hardest part of SiteMesh is setting up the infrastructure. Once you're got that done, you hardly ever touch it again.

Next task: WebWork integration.

Posted in Java at Aug 21 2004, 11:50:50 PM MDT 14 Comments

Should I ditch Tiles in AppFuse?

I've haven't been developing applications with AppFuse since May. Instead, I've been using Equinox. One of the main things in Equinox I've grown to love is SiteMesh. It's worked in all the webapps I've written, which utilize frameworks like Struts, Spring MVC, WebWork, Tapestry and JSF. Tiles will only work in 3 of those.

I think it's time to make an executive decision on AppFuse and ditch Tiles in place of SiteMesh. It's faster and easier to develop with, and it doesn't get in your way. In fact, I didn't have to change a single line of SiteMesh-related code to support any of the aforementioned frameworks. Furthermore, using SiteMesh would also greatly reduce the duplicate between frameworks. I've thought about keeping Tiles around, but it's a pain in the ass to maintain parallel sets of documentation.

Whaddya think - any reason you can think of to keep Tiles? I can't. In fact, I think I'd cringe if I had to start my next AppFuse-based project w/o SiteMesh.

Posted in Java at Aug 18 2004, 10:11:56 AM MDT 33 Comments

My JSF Experience

Of all the MVC Frameworks I've developed with in the last few weeks (Struts, Spring MVC, WebWork and Tapestry) - JSF was by far the worst. And it's not the implementations that are the problem, it's the spec itself (as far as I can tell). Plain and simple, it does not simplify web development.

I spent 3 days developing a simple JSF app - most of it which I had done in the first day. The last 2 days have been spent migrating to MyFaces and trying to find clean ways to do things. My perspective on JSF after this experience? Run away. Run far, far away. All of the above mentioned frameworks are MUCH superior to this technology. Let's get on with the things I learned.

  • MyFaces handles duplicate posts nicely. If you hit "reload" on your browser after saving a record, you get presented with an empty form rather than a duplicate record. I believe I got a duplicate record with Sun's RI.
  • The ability to specify an "action" attribute on a button (or a link) and them map that action to a page (in faces-config.xml) is pretty cool.
  • Every button or link clicked results in a form post. That's just wrong - why can't I have true links like the web is supposed to? So much for bookmarks.
  • Saving state on the client results in enormously long URLs and/or hidden fields.
  • JSF support is fairly non-existent. Unlike the other MVC frameworks, the MyFaces mailing list has hardly any traffic and the Sun forums aren't much better.
  • The MyFaces website seems to be down whenever I want to look something up on it, like right now.
  • I did find some CRUD examples, like this this one, but was disappointed to find that i18n is not considered for setting success messages. I ended up using the solution described in this post. 6 lines of code to set a success message - you've got to be kidding me! Most frameworks have a simple 1-2 liner.
  • Waiting for JSPs to compile the first time has surprisingly become painful after using Tapestry, Velocity and FreeMarker for the last 2 weeks.
  • Integration with Spring is fairly easy (code is in CVS), but MyFaces spits out an error when it shouldn't be.
  • Validation messages are ugly. For instance, when a required field isn't filled in, I get: "lastName": Value is required. I was able to override the default messages, but I was never able to use the label of the field (vs. the field's id).
  • The <h:messages> tag is practically worthless. Sure it's great for displaying messages (error and success), but that's about it. It has a "layout" attribute that doesn't even work in Sun's RI, and in MyFaces it just wraps a <span> with a <ul><li> or a <table>. Both of these layouts are useless b/c you can't set a css class on them. I ended up using "table" and having to set a generic CSS rule (width: 100%) in order to get the message/error bar to show across the top of my page. This tag also doesn't allow you to escape HTML.
  • The <h:dataTable> component is nothing like the displaytag. MyFaces claims to have a pageable/sortable component, but it requires custom logic/methods in your managed-bean. Yuck. I ended up using <h:dataTable>, which has neither sorting or paging. This is only because I couldn't get an <h:commandLink> working inside a displaytag column.
  • JSF-created apps are pretty much untestable. Managed-beans are testable, but the UI seems really difficult with jWebUnit and Canoo's WebTest. IMO, it should be possible to specify a URL to edit a record (i.e. editUser.html?id=2). With JSF and my master/detail app, the link to edit actually sets about 5 hidden form fields with JavaScript and then submits the form. I could probably figure the URL out, but it'd be ugly. Also, the MyFaces <h:dataTable> will not render an "id" attribute if you specify one. This is needed to verify tables and their data with jWebUnit.
  • When using "ant reload" to reload my application (using Tomcat's Ant Tasks), I kept encountering a ThreadDeath error. This seems to be specific to MyFaces as I never saw it with other frameworks or Sun's RI.

Like Tapestry, I felt like I was banging my head against the wall a fair amount. However, with Tapestry (and all the other frameworks), I was able to get exactly the behavior I wanted w/o too much work. I could produce clean and user-friendly error messages - (Tapestry already had clean required messages built in). I was able to write a jUnitWebTest to test all CRUD activities. With JSF, I was able to test one thing - adding a new record. I couldn't edit it b/c the JavaScript support (which I tend to not use) puked every time it encountered a JSF-generated JavaScript function.

My opinion after all of this? If you know Struts, Spring MVC and WebWork are fairly easy to learn. WebWork is simpler and elegant, but Spring MVC supports more view options out-of-the-box. Tapestry is cool, but you'll have to invest a lot of time into learning it and you'll probably get caught up in its cult and forever be claiming "Tapestry Rocks!" which can get annoying to your fellow developers. ;-) Finally, I can confirm that SiteMesh rocks - it worked for all the frameworks I used and I never had to change a single line of code.

Whatever you do, don't use JSF. Not yet anyway.

Posted in Java at Aug 06 2004, 04:53:22 PM MDT 76 Comments

The Joy of developing with JSF

I plan to write up a "My JSF Experience" post later today, but first, I'm forced to rant on the state of JSF implementations. First of all, I must say that JSF isn't so bad. It's cool how you can map buttons to "actions" defined in a navigation entry, as well as to call a method in a managed bean. The problem that I'm experiencing is that the JSF implementations, both from Sun and MyFaces - are errrrr, not so good.

I actually managed to almost finish my simple JSF sample app in one day, but then decided to shoot off some questions to see if I could resolve some remaining issues. Then based on feedback I received, I decided to switch from Sun's RI to MyFaces - not only for the "sortable" grid (I still don't know if it exists), but also Spring supports it w/o using an add-on library.

Ever since I switched, things just haven't gone right. First of all, MyFaces, requires your implement a <listener> in web.xml - who knows why, but you get an error indicating you need it if you don't have it. Standard JSF doesn't require this - why does MyFaces?

OK, I can deal with adding the listener. Everything works as with Sun's RI - and even better since the "layout" attribute of <h:messages> actually works. BTW, why isn't "div" a choice instead of "table" - whoever designed these choices obviously still uses Netscape 4 and table-based layouts. I'm happy now. MyFaces seems to solve the duplicate post issue so if you refresh after adding a record, it just shows a blank form. Cool, I can live with that.

One problem I found, that likely exists in both implementations, is that it's a true pain-in-the-ass to get a declared ResourceBundle in a managed-bean. Here's the method I'm currently using to add a success message:

    public void addMessage(String key, String arg) {
        ApplicationFactory factory = (ApplicationFactory)
            FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
        String bundleName = factory.getApplication().getMessageBundle();
        ResourceBundle messages = ResourceBundle.getBundle(bundleName);
        MessageFormat form = new MessageFormat(messages.getString(key));

        String msg = form.format(new Object[]{arg});
        FacesContext.getCurrentInstance().addMessage(null, 
                new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
    }

There has to be an easier way! Please tell me there is. I admit that I'm a JSF rookie - having just started using it two days ago, but it seems ridiculous that all the "success message" examples out there don't even consider i18n.

So now I have my success messages working, but I discover that there's no way to escape HTML (using <h:messages>) from my ResourceBundle (to put bold around a part of the message). ALL of the other MVC frameworks I've been dealing with allow this - why doesn't JSF?! Again, I'm hoping someone tells me I'm ignorant and there is a way to do this.

Lastly, I tried to upgrade to the latest MyFaces snapshot from CVS to solve this bug and now I can't even get my fricken app to start up because of this issue. Are these the hoops that developers have to go through to get started with JSF? Thump, thump, thump. My head is starting to hurt.

Update: I'm an idiot about the "can't get my app to start thing" - I didn't copy all the new myfaces*.jar files into WEB-INF/lib. Heh. =P~

BTW, MyFaces requires a whole slew of JAR files just like Struts. Here's my current inventory:

  commons-codec-1.2.jar
  commons-collections-3.0.jar
  commons-digester-1.5.jar
  commons-validator.jar
  commons-oro.jar
  commons-logging.jar
  jstl.jar
  myfaces.jar
  myfaces-components.jar
  myfaces-jsf-api.jar

Posted in Java at Aug 06 2004, 10:35:05 AM MDT 4 Comments

My WebWork Experience

Yesterday I began converting a small application from Spring MVC to WebWork. By the end of the day I was pretty much finished, but shot an e-mail off the the user's list to figure out a few more things. Today was spent incorporating that knowledge and making the app follow more WW "best-practices". Below is a list of things I discovered:

  • WebWork's documentation is actually quite good. I was able to figure out most things just by reading it. I'm still surprised that most web app frameworks don't describe a simple CRUD operation as their first example. In my experience, CRUD is 80% of a webapp's job.
  • WebWork integrates with Spring quite nicely. It's interesting to see that Spring has most of its MVC Framework support as part of the core, but WW has its own. I wonder why? Who cares, it works!
  • WebWork is a bit better than Spring MVC in that they have a mechanism for saving/displaying success messages. However, it doesn't live past a redirect, so you're still stuck putting messages in the session. Struts (as of 1.2.1) allows you to use a saveMessages(session, messages) call - and subsequent JSP tag to display (and automagically remove). Like it or not, Struts seems like the easiest solution for developers to use.
  • There's no clean mechanism for cancelling validation when a user clicks on a "cancel" or "delete" button. Struts supports cancelling using it's <html:cancel> button and it's pretty easy to detect "delete" and cancel validation in a form's validate() method. I ended up using an onclick handler for my cancel button and not worrying about validation on delete. This is the way I did it with Struts for years. Spring is cool in that it has a processFormSubmission() method that you can override before validation kicks in.
  • With Commons Validator, I'm used to specifying generic validation messages like "errors.required={0} is required.". This is possible with WW by using "errors.required=${getText(fieldName)} is required.". However, WW is a bit unique in that validation rules and ResourceBundles are defined on a per-action basis. I like having a central location for all my messages - like Spring and Struts have. I know it's possible with WW, but I'm trying to develop a "best-practices" sample app.
  • I really dig that fact that you can use one JSP tag to render an entire <tr> in a table. This <tr> ends up having a label and an input field - which is very cool IMO. I did find some issues with the XHTML output, but found it very easy to submit patches. Good stuff.
  • The config files (xwork.xml and validators.xml) must be in WEB-INF/classes. This is because they're XWork configuration files, and XWork is a non-web framework. It would be nice if I could put these in WEB-INF - where the rest of my config files (Spring, SiteMesh, etc.) reside.
  • Many of the JSP tags require you to use "'literal value'" - where you put single and double quotes back-to-back. IMO, this is just ugly and I'd much rather put some sort of indicator that it's a dynamic value - i.e. ${...} or #.
  • I couldn't get client-side validation to work. Seems cool though.

My experience with WebWork has been quite pleasant. I received excellent support from the mailing list - even though it took me a while to subscribe. The mailing list archives are woefully out-of-date, but this is a general java.net problem - not a WW issue. Maybe they should create a forum until the mailing lists get back on track?

Hopefully this last day and a 1/2 will make it much easier to implement WebWork in AppFuse. Thanks for the support gents - now I'm off to learn Tapestry!

Posted in Java at Jul 21 2004, 03:41:58 PM MDT 8 Comments

[ANN] AppFuse Light 1.0 - a.k.a. Equinox

For those of you looking for an AppFuse Light, I have good news for you. I've actually been sitting on it for several months now, but now I'm prepared to release it. It's name is Equinox and it's much, much simpler than AppFuse. Equinox has only one build-time dependency (CATALINA_HOME being set for the servlet-api.jar). There's no code generation and no features - not even security. However, it supports building, testing and deploying from Ant, and even has support for managing Tomcat out-of-the-box.

To get started with Equinox, you can download the QuickStart Chapter from Spring Live. This chapter shows you how to develop a simple webapp using Struts, Spring and Hibernate - which talks to an HSQL database. Struts and Spring are integrated using the ContextLoaderPlugin and all tests are designed to be run out-of-container using JUnit and StrutsTestCase. Equinox ships with project files for both Eclipse and IDEA so you can develop and run the tests in either of these top-notch IDEs. There's also a demo available. Thanks to Boér Attila for the kick-ass CSS.

If you like what you see in the QuickStart Chapter, there's much more in the other ERP chapters of Spring Live - now available for download. Too see what's in the other chapters, checkout the Chapter Summaries.

This is a nice milestone - feels good to have made it this far. Have a good weekend!

Posted in Java at Jul 09 2004, 04:38:01 PM MDT 34 Comments

My Job for the next couple of weeks

I can't help but brag about how cool my current gig is with Open Logic. My task for the next few weeks is to write a simple sample app - and create alternative MVC implementations. Targeted frameworks include Struts, Spring MVC, WebWork, Tapestry and JSF. Not only am I working from home, but they dropped off an AMD XP 2800 to work with. Installing Fedora Core 2 with VMWare is what I'm up to this morning. Working with open source all day - it doesn't get much better than this.

Posted in Java at Jul 09 2004, 08:36:52 AM MDT 11 Comments

[JavaOne] State of the Web Tier

I'm sitting here with Bruce, listening to Craig McClanahan and others speak about the "state of the web tier." After the first 15 minutes, it seems like a waste of time. I should go to something I don't know about. The first 15 minutes touched on MVC frameworks and things like filter and tag libraries. I was impressed that they mentioned WebWork, Tapestry and Spring. Heck, they even mentioned SiteMesh when they talked about filters. Now Craig is talking about portlets.

It would be cool to do some portlet development. I took a class a couple of years ago to become a Portal Server instructor. I got certified, but never actually taught a course.

JSF: A server-side user interface component framework for Java technology-based web application. It's not an application framework for your business logic - it's for the UI only. JSF looks cool - especially since it uses the same "form backing object" like Spring MVC has. I think JSF has an advantage over a lot of other frameworks because (1) it'll be well documented and (2) it'll be well tested and (3) it'll be widely used. Having a widely-used technology is sooooo much easier to learn than ones that aren't. I'm willing to bet that the JSF version of AppFuse will be the most popular one in a year from now. By the end of the year, AppFuse will support WebWork, Tapestry and JSF in its web layer - in addition to Struts and Spring MVC.

Demo time. Craig is showing us the JSF demo app that we saw in the keynote. We're looking at Java Studio Creator now. There's a Creator party tomorrow night - get tickets from downstairs at the Creator booth.

J2EE 5.0: New name, same great platform. Final release in second half of 2005. Ease of Development is the primary theme. Based on J2SE 5.0, with great benefits (shouldn't it be J5SE and J5EE - WTF!?). New JSRs: JSP 1.2/JSF 1.2 - EL alignment is key. Toolability is key. Maintenance reviews: Servlets and JSTL. J2EE.next - successor J2EE 5.0. Work will begin shortly after JavaOne and JSRs will be filed after JavaOne. Experts groups are on Java.net - JSP and JSTL are there today. Also,the JSF Reference Implementation is now on java.net. BTW, I'm on the J2EE 5.0 Expert Group so hopefully I can contribute to making J2EE 5.0 easier too. They'll let just about anyone onto these expert groups - can you believe they let both Hani and I in? ;-)

Posted in JavaOne at Jun 28 2004, 03:29:35 PM MDT 5 Comments