4 Turn it Inside Out – JavaServer Pages

In this chapter you will be learning how to use designer friendly HTML (extended with some markup directives) to replace the MemoViewRenderer from the previous chapter. We’re doing so using JavaServer Pages as a template language.

Before we start, please verify again that your project is accessible in Codenvy and is up to date, i.e. you finished the previous chapters successfully as described. If this is not the case you can follow the preceding factory link that generates a project environment for you[1].

Project after chapter 3 (Servlet)

Project after chapter 3 (Servlet)


4.1 Using JSP as the View Renderer

In the previous chapter, we introduced the class MemoViewRenderer for rendering the HTML view. The problem with this implementation is that it consists mostly of inline strings containing HTML code. Maintaining this HTML code is nearly impossible: every little change is already a burden for us developers – just imagine how web designers feel, who in a regular development process should actually be able to create and maintain such views.

This raises the question if it wouldn’t be better to embed the little logic we have in this view (for displaying the value objects) directly in a regular HTML file, instead of adding inline strings in a class barely handling any logic, as we’re doing right now.

For this purposes the so called JavaServer Pages (JSP) were introduced. Basically this technology allows us to use a regular HTML file as our view and add logic parts written in Java if needed so. Listing 4-1 shows our view implemented as JSP. Please create the folder src/main/webapp/WEB-INF and add the JSP file[2] under the name memos.jsp. The folder WEB-INF is a special folder who’s content can only be used by server side code such as JSPs and Servlets – files inside the folder can not be directly accessed by web clients.

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.List" %>
<%@ page import="press.turngeek.mymemo.model.Memo" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>My-Memo</title>
    <link rel="stylesheet" type="text/css" href="screen.css">
</head>
<body>
<div id="container">
    <div id="header">
        <p>
            <b>My-Memo</b> – A Simple Web App for Managing Memos
        </p>
    </div>
    <div id="content">
        <h1>Add Memo:</h1>

        <form method="POST" action="memos">
            <input type="text" name="memo" size="30" placeholder="Enter your memo here"/>
            <button type="submit" name="button" value="save">Add</button>
            <% if (request.getAttribute("err") != null) { %>
            <span style="color: red"><%= request.getAttribute("err") %></span>
            <% } %>
            <h1>My Memos:</h1>
            <% if (session.getAttribute("memos") == null || ((List<Memo>) session.getAttribute("memos")).size() == 0) { %>
            <p>Please add some memos.</p>
            <% } else { %>
            <table>
                <tr>
                    <th>
                        Memo
                    </th>
                    <th>
                        Saved
                    </th>
                </tr>
                <% for (Memo memo : (List<Memo>) session.getAttribute("memos")) { %>
                <tr>
                    <td>
                        <%= memo.getDescription() %>
                    </td>
                    <td>
                        <%= memo.getCreated() %>
                    </td>
                </tr>
                <% } %>
            </table>
            <br/>
            <button type="submit" name="button" value="reset">Reset list</button>
            <% } %>
        </form>
    </div>
    <div id="footer">
        <p>(C) 2015 Schiesser/Schmollinger, MIT license</p>
    </div>
</div>
</body>
</html>

Listing 4-1 JSP file memos.jsp – Our view as JavaServer Page

As we can see, the file is a regular HTML file. The parts containing Java logic are embedded using the <% %> tag. If you have written PHP before, this is very similar to using the <?php ?> tag for including PHP code in a HTML file.

Note that we also add some special directives in the header of the HTML file using the @page tag.

Firstly, we are setting the encoding of the page to be UTF-8, which is as always highly recommended:

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>

Secondly, we are importing the Java classes we are about to use in our inline Java code:

<%@ page import="java.util.List" %>
<%@ page import="press.turngeek.mymemo.model.Memo" %>

Later, we are using Java if clauses to conditionally render HTML code. The first one is checking if the expression request.getAttribute("err") is not null, meaning an error message is set in the HTTP request[3]. If so, we are displaying that error:

<% if (request.getAttribute("err") != null) { %>
<span style="color: red"><%= request.getAttribute("err") %></span>
<% } %>

Note that we use the <% %> tag to embed the Java code for the if clause. A special version of this tag also exists: if you add a equal sign (=), you can calculate the result of a Java expression and directly render it to the HTML output. We are using this method to render the error by calling <%= request.getAttribute("err") %>.

You can find other if clauses later in the code. All using the previous method.

We’re using the very same approach for the for loop. It allows us to generate the same HTML snippet for each iteration. In our example, we are iterating over a list of Memo objects.

The HTML code inside of the for-loop is generated for each memo in the list. Besides HTML code, we also have two Java expressions included inside of the loop. Same as in regular Java these expressions are calculated for each iteration. In our case they are returning the description of the actual Memo object (memo.getDescription()) and the create date (memo.getCreated()).

As the Memo object changes for each iteration, the for loop code is rendering these two expressions for each Memo object in the list. The result is the desired HTML table of memos.

4.2 Enabling the JSP

In the last section we have written a JSP that is capable of replacing the functionality of the MemoViewRenderer we created before. Nevertheless, so far we are still not using the JSP to render the view.

To do so, we have to replace the sendResponse method in the MemoServlet with the following code:

private void sendResponse(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    config.getServletContext().getRequestDispatcher("/WEB-INF/memos.jsp").forward(request, response);
}

The method is firstly retrieving a so called RequestDispatcher for the JSP page by calling the expression config.getServletContext().getRequestDispatcher("/WEB-INF/memos.jsp").

A RequestDispatcher acts as a wrapper for servlet resources (servlets or JSP pages). You can use it to forward requests from one resource to another. By calling the forward method on it, we’re therefore forwarding the servlet’s request to our previously designed JSP page – exactly as we intended to do.

