clicking on this will visually collapse the text block directly below it

The New Servlet Tutorial - Part One, A Different MVC

Well it's been three years since my last servlet tutorial, which were primarily written for my students at the time. Time passes and we get older and wiser so I felt it was time to redo the whole series. Over the next 6 or 7 tutorials we will look at a home-made MVC (Model View Controller) system built especially for the website and web application coder. Were going to take a complete relook at the whole idea of servlets and how to use them with a website, how to secure a website with sessions and how to build these applications to use the least amount of server resources while giving your clients a rocket fast web application. Stick around for the whole series, I think you'll enjoy it.

The Model View Controller Concept

Before we start looking at how to build our MVC we need to take a few moments to explain exactly what it is and why we would want to use it in out web applications. The MVC concept is a design pattern where you separate your application into three pieces, the model which stores the data (anything from flat files to a large scale relational database), the View which displays it (your layout-design the customer interacts with), and the Controller which handles data moving back and forth between the model and the view. It what's commonly known as a 3 tier programming platform. The primary advantage of this system is creating a buffer (the controller) between your client, their actions and your data. As any good programmer knows data integrity is paramount. So now that we have an explanation of what we are trying to create lets start working out the details.

Building A Different MVC

While most Java MVC tutorials around today use a JSP for the front end I don't. Even though many of these other programmers feel the JSP / Servlet model allows them a complete separation of display content from their application code I constantly find a massive amount of lines of java code embedded in these JSPs, which of course contain all (or most) of their HTML. I take a slightly different approach that I feel allows almost the same separation of html from java while adding a massive amount of functionality to a web application. Do I have HTML within java files? Yes but my HTML is contained with 2 or 3 class files that are created exactly for this purpose, but we will get to that soon enough. Now before I go any further I must say I do use ONE JSP on every website, the index page BUT it only consists of two lines of code:

<%@ page session="false"%>
<jsp:include page="/servlet/Controller?page=Main" />

If you notice this code does nothing more than include my controller servlet, which handles all of the processing throughout the website. This allows me to control ALL the design graphics and functionality from one set of files including the index page. You may ask why I just don't redirect into a servlet from an HTML file. The answer lies in the fact that html redirects reek havoc on search engine rankings, something else any good web developer should always consider. So we have waited to long to get started, lets get to some code.

We are going to start out with our main controller class, which we will call (surprisingly) Controller.java. I'll start from the basics again even though my old tutorial did this I feel its worth repeating. So here's our HTTP Servlet Skeleton, really nothing special but we'll cover the basics of it. Notice I have both a doPost and a doGet coded with the doGet doing nothing more than passing everything to my doPost. This eliminates the need to worry about how the data might come in from a form, link or whatnot. Next you will notice I've created a StringBuffer object within the doPost. This handles all of my HTML output back to the client, and provides us an easy to use object for adding and removing that html. Lastly you will notice I have created a PrintWriter object (java.io.PrintWriter) for our final send back to the client, I pass the now filled StringBuffer to it and print it, then close it. One important thing to notice here (as I mentioned in my first tutorial) is that only one printing is done here. This avoids many, many problem with browsers and can mean the life or death or your servlet-based application. Multiple out.print statements will slow a servlet down to a crawl and should be avoided at all costs! Also note the res.setContentType("text/html"); line. This is the one line that's I've seen more beginners screw up than any other. Without this line several Mozilla-based browsers will actually output your code into the browser, NOT the finished page! OK, That's the absolute basics needed, now let's attack our different page's content.

I've added two new lines of code in this next example. First is a test for the incoming page name parameter, appropriately called page. This is done with a ternary operator which I use more than any other test condition. The second is a call to a class I call ContentReader which, as we we'll see shortly, handles all of our different pages and adding them to the final output. So here's the next step of our servlet. But before we go into too much detail I feel it's probably a good idea to address the ternary operator, since you will be seeing a lot of them in this tutorial.

Ternary Operators are Fun and FAST

A lot of beginning (and even some more seasoned) Java programmers have literally thousands of lines of if-else statements or multiple if statements one after another. I'm sorry but if you want lightning fast webapps (or any application for that fact) you MUST learn how to use ternaries to your advantage. A ternary replaces those nasty old mulitline if-else statements with a single rocket fast check condition. You can also replace those simple one lined if statements with them! So let's look at the code and make some sense of it.

String page = (req.getParameter("page") != null && req.getParameter("page").trim().length() != 0) ? req.getParameter("page").trim() : "None":

