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.

How does your MVC framework handle duplicate posts?

One of the problems that you'll often see in webapps is that when a record is added - hitting refresh on the browser will cause a 2nd record to be added. This is because the "Save" action usually does a forward, rather than a redirect, and the full post is re-created. I'm curious to know how other MVC Frameworks handle this issue, particularly Spring, WebWork, Tapestry and JSF. In Struts, it's pretty simple to solve. When the form is first displayed, you'll likely go through an Action. In AppFuse, this would be something like UserAction.edit(). In the edit method, you add a saveToken() call to put a token into the session:

// edit method - mark start of operation
saveToken(request);

Then in the save() method, you can check for a duplicate post using the isTokenValid() method:

// save method - check for valid token
if (!isTokenValid(request)) {
    // duplicate submit, continue to success mapping
    return mapping.findForward("success");
else {
    resetToken(request);
}

How does your Java MVC framework handle this? Do you have to programmatically handle it like Struts - or is it built-in to the framework to handle it auto-magically?

Posted in Java at Apr 20 2004, 11:36:29 PM MDT 22 Comments

NYC Seminar: Flex and WebWork

Christophe talked about Flex, it's architecture and built the data grid for the Flex pet store in a matter of minutes. After seeing this presentation, I definitely think Flex is wicked cool. It's too bad that it's price tag is $6K/CPU. However, Vic is probably right - this stuff should be the next generation of webapps. I'd order the developer CD but it sounds like something I'd play around with and never use. It looks so easy to use that I'm willing to bet I can wait until a client demands it - then learn it in a matter of days - or even hours. I did end up asking Christophe about unit testing these Flash UIs. They're working on it, but nothing exists yet.

Now Jason is up - the last session of the day.

What is WebWork 2.0?

  • The 2nd generation of WebWork
  • A web MVC Framework
  • a wrapper on top of a generic Command Pattern implementation (XWork)
  • A small but powerful tag library

XWork is where Jason spends most of his time. XWork is a generic command pattern implementation. Actions are command objects in XWork. XWork adds advanced features.

  • Interceptors: setting parameters, workflow, etc.
  • Results: includes one for chaing to another Action
  • Simple IoC container
  • Powerful expressional language (OGNL)
  • Flexible type conversion
  • Metadata driven validation framework

What does WebWork add?

  • Adapter for Http request/response
  • Integration of Session / Application Scopes
  • ServletDispatcher translates HTTP Requests into Action execution
  • Request parameters passed to Action Results
  • Supported view technologies: Velocity, Freemarker, XSLT Jasper Reports, JSP

Action is a simple interface with an execute method. ActionSupport is a useful base class.

I gotta say - one of my favorite things about WebWork is the fact that all its UI tags are built using Velocity. This means that you (the developer) have full control over what HTML is generated from the JSP tags.

Interceptors have been nicknamed "Domain AOP." Interceptors allow custom code into the call stack and much of the WebWork "magic" happens with Interceptors. WebWork has a number of built-in interceptors:

Setting Parameters

  • ParameterInterceptor
  • StaticParameterInterceptor
  • ChainingInterceptor
  • ConversionErrorInterceptor

Defining Workflow

  • DefaultWorkflowInterceptor
  • PrepareInterceptor
  • ServletConfigInterceptor

Preventing duplicate posts

  • 2 types of token interceptors

Interceptors can be grouped into named Interceptor Stacks (i.e. defaultStack, validationWorkflowStack).

2 types of actions possible: Model-Driven vs. Field Driven (merging of Action and ActionForm). ModelDriven Interface - public Object getModel(). Porperties of the model will be available as simple properties - "user.name" becomes "name". To use, you have to add ModelInterceptor to your WW config file.

OGNL (Object Graph Navigation Language). An expression and binding language for getting and setting properties of Java objects. Normally the same expression is used for getters and setters.

XWork Validation Framework

  • XML based. Validation file in the same package as the class. Defines one field validator and the error messages to add if it fails.
  • Bundled validators - supports required, range, email, url and OGNL Expressions (very powerful).
  • JavaScript support recently added for simple validators - nothing for expressions though (tough to do).

Doh! Jason's demo didn't work. I did a lot of demos in my preso so I couldn't help but say "shoulda used a Mac!" These PowerBooks might be a bit slow for development, but they're definitely nice for this traveling salesman thing.

This is where you get your money's worth: All the speakers and attendees comparing frameworks, talking about their problems and trying to figure out a better way.

Posted in Java at Apr 03 2004, 04:13:54 PM MST 8 Comments

Saturday Afternoon

I have a whole bunch of notes from watching all the speakers this morning, but there's no point in me regurgitating all the stuff that Jason has written. Unfortunately, I don't have unlimited bandwidth on my phone - so this post (and checking my e-mail) will probably cost me $20. I finished my talk about a half hour ago and damn it feels good. All my worrying from the last week is over. I'm done. Phewfta. ;-)

Below are my thoughts on the speakers so far. I'll update this for Vic (speaking now) and Jason as they speak.

Clinton Begin: - iBATIS. He actually works for ThoughtWorks in Calgary, which I didn't know. I've met Ted, Jason, Rod and Tom this morning. All very cool guys. It's funny to see Jason and Ted sitting at the same table - I thought they were mortal enemies. ;-) There's not a whole lotta folks here - approx. 30 right now. That's good since this room doesn't look like it'd hold much more than that.

Clinton wrote SQL Maps because Data Models are rarely perfect. He's actually using Hibernate right now - b/c his team has control of the database.

Clinton is toying with the idea of using something like XDoclet to generate SQL Maps.

Caching - on a single box OSCache is the slowest caching mechanism. It'll actually cost you more than it helps you. For distributed systems, however, it's the only choice. He doesn't know why it's so slow - it just is.

Rod Johnson - J2EE without EJB. Rod actually flew in from London just for this event. It's his first time to NY, as it seems to be for many speakers here. I took a lot of notes from Rod's presentation. He was mainly advocating that you can write fast, scalable J2EE apps without EJB. He didn't cover Spring much, but did point out that Spring offers most of EJBs built-in services. After watching Rod's presentation, the only reason I can see for EJBs is for distributed systems. However, these days it seems that more folks are using web services instead of RMI.

Ted Husted - Commons Chain. Ted's presentation was quick (1/2 hour) and I missed most of it, so I can't really comment on it.

Vic Cekvenich - basicPortal RIA. Vic's presentation was titled "basicPortal RIA" but that's not what he covered. He ended up talking about requirements, project management and good programmers. Damn, I've heard this talk before - nothing new here. It's good stuff though, and an enjoyable talk.

Vic's predication: in the next 12 months, declarative languages (like Flex, XAML and XUL) will be next generation of MVC frameworks. He thinks it's very liberating to not write HTML anymore. As I said yesterday - you're still writing XML, so as a developer I don't think you have to learn that much. He just showed us some Flex code - it's pretty simple stuff. 10 lines of code to declare a data grid (like the display tag) and load its data from a DAO.

I asked Vic if calling a DAO from the View (Flex page) is a bad thing. Isn't that like using scriptlets in your JSPs to call your DAO? I mentioned that the design pattern bigots would bash all over this. He said - "screw the design patterns, this works." I suspect the next guy (Christophe Coenraets on Flex) might promote cleaner design patterns. This should be fun - a bunch of open source fans about to be presented with a closed-source, expensive product.

Posted in Java at Apr 03 2004, 01:37:16 PM MST 1 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

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

AppFuse 1.4 Released!

This release involves many changes: re-arranging packages/directories, Spring integration, Remember Me refactorings and I also added iBATIS as a persistence option. I also spent a lot of time going through the tutorials to make sure they are up to date. I've been using AppFuse 1.4 for a few weeks on my current project, and I really do like the way Spring makes it easy to configure Hibernate, Transactions and Interface->Implementation relationships. If you're interested in upgrading your AppFuse 1.x app to use Spring, you can checkout this howto.

I also made the leap and moved the AppFuse project from SourceForge to java.net. This is mainly so I have more control over mailing lists and adding other developers. As of today, CVS files in SourceForge and Java.net are the same - but I'll only be updating Java.net from here on out. I also have released files in both projects, but will only use java.net in the future.

I spent all weekend updating the tutorials and fixing release-related issues. Phew - I'm glad that's over. "So," you ask, "what's next?"

A week of vacation (my sister flies in tomorrow), followed by starting to write Spring Live and creating a Spring MVC option for AppFuse. Oh yeah, I'll also be at SD West in Santa Clara, CA - let me know if you plan on attending.

Posted in Java at Mar 01 2004, 12:35:54 AM MST 11 Comments

Simplify your AppFuse Managers

I figured out a way to remove any ActionForm references from my Managers yesterday. It was pretty simple, but I thought others might benefit from this knowledge. Basically, you just need to add a couple methods to your BaseManager.java file. Here is the latest one from CVS HEAD. Then you can pretty much eliminate any *Form references in your Manager by using the convert(Object) method. This method will convert POJOs <-> Forms and vise versa. You will likely have to do some tweaks on the package names if you're using anything < v1.4. Looking at this diff of the UserManager before and after this change will show you what's changed.

I started this task thinking I could remove the need for Forms in my classpath when compiling the service layer. However, I soon discovered that my Tests have Forms all over the place - since they replicate what my Actions will pass in. Oh well, at least my code is a bit cleaner now.

Of course, this code will become even simpler when I start using an MVC Framework that allows my POJOs to be my data handlers on the UI. These frameworks make me question if I even need Managers. Then again, it's nice to unit test what your DAOs are returning/receiving from the web layer.

Posted in Java at Feb 19 2004, 11:28:41 AM MST 2 Comments