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.

Denver JUG and Rock Bottom Brewery

Last night was a fun night. First of all, Mike Clark spoke about TDD development at the DJUG and he wowed me with his presentation abilities. I think he could have presented on just about anything and it would've been entertaining. He had a fair amount of humor in his presentation and came off as a true Montanan (a.k.a. very cool guy). I talked with him after the meeting as a whole bunch of us were entering Rock Bottom Brewery and my suspicions where confirmed. I look forward to the next time I hang out with Mike.

At Rock Bottom, it was all about drinking beer and bullshitting about Java. I sat across from Rod Cope (Out of the Box) and next to Bruce Snyder (Geronimo/Castor). The topics ranged from Groovy (Rod is speaking about Groovy at the Denver NFJS) to Spring to Castor and Kids (Bruce has a little one that's a week and a half younger than Abbie). I had a great time talking to these guys and look forward to our next meeting. It won't be long until I see Bruce again - he's attending SD West next week. He reminded me that next Wednesday is St. Patty's day, so since I'm part Irish - it should be a fun night. St. Patty's day is also both my sister and Julie's sister's birthday - neat eh?

I didn't leave downtown until 1:00 a.m. - a great Java-infested night it was. Thanks for the conversations and the booze folks - I had a great time.

Posted in Java at Mar 11 2004, 05:56:16 AM MST Add a Comment

Replacing line breaks with HTML breaks in Velocity

Roller currently has an issue where line breaks in comments are not auto-converted to <br>'s. This problem only exists in the in-page comments and the twisty comments you see on this site. Today, I might've figured out the solution. It turns out that using Jakarta Common's StrutsUtils to replace new lines with <br>'s doesn't work:

#set($comments = $stringUtils.replace($comments, "\n", "<br />"))

However, using the String.replaceAll(new, old) in JDK 1.4 does work:

#set($comments = $comments.replaceAll("\n", "<br />"))

I figured this out on my current project and haven't tested it on Roller. Since I didn't find anything on this via Google - I though y'all might be interested.

Posted in Java at Mar 10 2004, 03:58:26 PM MST 6 Comments

Groove Systems: Cheap Java Hosting Provider

Spotted on the WebWork Mailing List today. Groove Systems (Rick Salsa's employer) has some nice hosting solutions. I currently pay $30 (Canadian) for 200 MB, 5 GB Transfer and my own JVM at KGBInternet.com. Keith (at KGB) rocks because he is always quick to respond to any of my issues and always tries to help me out. However, I have to admit, Groove's Grooviest package looks pretty nice. For the same price ($30 Canadian), you get 1 GB space, 15 GB Transfer and your own JVM.

The only question I have is how much memory do you get? Keith does nothing to limit memory usage, so I'm currently set at a 512 MB max heap size. Who knows if I'm using it all, that's just what I'm set at. Oh and one other thing you might like to know:

... right now you can get a 32meg private jvm for free.

Read the read e-mail from Rick for more info.

Posted in Java at Mar 10 2004, 12:54:11 PM MST 3 Comments

Do you censor your own blog?

Someone asked me recently, "Do you censor your blog?" As in, "do you only write about stuff that you think readers will be interested in?" At the time, I said, "No - I write whatever the hell I want." However, I've come to realize that this is not exactly true. When I first started writing this blog, back in August 2002, I wrote about everything. I didn't care, I was writing to write and nobody was reading me.

Then, in November of 2002, along came the opportunity to help write a book. This was pretty damn exciting for me, as I think that being a published author is pretty cool (BTW, if I never started blogging, I'd have never gotten the Pro JSP or the Spring Live deals).

What has happened over the last year or so is something I never expected. Hopefully it's just in my head and it isn't really true. I've started to feel like an authority on web development - so I feel that I can't really post dumb questions, problems, etc. on this site. I feel that if I do, I'll lose credibility. It doesn't help that I've gone from 2 visits a day to over 4000. Damn - I'm censoring myself. That's just wrong...

I'm tempted to say, credibility be damned, actions speak louder than words - and run with it. After all, most of the hits on this site come from Google - and the reason is because I've copied and pasted so many errors/exceptions into this blog. More errors = more hits = more money from Google Ads? ;-)

Posted in Roller at Mar 10 2004, 11:42:03 AM MST 4 Comments

[DisplayTag] Changing a row's CSS class based on values in the row.

One request I've seen on the displaytag-user list a few times is the ability to change a <tr>'s CSS class based on a certain value. While the displaytag doesn't have this feature out-of-the-box, it is possible (and fairly easy) to do. All you need to do is sprinkle a little JavaScript into the mix. Basically, the displaytag will render a well-formed HTML table - like the following:

Username First Name Last Name
mraible Matt Raible
tomcat Tomcat User

By adding an "id" attribute to your table (i.e. id="user"), your table will get an "id" attribute and now you can easily access it via the DOM. The following JavaScript will grab the table and search the first column for a value of 'mraible' - and if found, it will change the row's background color to red.

<script type="text/javascript">
<!--
    var table = document.getElementById("user");    
    var tbody = table.getElementsByTagName("tbody")[0];
    var rows = tbody.getElementsByTagName("tr");
    // add event handlers so rows light up and are clickable
    for (i=0; i < rows.length; i++) {
        var value = rows[i].getElementsByTagName("td")[0].firstChild.nodeValue;
        if (value == 'mraible') {
            rows[i].style.backgroundColor = "red";
        }
    }
//-->
</script>

You could easily change rows[i].style... to rows[i].className = if you want to assign a new CSS class. Now let's see it in action (and see if your browser supports it). This has only been tested in Safari and Mozilla on OS X.

Username First Name Last Name
mraible Matt Raible
tomcat Tomcat User

Other displaytag tips: Static Headers HowTo and Highlight and allow clicking of rows. The 2nd tip (highlighting) is available in AppFuse, in the userList.jsp page.

BTW, I also added support for the DisplayTag to render the results from JSTL's SQL Tag. I haven't committed it yet - I'm still waiting for more feedback.

Posted in Java at Mar 08 2004, 01:22:34 PM MST 10 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

Happy Birthday Spam

Spam turns 10 today. I've been using my PowerBook for a week solid with no XP intervention. I have to admit, I'm really starting to get used to it - especially Mail's Junk Mail feature. Of course, using IDEA every day is quite a treat too.

Posted in The Web at Mar 05 2004, 11:12:28 AM MST Add a Comment

Great CSS Designs

While reading the latest issue of A List Apart this morning, I got sidetracked and visited the CSS Zen Garden, finally landing on David Shea's blog. There I found his listing of Great CSS Designs. There's some very nice sites in there.

In other news, today is one of those days that sucks to work from home. I can see the snow falling out my window, and it's snowed almost 2 feet in the last 48 hours at Vail, Breckenridge and Winter Park. Urgghh, the slopes are calling, but so is my pocketbook. Note to self: get your priorities straight next year so this doesn't happen again. This is the first year in the past 5 that I haven't bought a ski pass and I won't do it again. Oh well, at least it'll be a good night for a hockey game.

Posted in The Web at Mar 05 2004, 07:45:05 AM MST 3 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