CISC474, P. Conrad, University of Delaware, Spring 2006
The best way to learn something is by doing it. So this chapter is all about actually writing an MVC app.
This chapter is basically divided into two sections:
A key idea you will encounter in this section is the separation between the development environment and the deployment environment. (More about this in the notes on p.69).
This page points out that small applications—little hacks, for example—have a tendency to sometimes grow in ways we didn't expect. This is a good argument for developing good habits, and sticking to them even for the smallest little applications.
This is the last chapter where the book says that the SCWCDE objectives covered are covered completely in later chapters, so don't worry if you don't get them all. Starting with Chapter 4, you are expected, by the end of the Chapter, to be able to do all the things listed on the Objectives page at the start of the chapter.
So, the four steps:
These four steps aren't something you need to "memorize"; it's just a common sense way to organize the chapter.
But I'd suggest one more step—before developing the User's views (i.e. mockups of what the web pages will look like), you want to write "a story". (In a more complex web app, you might write several stories.)
The idea of writing stories is one that I first encountered in the eXtreme Programming (XP) movement. At first I wasn't sure exactly what a "story" was. I'm still not entirely sure I'm completely in sync with what the XP folks mean by story. But I think the idea is pretty simple. I'll show you a specific example in the notes for the next page (p.70).
Here's the idea:
Programmers sometimes balk at this notion, especially when writing a simple little application. Here are some objections:
But as p.67 pointed out, small applications have a way of growing. Keeping development and deployment environments separate is something that may create the question "why bother" when you first do it. After a while, the benefits become more obvious.
I ask you to accept this on faith for now—do what the book says, and set up two separate environments. Later, after we have some experience with doing things this way, we can have a discussion about the pros/cons. Hopefully, you'll discover on your own why doing things this way is a good idea. If you have any thoughts on that (pro or con), write them on the WebCT discussion board for the HFSJ reading notes.
Ok, as promised here's a story:
The story is the starting point for your web app. To give you another idea about "stories", try these stories. Do they sound like any web site you've ever seen before?
Ok, you get the idea. The point is that if you don't have a "story" in mind before you start to develop screens and source code, you are flying blind. The beer app has a very simple story.
Often, web apps that students envision in CISC474 for their independent projects actually have pretty complex stories—less like the beer app we are about to create, and more like the example given above, which obviously has a lot more details that I haven't yet spelled out: things like how a "shopping cart" works, how "creating a login/password" works, etc.
Hence, when we start to design our own web apps, I'm going to ask you to work on these stories first. One of the key principles of the eXtreme Programming approach is that you write your story first, and then you do the minimum amount of coding necessary to make the story work.
That means, for example, that you don't spend time, at least at first, on making the web site look beautiful with colors, and fonts and sophisticated CSS layout. Instead, you focus on functionality, and making sure it can do everything in the story without crashing!
In a previous semester, I saw several CISC474 projects that were beautiful to look at—students got carried away with Dreamweaver and CSS and fonts and colors and clipart, and expressing themselves artistically and aesthetically. Unfortunately, these apps often lacked key features, and/or crashed every third mouse click.
In the past, I've sometimes allowed myself to be swayed in giving grades by the aesthetic beauty of a web site, out of sympathy for all the hard work that students put into making the sites look beautiful. I've learned, though, that this isn't a good policy. This is course in software design, not in visual design.
This page is really at the heart of what you are supposed to be getting out of Chapter 3. Spend some time tracing through the sequence of events (1 through 11). Then, refer back to this page often as you work through Chapter 3. Keep track of "where you are in the diagram" as you look at the various parts of the chapter.
In my view, there is are a couple of "arrows" or "steps" missing from p. 71—or, to look at it another way, there are a few arrows that are "one way" arrows, that ought to be two-way arrows (i.e. a call that passes in some parameters, and a return that brings back some results).
Ok, this is where we start doing homework assignment 2 (H02).
First a note: the root of the development environment is shown here as MyProjects. You'll probably want that root directory to be, in fact, ~/cisc474/MyProjects (i.e. make MyProjects be a subdirectory under cisc474, under your home directory.)
mkdir -p
You hopefully already know that mkdir
is the Unix command to make a subdirectory. What you might not know is that if you add the -p
flag, you can make an entire directory tree with one command just by specifying the "leaf" directory (hopefully you remember from CISC220 what a "leaf" in a tree is.). For example, consider the following command (here, the $
is the unix prompt).
$ mkdir -p ~/cisc474/MyProjects/beerV1/src/com/example/web
This command makes not only the subdirectory called web
, but it also, with one command makes all the subdirectory levels in-between!
With mkdir -p
, you can create the entire subdirectory structure from p. 72 (containing 16 subdirectories) in eight commands or fewer, without doing any cd commands; and if you use the up-arrow and command line editing, you can really save on keystrokes. If you did it the long way (cd'ing into every directory, one at a time), it would take much longer.
For example, you could continue with:
$ mkdir -p ~/cisc474/MyProjects/beerV1/src/com/example/model $ mkdir -p ~/cisc474/MyProjects/beerV1/classes/com/example/model etc...
There are several other mkdir commands needed—you need to figure out yourself what those are.
Root the deployment environment in ~/cisc474/tomcat/webapps, otherwise known as $CATALINA_BASE/webapps
Note that here, only three mkdir -p
commands are needed to create a directory structure containing 10 subdirectories!
suzuki[80] > mkdir -p ~/tomcat/webapps/Beer-v1/WEB-INF/classes/com/example/web suzuki[81] > mkdir -p ~/tomcat/webapps/Beer-v1/WEB-INF/classes/com/example/model suzuki[82] > mkdir -p ~/tomcat/webapps/Beer-v1/WEB-INF/lib
This is basically a road map to the rest of the chapter. Note the reference here to eXtreme Programming.
Take special note of the Q and A about the .do
extension.
.do
extension is not specific to the HFSJ textbook; it seems to be a "Struts" thing. (Struts is a web development framework we'll talk about later in the semester; it is mentioned in Chapter 14 of HFSJ.) To see some references, search in these pages for ".do
extension":
You'll notice that the HTML on p. 75 is not XHTML compliant. Don't stress over it too much. If you want to clean up the tags (e.g. using <br /> instead of <br>, and closing the <option> tags that HFSJ folks leave unclosed, go for it; its good practice.
For now, as much as it pains me to look at this old-school sloppy HTML, it is probably good enough for our purposes in this chapter.
It is interesting, though, to see the bad HTML habits that these authors have: for instance using a <p> open-tag at the end of a line to make a "big line break".
It pains me especially because I know that prior to Fall 2005 (when I really dug into XHTML while teaching CISC103), I myself wrote HTML a lot like this. Perhaps you still do too—if so, I hope CISC474 can support you if you choose to develop more skillful habits.
The next page tells you where to type this in, but I'll tell you now since you need to be looking at page 75 to type: it goes in a file called ~/cisc474/MyProjects/beerV1/web/form.html
.
You edit it there, and then copy it into ~/tomcat/webapps/Beer-v1/form.html
You may be wondering: why edit it one place (the development environment), then copy it to another (the deployment environment)? Trust me. Ultimately, this way of working will make sense.
Look over the following slight modifications to each of the steps on this page before you start working:
Step 1: We already covered this step under the reading notes for the previous page (p. 75)
Step 2: For now, you can just do this copy manually (using the Unix cp command, for example.)
A shell script can help here, since ultimately there is a lot of compiling and copying to do. Here is an example shell script that you might use. I call this script deploy.sh, and I keep it in ~/cisc474/MyProjects/beerV1 (i.e. the top level directory of a given project under my development directory.)
#!/bin/sh # P. Conrad for CISC474, 02.19.2006 # Example shell script to deploy application based on # chapter 3 of "Head First Servlets and JSP" DEVELOP=/usa/pconrad/cisc474/MyProjects/beerV1 DEPLOY=/usa/pconrad/tomcat/webapps/Beer-v1 MODEL=classes/com/example/model WEB=classes/com/example/web MODELSRC=src/com/example/model WEBSRC=src/com/example/web CATALINA_HOME=/porsche/cisc474/tomcat CLASSPATH=$CATALINA_HOME/common/lib/servlet-api.jar:$DEVELOP/classes:$DEVELOP:. CP=/bin/cp JAVAC=javac #Substitute the following line to see some additional warnings #JAVAC="javac -Xlint:unchecked" $JAVAC -classpath $CLASSPATH -d $DEVELOP/classes $DEVELOP/$WEBSRC/BeerSelect.java $JAVAC -classpath $CLASSPATH -d $DEVELOP/classes $DEVELOP/$MODELSRC/BeerExpert.java $CP $DEVELOP/$MODEL/*.class $DEPLOY/WEB-INF/$MODEL $CP $DEVELOP/$WEB/*.class $DEPLOY/WEB-INF/$WEB $CP $DEVELOP/etc/web.xml $DEPLOY/WEB-INF $CP $DEVELOP/web/*.html $DEPLOY $CP $DEVELOP/web/*.jsp $DEPLOY echo "Deployed"
The "right" way to do this copying is using Ant. The advantage of using Ant is that unlike the shell script, which recompiles everything and copies everything every time, Ant is similar to the Make utility you may have used with C and C++ programming; it only compiles and/or copies the things that have changed. We'll come back in a @@@future homework assignment@@@ and update this project to use Ant.
>
is the Unix prompt, and you actually type the $
and the braces { }
as part of the command:
> ${CATALINA_HOME}/bin/startup.sh
Step 4: instead of http://localhost:8080/Beer-v1/form.html, you'll use
Check the confirmed errata for this page
So if you are following along, you'll know by now that:
~/cisc474/MyProjects/beerV1/etc/web.xml
~/tomcat/webapps/Beer-v1/WEB-INF/web.xml
Check the confirmed errata for this page
These are two very important pages in helping you to understand what you were typing on p. 77. Pause here to look over these two pages and think about them so that this doesn't just become and exercise in "type in the code and make it work". You need to also think about what you are doing if you are going to learn from what you are doing.
Compare these two pages also with what you learned in Chapter 2 from p.46, p.48, and from the DD part of the code magnets on p. 60 and 61. That will help the knowledge stick to your brain.
Don't just type this in... read all the little captions spread around the page and try to understand the code too!
Some changes here:
$CATALINA_HOME/common/lib/servlet-api.jar
in place of /Users/bert/Applications2/tomcat/common/lib/servlet-api.jar
and note that this string should never have "wrapped around" in the first place. Check the confirmed errata for this page
Note that you may want to make one change to the code on this page. The line that says
List brands = new ArrayList();
is soooo last year. The new Java 5.0 way to do this with generics is as follows (I've added bold to emphasize the changes)
List<String> brands = new ArrayList<String>();
This change says that the new ArrayList object is restricted to holding only objects of type String. This is a new feature in Java version 5.0 that enables safer type checking.
If you don't make this change, you may get some complaints from the compiler that look like this:
suzuki[217] > ./deploy.sh Note: /usa/pconrad/cisc474/MyProjects/beerV1/src/com/example/model/BeerExpert.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. Deployed suzuki[218] >
Changing the line in the deploy.sh script that defines javac to include the -Xlint:unchecked flag gives error messages like these
suzuki[218] > ./deploy.sh /usa/pconrad/cisc474/MyProjects/beerV1/src/com/example/model/BeerExpert.java:19: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List brands.add("Jack Amber"); ^ /usa/pconrad/cisc474/MyProjects/beerV1/src/com/example/model/BeerExpert.java:20: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List brands.add("Red Moose"); ^ /usa/pconrad/cisc474/MyProjects/beerV1/src/com/example/model/BeerExpert.java:23: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List brands.add("Jail Pale Ale"); ^ /usa/pconrad/cisc474/MyProjects/beerV1/src/com/example/model/BeerExpert.java:24: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List brands.add("Gout Stout"); ^ 4 warnings Deployed suzuki[219] >
This makes it more clear what the warnings are all about—the add member function is unsafe if the type of the thing being added is not being checked somehow.
If you aren't "up" on Java 5.0 and the changes that were made to collection types, this may all be mysterious. Chapter 16 in the Head First Java, 2nd Edition book explains this new concept pretty well. If you can find other sources (e.g. online sources) that are good tutorials about this topic, please point your fellow students (and me) to those, using the WebCT Discussion boards.
The idea here is that you will learn more if you try to think about what the code on the next page is going to look like before you turn the page. Try your hand at that. We want the servlet code on p.80 to somehow use the model code on p. 82. How can we do that? What will that code look like?
The answer is on the next page if you want to check your answer. No one will know if you just cheat and skip this exercise—but you won't learn as much if you do.
Check the confirmed errata for this page
This is the answer to the exercise from p. 83, and the code that we need to tie the Servlet to the Model.
Hopefully by now you've got the idea of what you need to do to adapt the steps listed in the book to our environment on porsche. Look back at the reading notes for p.76 and p.81 if you are not sure.
Ok, we aren't quite using the MVC design pattern yet. See if you can trace through the two models, and figure out what is missing. The model on the bottom of the page is the model for all the apps we are going to build all semester long, so we need to try to understand it pretty well.
I tried the modified version of the Servlet (from the reading notes for p.82) along with this JSP, and it seemed to work fine. I wouldn't be surprised though, if somewhere under the hood, there were some warnings being written to a log similar to those we say for the code on p. 82.
Check the confirmed errata for this page
These three pages are straightforward... follow the instructions (with the usual modifications to those on p.90) and enjoy the fruits of your labor!
We've deployed a simple MVC web app. The purpose was to give us something concrete to talk about as we dive into how the whole servlet architecture works.
As we'll find out, the app we've just deployed, while it's fine as a beginning example, is NOT a good example, ultimately, of how we want to build web apps in Java.
Some of the things we've done wrong:
EL and JSTL allow us to build JSPs that are much easier to maintain, especially since the web designers—the graphics artist types— typically don't know Java. Conversely, the Java programmers typically aren't the best web designers, at least from an artistic point of view.
But we are getting way ahead of ourselves. First, we have to step back a bit and understand what is "going on" inside a Java-based web app. That's what chapters 4, 5 and 6 in HFSJ are all about.
End of CISC474 reading notes for HFSJ, Chapter 3