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 "framework". 558 entries found.

You can also try this same search on Google.

Validation vs. Business Logic

In the manuscript I'm reading, I just ran into a diagram and overview of a layered architecture - and all of a sudden, it hit me. At work, most of our business rules are being implemented by Struts' Validator framework. In the case of indexed properties and more complicated rules, these reside in the validate() method of our action forms. So it's interesting to me that I'm using a business delegate to perform my business logic - when in actuality, all my delegates are doing is copying properties from a POJO to an ValidatorForm. So this begs the question - shouldn't validation (a.k.a business rules) be done wherever it is most convenient rather than only in the domain layer? Oh yeah, and most of this is just validation - our real business rules (comparing data for validation) takes place in Oracle stored procedures. And you know what - it works great!. So my opinion is - do whatever is easiest and makes the most sense.

Posted in Java at Apr 29 2003, 06:18:27 AM MDT 6 Comments

WebWork Tutorial makes it look easy

I have to admit that this webwork tutorial makes WebWork look easy. In comparing this to Struts, it seems as if the Form and Action are the same thing. I wonder if I could use BeanUtils.copyProperties(wwAction, POJO) like I am with Hibernate/Struts currently.

The funny thing is that XDoclet has made it so easy (IMO) that I don't write ActionForm's anymore. All I really write is Actions, JSPs, DAOs and Services (a.k.a. Managers). So, with my current architecture I'm using, it actually looks like more work to use WebWork's Actions than Struts Actions. Especially since I have to write my validation in my Action. The XDoclet/Validator combo makes this super simple with Struts (and would with WW if they'd adopt it ;-). The only time I've been writing forms lately is when I have a form with indexed properties. Then I create a childForm that extends the generated form and has the appropriate accessors/mutators for the indexed properties.

The one thing the article does bring to light is how much cleaner Velocity is. JSP 2.0 will make JSP's a lot easier, but Velocity looks like it's already there. The one thing that worries me about using Velocity is that, according to their homepage, they haven't had a release in 8 months and their last release was a Release Candidate. What the?! Seems like someone might be dropping the ball on that project.

Posted in Java at Mar 30 2003, 11:26:58 AM MST 6 Comments

Which caching framework to use?

I discovered this afternoon (after I got everything working - thanks to Jason's comment) that the main process in the webapp I'm building (day job) takes 15 seconds to process. It could be have something to do with the fact that the HTML page itself is 1.5MB of data (view-source, save as). And it's a very lightweight page as we're using strict XHTML and mucho CSS. So now it's time to start looking into caching frameworks. For the web/JSP side, I'll probably use OSCache. It's seems to be more tried and true, and commons-cache is still in the sandbox. If any of your have experience, chime in so I don't pick the wrong one! Another method I'm going to try is using JCS with Hibernate. Since I'm using XDoclet already, all I have to do is add the following to the top of my persistable objects.

@hibernate.jcs-cache usage="read-write"

Posted in Java at Mar 26 2003, 04:40:52 PM MST 2 Comments

TagUnit for the Display Tag

Simon Brown was nice enough to whip up an application for testing the display tag library. Amazingly enough, it passes all the tests! At first glance, Simon's TagUnit seems to just test getters and setters and if classes are loadable. I think these are great tests, but for truly robust tests for the display tag, I think we need tests that test specific behavior (i.e. you click on a column heading and it sorts that column). IMO, WebTest is probably the best candidate. The problem is, it might take awhile to write these tests, and no one seems to have much time to work on the display tag project. Any volunteers? ;-)

Posted in Java at Mar 23 2003, 08:24:10 AM MST 2 Comments

Struts Training: Week 3

I just signed in for 3rd week here in Struts Training. I'm coming to you live from Chelan, WA. So on with what Ted has to say.

Ted's talking about persistence in Struts: Transaction Script vs. Domain Model.

Transaction Script - organizes business logic by procedure. Great choice for small applications with simple logic. For example, online auction, public search engine or an address book.

Domain Model - an object model of the domain. Has a rich variety of objects that incorporate both data and behavior. Ted mentions that the Domain Model is better for larger applications. For example, managing inventory for an online auction might require using the domain model.

What Ted is doing is using the Domain Model to separate Struts from his Actions - so that he passes around a DomainRequest, DomainResponse, and gets his form from a factory. To me, this looks like a good way to make your Struts layer a lot more complicated! ;-) At the same time, Ted is getting this information from Martin Fowler's Patterns (in Enterprise Architecture, ISBN 0321127420) book, so maybe I should move to the domain model. Naahh, I think I'll keep using the Transaction Script method - it's probably easier for folks to learn and would definitely be easier for rookies to maintain.

Onto Hibernate and how it works:

- POJO beans, encourages fine-grained
- Utilizes "persistence by descriptor"
- Provides DBA-friendly text queries
- Plays well with others
- Buffet-style implementation

IMO, if you're not using Hibernate, you should know why. If you're starting a new project, it's worth looking at. If you're using it, but not using XDoclet - you should be. XDoclet is the best way to avoid DD Hell (quoted from Erik Hatcher).

I didn't know that Hibernate supported a version - did you? Apparently you can specify that a property is a version and Hibernate will use it as you'd expect. Don't see that I have a need for that, but possibly. Would a struts-resume user ever want to keep old versions of their resume? I like to keep old versions of mine, but I have to admit, I never look at them again.

<version name="version" />

Ted just touched on how Hibernate can generate your database schema for you. This is a very powerful feature IMO - especially with struts-resume. It makes it nice for an example app. For instance, with struts-resume, you can run "ant setup-db" and it'll drop tables and re-create your db schema for you.

A student asks about the bottom-up approach - what if you already have a database. My advice? Try looking at Middlegen, its Hibernate Plugin in designed to create an XDoclet-enabled POJO from a database schema. There's also the Reverse Schema Generator that is included with Hibernate. I've used this one and it works great. I've never used Middlegen, but I should be considering that I tag the generated POJO up with XDoclet tags.

Interesting: Ted just mentioned that Gavin (Hibernate's Lead Developer) is working on a book for Manning. It is on Object Relational persistence and it uses Hibernate for its example apps. Erik Hatcher, at his preso on Wednesday, also mentioned that an XDoclet in Action book will be published soon by Manning. He even showed us the book's cover - so I'm assuming it will be published soon.

Hibernate's Fashionable Friends: XDoclet, Commons Logging, Commons DBCP, DynaBeans and Turbine Caching.

To learn more about this Hibernate, checkout:

· AgileData Website (Scott Ambler)
· Hibernate Homepage
· Struts Application Site (Hibernate example and Struts Resume both use Hibernate with Struts)

Vic still likes RowSets and SQL better. I'm guessing this is because he's a SQL expert. The nice thing about Hibernate is that it's query language (HQL) is very much like SQL and allows you to do complex joins. At least, to my knowledge, I've never done any fancy joins in the HQL, just in the mapping (*.hbm.xml) files.

Quote from Ted: This is the year of JUnit books. Watch for them this summer..

Now Ted is covering StrutsTestCase, a JUnit extension that hooks into Struts and Cactus. IMO, it's an awesome way to test Struts Actions - even easier than testing a servlet with Cactus.

Another book: JUnit in Action (Manning) by Vincent Massol and Ted. To be published this summer. Vincent is the lead developer on Cactus, so I expect this to be a great book. Right now, I wish I had written my first book for Manning rather than Wrox. :-(

The one bad part about today's session is that I had to use a calling card to dial in and at $0.35/minute, I'm up to about $25! I should probably sign off soon and save some cash...

Tapestry - are you using it? A student asks about it and Ted mentions that he views it as a presentation framework like Velocity. I've heard lots of good things about it, but have never used it. Ted admits that he uses Velocity and gave up on using JSPs a while ago.

Good stuff - thanks Ted, I'm signing off (the QA session is still in progress).

Posted in Java at Mar 15 2003, 08:37:28 AM MST 1 Comment

Ant JMeter Task

By now, you've probably heard of JMeter. It's basically a Swing-based performance testing framework. From the struts-user list today, I found out there's a JMeter Ant Task. Sweet - looks easy to use too. Now if I could just figure out JMeter, or better yet - be tasked with actually implementing it. I've played with it a couple of times, but never long enough to get something I rely on and use.

Anthill, on the other hand, was so easy to install and use that I've set it up at home and I've automated some of my projects' build/deploy processes. I might have to add Roller to the mix. If I were real daring, I could set it up on this server and build/deploy Roller every day or so. Of course, I wouldn't keep this site up to the latest version - I'd setup a 2nd instance of Roller. Any interest in this? Or better yet, do you know anyone that's hosting an Anthill install that we can use?

Posted in Java at Mar 04 2003, 02:07:49 PM MST 1 Comment

The Debate is flawed: Struts vs. WebWork

Personally, I think the debate between Struts and WebWork is irrelevant. This is because I don't think that the Web Application frameworks are the problem. I spend most of my days getting persistence to work. Granted it's gotten a whole lot easier with Hibernate, but I've spent a lot of time tackling that learning curve in the last couple of months. Thanks to Dave Johnson and Gavin King for guiding me up the curve. I spend about 30 minutes each day writing Struts-related code, if that. More time is spent writing tests, CSS, JavaScript (the most time) and DAO's/Managers.

So the problem is my brain. If I could just get the damn thing to work right - it wouldn't matter which framework I chose, because I'd just know it. No learning curve == awesome productivity.

The WebWork guys claim to have this. Therefore, I'm interested. However, who's hiring WebWork gurus? Heh - I know - what I really need to do is learn WebWork and then I can offer an unbiased opinion. Right now, no one is offering an unbiased opinion. Patrick is heavily invested in Struts, as am I. Heck, I've written a chapter about it and I've used it on many project. Jason is invested in WebWork as he's a committer.

Baaah, I'm just gonna learn .NET - that's where the Florida Jobs are. Struts .NET and WebWork .NET - maybe I should work on getting those started. ;-) The post is meant to be read with a smile on your face - I don't want to start yet another flame war.

Posted in Java at Mar 03 2003, 04:13:58 PM MST 2 Comments

Validation - We need a common framework!

Jason doesn't like my Validator that matches two fields. I was just trying to help the Struts Community out by solving a problem that many have asked for. Oh well, I guess those WebWork folks will take any opportunity to bash on Struts ;-).

This is just another example of Struts making the common things hard. I'm more and more glad we went with Webwork, and once Xwork 1.0 / Webwork 2.0 are here, I'll be in nerdvana. [Jason Carreira]

Personally, I still think the Commons Validator is easier - you don't have to write any .java files in most cases (except for my extension, which will hopefully soon be added). I do like the ExpressionValidator - that looks cool. All in all, I think I'd bash on WebWork a little more - but I don't know enough about it. Where's the book ;-)

BTW, this post was sent (and edited!) via NetNewsWire. Very cool - but no titles.

Posted in General at Feb 27 2003, 05:31:50 PM MST 2 Comments

Struts Validator: Validating Two Fields Match

In the Struts Validator Guide, there is a section on how to create a pluggable validator that matches two fields. I've been using this server-side validator (as shown in the example) to do password/confirm password validation. This has worked great for me, but I've always wanted the Validator to have the client-side JavaScript method for it too. I wrote my own that just compared the two fields, but it's not the same as having one rendered for you (from validator-rules.xml). So yesterday, I did some tinkering and figured out how to add the JavaScript method to validator-rules.xml. So here's how to configure the whole thing (most of this is contained in the Validator Guide, save the JavaScript).

How To Add a TwoFields Validator

Step 1: Create a class with a validateTwoFields method. In my code, my class is ValidationUtil and has the following method:

public static boolean validateTwoFields(Object bean, ValidatorAction va,
                                        Field field, ActionErrors errors,
                                        HttpServletRequest request) {
    String value =
        ValidatorUtil.getValueAsString(bean, field.getProperty());
    String sProperty2 = field.getVarValue("secondProperty");
    String value2 = ValidatorUtil.getValueAsString(bean, sProperty2);

    if (!GenericValidator.isBlankOrNull(value)) {
        try {
            if (!value.equals(value2)) {
                errors.add(field.getKey(),
                           Resources.getActionError(request, va, field));

                return false;
            }
        } catch (Exception e) {
            errors.add(field.getKey(),
                       Resources.getActionError(request, va, field));

            return false;
        }
    }

    return true;
}

Step 2: Edit validator-rules.xml to contain the "twofields" rule.

<validator name="twofields" 
    classname="org.appfuse.webapp.util.ValidationUtil" method="validateTwoFields" 
    methodParams="java.lang.Object,
                  org.apache.commons.validator.ValidatorAction,
                  org.apache.commons.validator.Field,
                  org.apache.struts.action.ActionErrors,
                  javax.servlet.http.HttpServletRequest" 
   depends="required" msg="errors.twofields">
    <javascript><![CDATA[
        function validateTwoFields(form) {
            var bValid = true;
            var focusField = null;
            var i = 0;
            var fields = new Array();
            oTwoFields = new twofields();
            for (x in oTwoFields) {
                var field = form[oTwoFields[x][0]];
                var secondField = form[oTwoFields[x][2]("secondProperty")];
            
                if (field.type == 'text' ||
                    field.type == 'textarea' ||
                    field.type == 'select-one' ||
                    field.type == 'radio' ||
                    field.type == 'password') {
            
                    var value;
                    var secondValue;
                    // get field's value
                    if (field.type == "select-one") {
                        var si = field.selectedIndex;
                        value = field.options[si].value;
                        secondValue = secondField.options[si].value;
                    } else {
                        value = field.value;
                        secondValue = secondField.value;
                    }
                
                    if (value != secondValue) {
                    
                        if (i == 0) {
                            focusField = field;
                        }
                        fields[i++] = oTwoFields[x][1];
                        bValid = false;
                    }
                }
            }
            
            if (fields.length > 0) {
                focusField.focus();
                alert(fields.join('\n'));
            }
            
            return bValid;
        }]]></javascript>
</validator>

Step 3: Configure validation for your form in validation.xml:

<field property="password"
     depends="required,twofields">
  <msg
    name="required"
    key="errors.required"/>
  <msg
    name="twofields"
    key="errors.twofields"/>

  <arg0 key="userForm.password"/>
  <arg1
    key="userForm.confirmPassword"
  />
  <var>
    <var-name>secondProperty</var-name>
    <var-value>confirmPassword</var-value>
  </var>
</field>

Where errors.twofields=The '{0}' field has to have the same value as the '{1}' field. An alternative to Step 3 is to use XDoclet to generate your validation.xml. This requires (1) configuring XDoclet (of course) and (2) adding some @struts tags to your form on the setPassword method.

/**
 * Returns the password.
 * @return String
 *
 * @struts.validator type="required" msgkey="errors.required"
 * @struts.validator type="twofields" msgkey="errors.twofields"
 * @struts.validator-args arg1resource="userForm.password"
 * @struts.validator-args arg1resource="userForm.confirmPassword"
 * @struts.validator-var name="secondProperty" value="confirmPassword"
 */
public String setPassword() {
	return password;
}

I've sent this as a proposal to the struts-dev mailing list yesterday, but haven't heard anything yet. Enjoy!

Update: You'll need to update ValidationUtil.java and validator-rules-custom.xml for Struts 1.2. Full files: ValidationUtil.java and validation-rules-custom.xml.

Posted in Java at Feb 26 2003, 12:29:56 PM MST 10 Comments

A bit of Tomcat History - the names

I got this nugget of information off the tomcat-user list this morning.

I talked to the original Tomcat author, James Duncan Davidson, about the 
name choice. He gave me a surprising answer. Here's a bit of history...

Tomcat was born in response to the need for an independant servlet 
specification implementation. James wrote it hoping that it would 
eventually be open sourced. He figured that since most open source 
projects had O'reilly books about them that he should name it after an 
animal. Essentially he was thinking of an animal that would go on the 
cover of an O'reilly book. He came up with "Tomcat" since the animal 
represented something that could take care of itself and fend for 
itself. That's how he came up with the name.

And Craig McClanahan tells us why he named the Catalina Engine so:

Using "Catalina" was my idea, because I
wrote most of the original code that became it.  The reasons are mundane,
but here they are for the record:

* Even though I don't live in Southern CA, I've always liked
  what I've read and seen of Catalina Island.

* One of the towns on the island is Avalon, and we were (at the
  beginning) considering using the Avalon Framework
  (http://jakarta.apache.org/avalon/) for the internal architecture.
  It would have been a cute tie-in, but alas it didn't happen
  that way.

* When I'm coding, I regularly have one or more cats wandering
  around my lap and adding to the whitespace when they don't
  think I put enough (you don't need fingers to press the space bar :-).

Another "code name" you'll hear in the Tomcat world is Jasper -- that's
the name of the JSP page compiler part of Tomcat.  That name was carried
over from even before my time, but I'm sure it probabbly came from the
alliteration (JaSPer).

Posted in Java at Feb 04 2003, 05:43:56 AM MST Add a Comment