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.

Struts Menu 2.2 Released!

View changelog or download. New features in this release include a EL tag that allows JSTL's EL expressions in all attributes, as well as the ability to use Struts Menu outside of a Struts application. I also took the time to add a database-driven example to the sample app.

For the database-driven menu (as well as the app I'm writing for Spring Live) - I'm using HSQL. I never even touched the sucker before last week and I gotta say - damn it's easy. Just drop the JAR into WEB-INF/lib and when you make a database connection - it'll create the database on-the-fly. Even better, if you're using Hibernate, you can set a property (hibernate.hbm2ddl.auto=create) and it'll create your tables on-the-fly too. Cool stuff - HSQL rocks for sample apps. I don't know if it's production worthy - but I certainly like what I've seen so far.

Posted in Java at Mar 30 2004, 07:57:50 PM MST Add a Comment

Macromedia Flex 1.0 Released

Macromedia has released Flex 1.0. Flex is basically a server plugin that allows you to write XML to render flash. Here's the marketing lingo from their product page:

Flex is a presentation server installed on top of a J2EE application server or servlet container, a rich library of user interface components, an XML-based markup language used to declaratively lay out these components, and an object-oriented programming language which handles user interactions with the application. The result is a Rich Internet Application rendered using Flash Player and developed using industry standards and a development paradigm familiar to developers.

The major problem with Flex is its price.

Flex presentation server pricing starts at $12,000 for two CPUs and includes annual maintenance.

Macromedia's take on this seems to be "its an evolutionary step in web application design and development" - so $12K is a small drop in the bucket. Sun claims the same for JSF, but you don't see a hefty price tag on that sucker. What Macromedia doesn't seem to realize is that its important to market to developers. If you can inspire the developers to love your product - it's only natural that it will gain more traction. With a price of 12K and no free trial (CD by mail) - good luck on getting developer support.

Of course, as an independent consultant, I probably have a scewed perspective. Maybe the corporate drones like getting their development platform and tools shoved down their throat.

Posted in Java at Mar 29 2004, 07:36:10 AM MST 9 Comments

SiteMesh passed the 10 minute test

I decided to go out on a limb this evening and give SiteMesh a run for its money. The first warning sign was that the documentation refers to version 2.0.2, while the downloads section refers to version 2.0.1. So I proceeded to download 2.0.1. I promptly noticed that the install guide indicated I needed to download SiteMesh's two TLDs and configure them in my web.xml. Blech - this is so year 2000 - most modern containers support loading taglibs from JAR files with a URI.

So I did a good ol' cvs co of sitemesh from java.net. First of all, I'd like to say kudos to java.net and their CVS repositories - they've been rock solid for the few weeks I've used them. After checking out sitemesh, the first thing on my agenda was to give it the tried n' true ant test. This means I navigate to the sitemesh folder and simply type "ant". At this point, I should get one of two things - a BUILD SUCCESSFUL with a JAR or a help message telling me what I should type. I got the former, which I prefer.

After this, I integrated it into my app using the decorators documentation and deployed it. At first, I received the lovely ol' "getOutputStream() has already been called for this response" error, so I hacked PageFilter.java to use PrintWriter writer = response.getWriter(); instead of PrintWriter writer = new PrintWriter(response.getOutputStream());. Build, copy, package, deploy and voila - it all worked!! Wow that was easy. ;-)

Here's the weird part. I decided to reverse my hack on PageFilter.java to prove that I'd actually fixed the bug. Now I'm back to the original code I got from CVS and I can't get the getOuputStream() error to rear its ugly head. Doh!! This experience begs the following question.

Is SiteMesh stable enough on Tomcat 5 that I can should use it in my Spring Live sample app?

SiteMesh definitely passed my 10 minute test, we'll see if it holds up for the long haul. So far, I'm quite impressed with its easy configuration and quick implementation. I especially like that you can literally guess at it's syntax and you'll get it right. Maybe I was just lucky... heh

P.S. You should probably know I'm a big fan of Tiles. I wonder if SiteMesh will let me switch a decorator on the fly like Tiles does?

Posted in Java at Mar 24 2004, 12:07:56 AM MST 16 Comments

OGNL 2.6.4 Released

OGNL 2.6.4 was released today. So you're asking - "Why do care? You don't use it?" You're right, I don't use it - but I will be soon. It's the Expression Language used in Tapestry and WebWork - which I hope to learn, beat and abuse in the coming months. I've also had some discussions with Drew about adding it as an EL option to the Display Tag. BTW, with the release of 2.6.4, XWork 1.0.1 and WebWork 2.1 will be released very soon - quoted from the WebWork mailing list.

A lot of the WW and Tapestry folks swear by it and claim it's vastly superior to JSTL's EL. As far as I can tell, it has some more advanced features (i.e. the ability to call a method), but it's not *that* much better. It's not going to revolutionize my webapp productivity - is it? Of course, Jason and Erik will argue that [ insert WebWork or Tapestry here ] is the real productivity enhancer. Personally, it's not the MVC frameworks that slow me down. It's the meetings, the requirements gathering and the UI tweaking (CSS and JavaScript) that takes the most time - as well as the occasional fumbling with Hibernate. That's unlikely to go away no matter what MVC framework I use.

That's why I use AppFuse - b/c most of the CSS and JavaScript I use on a project is already in there. A little massaging here and there, and the UI tweaking for the whole app can be done in a matter of hours. Of course, Tiles helps tremendously with this - as Sitemesh would I suspect.

I think what helps me the most about AppFuse is having a structured process for developing webapps. Create POJO -> Create DAO -> Create Manager, etc. I suspect that my process will stay the same with Tapestry and WebWork - so that's why I'm not afraid to learn them. The productivity-enhancing attributes of AppFuse will not go away with a new framework, but some parts may become a bit easier. Of course, you can bet that if I trip and fall along the way (which I likely will), you'll be able to hear about it here. Maybe someday this site will get as many hits for these frameworks as it does for Struts (up to 914 before this post).

Posted in Java at Mar 21 2004, 01:34:28 PM MST 1 Comment

No more Struts in services layer

Yesterday, I did some more refactoring on AppFuse and got rid of Struts in AppFuse's services layer. Basically, I was using business delegates (a.k.a. Managers) to convert POJOs -> ActionForms and vise versa. So now the question is - why do I even need Managers and why don't I just talk directly to DAOs (as most sample webapps do)? I think the best justification is that Managers can be used by rich client apps and it abstracts the DAO implementation a bit more.

The question is - is there any point to using Managers in a webapps that will always be webapps (no rich client)? To be honest, probably not - but it does make for easy testing of the business logic. The main reason I did a Struts-purge is to get ready for adding other MVC options - most of which allow me to use POJOs in my view. I'm looking forward to adding Spring and WebWork support and I'm willing to bet these solutions will be a bit cleaner. Unfortunately, neither of these frameworks offer client-side validation support, but the good news is it's coming.

The best part about yesterday's refactoring? I ended up deleting more code than I added - which is always a good thing.

Posted in Java at Mar 18 2004, 06:58:16 PM MST 16 Comments

[Struts Menu] Building Dynamic Menus from a database table

I spent a few hours this weekend and did some work on Struts Menu. At the very least, I made it easier to build dynamic menus programmatically and put together an example of doing it from a database table. I also added support for Expression Language (EL) syntax in all the tag's attributes. For the EL implementation, I simply copied what was implemented in the DisplayTag. I don't know that it's the best way (two TLDs, subclassing tag classes), but it works and it is good enough for now. The main reason I copied the implementation in the DisplayTag is that we've been talking about adding support for OGNL. I figure if I copy the implementation, it should be easy enough to copy the refactorying if/when it happens.

Back to the point of this post - how do you build dynamic menus? So without further ado, here's how to build and display database-driven menus with Struts Menu.

Posted in Java at Mar 14 2004, 04:53:33 PM MST 4 Comments

Velocity Templates in RTF

For most of this week, I've been developing Velocity templates for rendering resumes in HTML and RTF (Word). Thanks for Mathias once again for showing me this was possible. The HTML part has been pretty easy, but the RTF stuff has been a bear. Mostly because I want to hide/show different sections of a person's resume based on whether they've entered information or not. In order to do this, I first created a rough draft of the RTF template in Word and then I began hand editing it with a text editor (HomeSite and BBEdit). And if you look at the RTF syntax, it's pretty damn ugly. The main thing I'm struggling with now is showing hiding rows of a table based on whether data exists or now. In HTML - it's easy - you just put your #if statement before a <tr> and you can easily hide the row. In RTF - it seems like the number of rows/columns/borders, etc. is all defined at the beginning of the table - but I can't really read the syntax well enough to understand it.

Therefore, my question is - does anyone know RTF well enough to tell me how I can hide a row? Is there something in the beginning of the table definition I can modify with Velocity #if statements? For now, I'm simply putting "Not Specified" text in rows where no data exists.

Finally, how about some RTF syntax I've learned in this process:

{\f116\fs20 = Verdana 10pt Font
The document must end with " }}" (no quotes) on the same line as the last bit of text
Escape "\n" with "\\par "
{\b\f116\fs24\cf17 = Bold, Verdana, 12pt, Ocean colored Font

How's that for a bunch of useless information! ;-)

Posted in Java at Mar 11 2004, 10:51:18 AM MST 4 Comments

BeanUtils.copyProperties() with Dollar amounts and Dates

A frequent issue that crops up when using Struts is how to transfer data from ActionForms to DTOs or POJOs and vise-versa. In other words, how do you get the data from your true model into Struts' Model? There are a few solutions out there, including the ActionForm-Value Object Mapper and BeanUtils.copyProperties. I've used both and (IMO) the only advantage of using BeanUtils is that Struts uses it internally and it's a bit easier to work with.

The reason I'm writing this post is to show you how to handle Dates and Doubles in your POJOs. The first step is easy - you simply need to register converters for Date and Doubles. The easiest way to do this (that I know of) is to add a static block to one of your classes. I do this in BaseManager, but it could be easily done in a BaseForm class.

    static {
        ConvertUtils.register(new CurrencyConverter(), Double.class);
        ConvertUtils.register(new DateConverter(), Date.class);

        if (log.isDebugEnabled()) {
            log.debug("Converters registered...");
        }
    }

When I use Doubles, it tends to be for dollar amounts displayed in a JSP page. Therefore, I call it a CurrencyConverter (source), and I use a DateConverter (source) for dates.

After registering these converters, the next step is to throw a little validation into the mix so that the String values (from the Form) are in an expected format. Since I'm using XDoclet to generate my Forms, it's as easy as adding a couple of tags to my POJO. Here is an example for validation Dates:

    /**
     @return Returns the startDate.
     * @struts.validator type="required"
     * @struts.validator type="date"
     * @struts.validator-var name="datePatternStrict" value="MM/dd/yyyy"
     * @hibernate.property column="start_date" not-null="true"
     */
    public Date getStartDate() {
        return startDate;
    }

And one for validating dollar amounts:

    /**
     @return Returns the startingSalary.
     * @struts.validator type="required"
     * @struts.validator type="mask" msgkey="errors.currency"
     * @struts.validator-var name="mask" value="${currency}"
     * @hibernate.property column="salary_start" not-null="true"
     */
    public Double getStartingSalary() {
        return startingSalary;
    }

For the currency validation to work, you have to add a few things to your Struts project. The first is the errors.currency to your ApplicationResources.properties file:

errors.currency=The '{0}' field should be a dollar amount.

The 2nd piece you'll need to add is the currency mask as a constant in your validation.xml file (or metadata/web/validation-global.xml if you're using XDoclet/AppFuse):

<constant>
    <constant-name>currency</constant-name>
    <constant-value>^\d{1,3}(,?\d{1,3})*\.?(\d{1,2})?$</constant-value>
</constant>

I'm not much of a regular expression expert, but I think this mask is specific to US Dollar amounts. I'd love to see a i18n version, but I haven't had a need for one (yet) - so it's not a big deal for me. The last thing you'll need to do is add a little JSTL lovin' to render your dollar amounts with the proper number of decimal places:

<fmt:formatNumber type="number" minFractionDigits="0"
    maxFractionDigits="2" value="${myForm.startingSalary}"/>

It seems that most web frameworks are getting away from a separate web model (ActionForms) and allowing you to use your POJOs in your view. This is likely to be a bit cleaner, but I'm sure they still have to use some sort of converter to get Dates/Doubles from your UI into your POJOs. The nice thing I've seen in other frameworks is that they have Date Converters built in. Why doesn't Struts? Who knows, but IMO it should be a built-in component.

Both of the Converters described in this article can be found in AppFuse.

Posted in Java at Mar 08 2004, 07:00:08 AM MST 1 Comment

Outline for talk on Display Tag, Struts Menu and AppFuse in NYC

This weekend I'm preparing slides for my talk in NYC on the Display Tag and Struts Menu. I'm also going to do a bit about AppFuse since it includes and uses both libraries. I have an hour to talk, so I think I'll try to present for 50 minutes and leave the last 10 minutes for questions or simply quitting early. That means, realistically, I only have 15-20 minutes for each project. That sure seems like a lot now, but I'm sure it'll fly once I'm up there in front of everyone. I'm definitely nervous about this event - I've only ever done technical talks to team members, never to a large audience. I've done large audience (20-50 attendees) talks, but those where in college and covered growing up in Montana and business plan-type presentations. Oh well, I'm sure I'll get over my anxiety about 10 minutes into it.

The purpose of this post is to write down the topics I plan to cover and hopefully get some feedback from the more experienced presenters out there. I'd also like to get feedback from developers - as in what you'd like to see covered if you were attending.

  • Introduction. Who am I, etc. (2 minutes)
  • Struts Menu. What is it - it's history, etc. (3 minutes)
       - Features and Demo of sample app. Questions. (5 minutes)
       - Expression Language support and building menus from a database (including code). (10 minutes)
  • The Display Tag. What is it - it's history, etc. (3 minutes)
       - Features and Demo of sample app. Questions (7 minutes)
       - Expression Language support and using to create an editable table (including code). (10 minutes)
  • AppFuse. What is it - it's history, etc. (3-5 minutes)
       - Features, Libraries included, etc. Questions (5 minutes)

Posted in Java at Mar 06 2004, 09:47:32 AM MST 8 Comments

JAG - similar to AppFuse, but offers more choices

This afternoon, I stumbled upon the open source Java Application Generator on SourceForge:

JAG is an application that creates complete, working J2EE applications. It is intended to alleviate much of the repetitive work involved in creating such applications, while providing a means of quality assurance that the applications created will be of consistent quality.

Major differences include: JAG has a Swing GUI to create your app and it uses EJB 2.0 for its persistence layer. AppFuse has an Ant task (ant new) and uses Hibernate (or iBATIS) for the persistence layer. Both use Struts 1.1 with Tiles and Validator support. The question is - will they eventually offer Spring, WebWork and Tapestry options for the MVC layer? I doubt it...

BTW, my experience with java.net has been quite nice so far. I like the fact that I can use a pserver for developer CVS access (vs. SSH only at SF). I also like that I can approve e-mails just by replying to an e-mail (vs. using a web interface on SF). The best part, however, has to be that CVS commits and e-mail messages are immediately browse-able in the archives. This is rather convenient when you're a blogger that likes to link to source code and messages in (sudo) real-time.

Posted in Java at Mar 04 2004, 01:05:51 PM MST 1 Comment