The first part of the ternary is what the data will be assigned to based on the return of the check condition. In this case its the String, page. Next is the check condition itself, which is enclosed in the parens. This condition tests whether the variable we are looking for actually exists AND its not an empty string. Note: You MUST check for null before attempting to check for the empty string to avoid throwing a NullPointerException from the call to trim() and you MUST use the && shortcut operator so if the parameter is null the trim is never called. After the check condition is a ? (question mark) This separates the check condition from the two available assignments. The first statement after the ? is what will be assigned to the String page IF the check condition returns true. After that statement is a : that separates the true return from the false return which of course follows the colon. So in plain language the ternary above says this:

If the request parameter "page" exists and is NOT an empty String assign its trimmed value to the String page, ELSE assign "None" to it.

They really are simple to use once you get the hang of them and will increase the speed of all your apps 10 fold. Even better they can be nested within other statements (more on this later). Keep these in mind because you will see them used in many of the following examples in a multitude of different ways.

Back to the Servlet

OK, so now we understand the first of the two new lines in our example servlet, now lets look at the call to our ContentReader. It's this line: sb = new ContentReader().getPageContent(sb, page); Now here's another way to save some server resources, which always makes things run smoother and faster. You'll notice I didn't create a variable here, in other words I didn't do: ContentReader cr = new ContentReader(); and then call the method cr.getPageContent(sb, page); There is no reason to create an instance of ContentReader since we are only using it once within the scope of this servlet. Now does it save a ton of memory, no its probably a minute amount that would never even register with this servlet running ..... until you have 100,000 people all hitting it at the same time. You see IF I made an instance it's life span would be the whole doPost where as the nanosecond the method returns this way makes the ContentReader object eligible for garbage collection. I'll grant you its not a huge savings but every little bit helps and secondly it's one line I code we don't need to write. Now as I said before our ContentReader object handles reading in our page content. I still use (for you old time readers) flat .txt files for my websites content. Why? They are simple for a non HTML enabled customer to edit and they are small and memory friendly.

Reading Content from files

Now as I mentioned before I store all of site's content in flat .txt files. Many people throw their content into databases but I have found that the whole process of connecting to the database, running the query, iterating through the ResultSet and THEN adding it to your output extremely wasteful of server resources. This is especially true when the site you build has to grow into millions of user. Personally I don't go to a database unless I have to! Now our call to ContentReader passes the name of the page, the StringBuffer to add the page's content to AND the servlet context which is essential for being able to locate the content files. Here's our ContentReader example. Let's run through the code quickly just in case there is anything you may not understand. The first line of the getPageContent method locks into our content file by use of the URL object. Note it uses the ServletContext object we passed to the method from the servlet. What is the ServletContext, why couldn't we get it here and why did we have to pass it? The ServletContext can only be grabbed from within a servlet, what it does, in simple terms, is tell your app where on the server you are. Without it and it's method sc.getResource we'll never be able to locate where your application is actually running and how to access files and folders without the entire path from the root. I should also mention I could have used the getRealPath method, which returns a String that includes the whole path but I just find this method easier.

Notice after we have the URL object everything is contained within a try / catch block. This gives us protection from those nasty NullPointerExceptions when someone types the wrong URL into the browser or we delete a page. You'll notice I've caught both a NullPointer and a FileNotFound Exception for this very reason. Both of these catch blocks add our pageNotFoundError HTML code in place of the page that isn't there. This is a cleaned up handled 404 page that gives them a nice Sorry you page wasn't found error page ... not a blank white page or exception stack trace.

Our first line of code opens the stream from the file we locked into with our URL object via an InputStream. You will also notice I then test that InputStream object just to make sure its really there. I consider these type redundant checks as insurance because I don't like my clients getting errors! Once we know we have our stream we then create a BufferedReader object to start the read. Finally we run though the file line by line assigning the lines content to the String s and adding it to our StringBuffer, along with a new line character for easier source code reading. Finally we MUST close the BuffferedReader and the InputStream objects to prevent those nasty memory leaks. Very fast, very low overhead while allowing us to let clients edit their own page content, either through a CMS or just plain notepad. Of course any formatting they want in those files is truly their option but I always keep it to header tags <h1> etc. and paragraph tags.

Next, adding design and functionality to our servlet driven site

Customer Comments

clicking on this will visually collapse the text block directly below it
Lee Ritenour and his staff and fans are very pleased with the work of the DCD Designs team.
Lee Ritenour Staff, leeritenour.com | More Testimonials >>

Latest Articles / Tutorials

clicking on this will visually collapse the text block directly below it |
Our RSS Article Feed Available as RSS Feed!

Check here often for articles & tutorials that will help make your business grow!

| More Articles & Tutorials >>

Partner Comp. & Friends

clicking on this will visually collapse the text block directly below it