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].
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:
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.
- 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. ↵
- Codenvy does not provide a special menu item for JSP files. Please use the general menu item for file creation (
New → File
). ↵ - In JSP the actual
HttpServletRequest
object as available asrequest
and the actualHttpSession
object assession
. ↵