Java EE Tutorials - JSP and MVC

Today we will be looking at how Java Server Pages are used in Model-View-Controller setups. The example code can be found in the jsp_part_3 branch of our example repository on Github, and a ZIP file of the code can be found here.

I mentioned in our introduction to JSP that JSP is often used as the View component in many Java-based MVC frameworks. Unfortunately, if you aren’t familiar with MVC, this isn’t the best time and place to explain it in detail. Suffice to say that in order for JSP to be feasible as the View component, it needs be able to accept real data so that it can render it on the page. So far, none of our previous examples have demonstrated this capability, but rest assured that it does exist.

The secret lies in a feature of the Servlet API which, admittedly, I never covered in past Tutorials. There is a class named RequestDispatcher which is primarily used to forward request/response objects from one Servlet to another. We can create a Servlet which accepts user requests, fetches some data, and uses an instance of RequestDispatcher to send it all down to a JSP page for rendering. In other words, you can create a poor man’s MVC framework using nothing but Servlets and JSPs.

Let’s start with the Servlet. We’ll call it MVCServlet, and it looks like this. The in-class comments explain everything:

package net.cmwolfe;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Example of how to use a Servlet to redirect requests to a JSP page,
 * thus behaving as a poor man's MVC framework.
 */
public class MVCServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        // First we need to get this query param. from the URL.
        String field = req.getParameter("field");

        // We are trying to simulate the behavior of an MVC app,
        // so let's pretend to fetch some data
        FakeModelClass model = new FakeModelClass();
        String data = model.getSomeData(field);

        // We add our data to the request object. Here we are
        // adding a String, but you could add any Java object you want
        // to the request.
        req.setAttribute("reversed_string", data);

        // This is how we send the request and response to the JSP page
        // using a RequestDispatcher.
        RequestDispatcher rd= req.getRequestDispatcher("mvc.jsp");
        rd.forward(req, resp);
    }
}

Our Servlet uses a class named FakeModelClass. Its contents aren’t really relevant for the sake of this post (check it out in the source code if you’re curious).

Now, finally, our JSP page. Notice that it retrieves and uses the “reversed_string” attribute that we added to the request:

<html>
    <body>
        Here is some data - <%= request.getAttribute("reversed_string") %>
    </body>
</html>

If you load the project as a webapp, you can access this example via the url http://localhost:8080/mvc. You should see something like this:

Hmm … I guess we should add a query parameter. Let’s try again:

And there you have it! We serviced a request, grabbed some data, and sent it to a page which changes its contents based on the data.

General Comments

  • In all honesty, this is a ridiculously simple example. We aren’t using a real Model class, nor are we routing different requests to different Servlets or JSPs. That’s OK though - the main point of this lesson was to show you that you can pass Java objects containing data to a JSP page.

  • I don’t exactly know how every Java-based MVC framework uses JSPs to render views, but I imagine that they do something similar to the above (albeit with more features and better error handling).

In our final JSP-related posts, we will be taking a look at JSP tag libraries, which many developers consider the “proper” way to use the technology. Are they correct? I’ll let you be the judge after giving them a spin.