After restarting our project, the JSP is used for rendering the view instead of the MemoViewRenderer. You can therefore remove this class now.

4.3 Optional: Clean it up using JSTL

So far so good, but there is still a minor problem with our JSP page: as mentioned before the target group for the editing of JSP pages are web designers. Apart from that they most likely have a hard time reading the inline Java code, the tools they are usually using also don’t know how to handle it.
Therefore, we should get rid of this inline code and this is where the JSTL (JSP Standard Tag Library) comes into play.

To better understand JSTL, we firstly have to understand what is meant by a tag in the context of a JSP:
tags in HTML are the elements of the markup language that define how some text is to be rendered. For example, we have the tag <b>, which tells the browser that the enclosed text should have a bold typeface. A tag in JSP has a similar purpose: the difference is that JSP tags can be defined by the developers themselves and they are generating HTML. We as developers can therefore extend the behavior of HTML and thereby help the web designers.

For example, we might create a JSP tag that renders the enclosing text in bold and italic typeface. The code would generate an <i> tag for italic and a <b> for bold typeface. JSTL provides a standardized set of such custom tags in a library, therefore the name Standard Tag Library.

The JSTL covers a lot of different tags, too many to have a look at in this section – for our purposes we are just using a subset of the core tags. We include them by adding the following line to the header of our JSP:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

After that, we can use the core tags which are all prefixed by the XHTML namespace c. For our example we are just using the c:if tag for conditional rendering, the c:out tag for generating output and the c:forEach tag for iterating over the items of a collection. Take a look at how we are using them in Listing 4-2. As usually save the file in your workspace – this time replacing the existing content of memos.jsp.

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
  <meta charset="UTF-8">
  <title>My-Memo</title>
  <link rel="stylesheet" type="text/css" href="screen.css">
</head>
<body>
<div id="container">
  <div id="header">
    <p>
      <b>My-Memo</b> – A Simple Web App for Managing Memos
    </p>
  </div>
  <div id="content">
    <h1>Add Memo:</h1>
    <form method="POST" action="memos">
      <input type="text" name="memo" size="30" placeholder="Enter your memo here" />
      <button type="submit" name="button" value="save">Add</button>
      <c:if test="${!empty requestScope.err}">
        <span style="color: red"><c:out value="${requestScope.err}"/></span>
      </c:if>
      <h1>My Memos:</h1>
      <c:if test="${sessionScope.memos == null || sessionScope.memos.size() == 0}">
        <p>Please add some memos.</p>
      </c:if>
      <c:if test="${sessionScope.memos.size() > 0}">
        <table>
          <tr>
            <th>
              Memo
            </th>
            <th>
              Saved
            </th>
          </tr>
          <c:forEach items="${sessionScope.memos}" var="memo">
            <tr>
              <td>
                <c:out value="${memo.description}"/>
              </td>
              <td>
                <c:out value="${memo.created}"/>
              </td>
            </tr>
          </c:forEach>
        </table>
        <br/>
        <button type="submit" name="button" value="reset">Reset list</button>
      </c:if>
    </form>
  </div>
  <div id="footer">
    <p>(C) 2015 Schiesser/Schmollinger, MIT license</p>
  </div>
</div>
</body>
</html>

Listing 4-2 JSP file memos.jsp – Our updated JSP view using JSTL

The c:if tag is rather self-explaining: the attribute test defines an expression – if the expression evaluates to true the enclosed text is rendered, if not it is not rendered.
More interesting is what kind of expressions can be used. They must be defined in the so called EL (expression language). It is a simple language to evaluate expressions on JavaBeans. The syntax is similar to Java, but easier to read, e.g. we have an operator empty to check for an empty string.

The used expression !empty requestScope.err is therefore true, if the err attribute of the JavaBean requestScope is not empty. As requestScope is the EL’s name of our request object, we’re thereby checking if an error was generated by the controller class MemoServlet.

The c:out tag is even simpler, it evaluates the EL given in the value property and directly renders its result as HTML output.

Now it is also easier to understand the c:forEach tag. In the items attribute we are defining the collection we want to iterate over. In our case sessionScope.memos, which are the Memo objects stored in the user session.

The var attribute stores the name of the variable to reference the instance of the actual iteration. Therefore this variable is used in enclosing EL expressions. For example in the memo.description expression used by the c:out tag. It evaluates to the description attribute of the Memo object of the actual iteration. Therefore the description of the memo is rendered in this place.

With the help of JSTL we generated a view description which can be easier understood by web designers than JSP pages containing inline Java code.

4.4 Further Reading

As you can see, Java Servlets and JSPs work hand in hand in the MVC pattern. More details about JSP, Java Servlets and friends can be found in the following textbooks:

Joel Murach, 2014. Murach’s Java Servlets and JSP, 3rd Edition (Murach: Training & Reference). 3rd Edition. Mike Murach & Associates.

Mahesh P. Matha, 2013. JSP and SERVLETS: A Comprehensive Study. Edition. PHI.

 

Discussion

Use the message board below to give the authors your feedback or to discuss this page’s topic with other readers (in English please!). Please don’t expect the authors to answer directly, but they might update the content of this site according to your feedback.


  1. Remember, if you sign up to Codenvy, you will be able to persist the project in your workspace. This enables you to store intermediate states of your project, and by that, to make a break when ever you like. Otherwise, all your changes are volatile and will be lost after closing the browser.
  2. Codenvy does not provide a special menu item for JSP files. Please use the general menu item for file creation (New → File).
  3. In JSP the actual HttpServletRequest object as available as request and the actual HttpSession object as session.