Implementation
In a JSP application, putting all of the Java codes in the JSP pages is not a good practice. You should separate the presentation layer from the business logic. In this way, you can easily adapt the application to a new look without changing the infrastructural codes.
As I mentioned before, we store the issue records in a H2 memory database. We put the database implementation codes in a new Java class, not in the JSP page. To keep simple dependency list, we choose pure JDBC approach for database access, not an ORM tool like Hibernate, or another helper framework like Spring JDBC. The code of our database access class “DbOperations” is below. We call it in the JSP page to perform the database layer executions.
DbOperations.java
package com.javacodegeeks.examples.jspexample.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.javacodegeeks.examples.jspexample.db.entity.Issue;
public class DbOperations {
private static DbOperations theInstance = new DbOperations();
private Connection connection;
private DbOperations() {
try {
Class.forName( "org.h2.Driver" );
connection = DriverManager.getConnection( "jdbc:h2:mem:testdb", "sa", "" );
// Create table
final PreparedStatement ps = connection
.prepareStatement( "CREATE TABLE ISSUE( ID INT PRIMARY KEY auto_increment, TITLE VARCHAR, OPENEDBY VARCHAR, PRIORITY VARCHAR, STATUS VARCHAR DEFAULT 'OPEN', COMMENT VARCHAR, CREATE_DATE TIMESTAMP DEFAULT NOW() )" );
ps.executeUpdate();
} catch ( final ClassNotFoundException e ) {
e.printStackTrace();
} catch ( final SQLException e ) {
e.printStackTrace();
}
}
public static DbOperations getTheInstance() {
return theInstance;
}
public void addNewIssueRecord( final String title, final String openedBy, final String priority,
final String comments ) {
try {
final PreparedStatement ps = connection
.prepareStatement( "INSERT INTO ISSUE( TITLE, OPENEDBY, PRIORITY, COMMENT ) VALUES ( ?, ?, ?, ? )" );
ps.setString( 1, title );
ps.setString( 2, openedBy );
ps.setString( 3, priority );
ps.setString( 4, comments );
ps.executeUpdate();
} catch ( final SQLException e ) {
e.printStackTrace();
}
}
public List getAllIssues() {
final List issueList = new ArrayList();
try {
final PreparedStatement ps = connection
.prepareStatement( "SELECT ID, TITLE, OPENEDBY, PRIORITY, STATUS, COMMENT, CREATE_DATE FROM ISSUE" );
final ResultSet rs = ps.executeQuery();
while ( rs.next() ) {
final Issue issue = new Issue();
issue.setComments( rs.getString( "COMMENT" ) );
issue.setCreateDate( new Date() );
issue.setId( rs.getInt( "ID" ) );
issue.setOpenedby( rs.getString( "OPENEDBY" ) );
issue.setPriority( rs.getString( "PRIORITY" ) );
issue.setStatus( rs.getString( "STATUS" ) );
issue.setTitle( rs.getString( "TITLE" ) );
issueList.add( issue );
}
} catch ( final SQLException e ) {
e.printStackTrace();
}
return issueList;
}
public void updateIssueRecord( final String id, final String newStatus ) {
try {
final PreparedStatement ps = connection
.prepareStatement( "UPDATE ISSUE SET STATUS = ? WHERE ID = ?" );
ps.setString( 1, newStatus );
ps.setInt( 2, Integer.parseInt( id ) );
ps.executeUpdate();
} catch ( final SQLException e ) {
e.printStackTrace();
}
}
}
At the top of the JSP page, we place the “taglib” and “page” JSP directives to import the backend Java classes and Servlets in the application and JSTL tag libraries.
Bootstrap is a popular HTML, CSS, and JS framework. It contains predefined css classes, icons that help the developers to form the gui look easily. We use it to build the jsp page appearance. The html codes that generate the “new issue form” are below:
The Html codes of the issue list are below. Later, we will discuss the fundamental lines and explain them.
<%
List< Issue > issueList = DbOperations.getTheInstance().getAllIssues();
pageContext.setAttribute("issueList", issueList);
Map< String, String > issueColors = new HashMap< String, String >();
issueColors.put( "OPEN", "#E2C8C8" );
issueColors.put( "FIX", "#C1E212" );
pageContext.setAttribute("issueColors", issueColors );
%>
<div style="width: 800px; margin-left: 50px; margin-top: 30px;">
<%
if ( issueList.size() > 0 ) {
%>
<div class="col-md-11">
<div class="panel panel-default">
<div class="panel-heading">
<i class="icon-calendar"></i>
<h3 class="panel-title">Issue List</h3>
</div>
<div class="panel-body">
<table class="table table-hover col-md-11">
<thead>
<tr>
<th class="col-md-2">Title</th>
<th class="col-md-2">Opened By</th>
<th class="col-md-1">Priority</th>
<th class="col-md-2">Create Time</th>
<th class="col-md-1">Status</th>
<th class="col-md-1">Fix</th>
<th class="col-md-1">Close</th>
<th class="col-md-1">Reopen</th>
</tr>
</thead>
<tbody>
<c:forEach items="${issueList}" var="item">
<c:if test="${item.status ne 'CLOSE'}">
<tr style="background-color: ${issueColors[item.status]}">
<td><c:out value="${item.title}"/></td>
<td><c:out value="${item.openedby}"/></td>
<td><c:out value="${item.priority}"/></td>
<td><fmt:formatDate value="${item.createDate}" pattern="dd-MM-yyyy HH:mm" /></td>
<td><c:out value="${item.status}"/></td>
<td><input type="button" <c:if test="${item.status == 'FIX'}"> disabled="disabled" </c:if> onclick="location.href = '/jspexample/updateIssue?id=<c:out value="${item.id}"/>&newStatus=FIX'" value="Fix" /></td>
<td><input type="button" onclick="location.href = '/jspexample/updateIssue?id=<c:out value="${item.id}"/>&newStatus=CLOSE'" value="Close" /></td>
<td><input type="button" <c:if test="${item.status == 'OPEN'}"> disabled="disabled" </c:if> onclick="location.href = '/jspexample/updateIssue?id=<c:out value="${item.id}"/>&newStatus=OPEN'" value="Reopen" /></td>
</tr>
</c:if>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
<%
}
%>
</div>
First of all, the issue records are retrieved from the database through the instance. In the JSP page, we can access to the other Java classes in the classpath. Please note that we already import the class with JSP page directive at the top of the page. A compilation error occurs in the JSP page, unless you import an external Java class name.
<%@ page import="com.javacodegeeks.examples.jspexample.db.DbOperations"%> ... % List< Issue > issueList = DbOperations.getTheInstance().getAllIssues();
Notice the “if statement” before the issue list code. We will show the list, if only the issue list has at least one item. The html codes between the false condition statements are not rendered, because they are not added to the Jsp counterpart Servlet class by the compiler.
<% if ( issueList.size() > 0 ) { %> .... // Issue list HTML codes. <% } %>
We use JSTL tag library in the JSP page. <c:forEach tag creates the loop and for each item in the “issue list”, a table row is printed. In the loop, the issues with ‘CLOSE’ status are not displayed in the list. We construct the “if statement” with the <c:if JSTL tag. As you see, the condition is tested with ${item.status ne 'CLOSE'}. This code is an example of JSP expression language. ne is represented as ‘not equal’ and it is one of the JSP EL relational operators. The others are == (eq), != (ne), (gt), = (ge).
We use the JSTL fmt (format) tag in order to format the issue “createDate” date variable:
<td><fmt:formatDate value="${item.createDate}" pattern="dd-MM-yyyy HH:mm" /></td>
We do not want the “fix button” being active if the issue status is already ‘FIX’ and in a same manner, the “reopen button” should be active if the issue status is not ‘OPEN’. We provide it inserting JSTL “if statement” in the button HTML code and put disabled="disabled" code if the relevant condition is true:
<td><input type="button" <c:if test="${item.status == 'FIX'}"> disabled="disabled" </c:if> ...
In the example project, there is a simple “Java bean” class like below:
package com.javacodegeeks.examples.jspexample.db.entity;
package com.javacodegeeks.examples.jspexample.servlet;
<c:forEach items="${issueList}" var="item">
<c:if test="${item.status ne 'CLOSE'}">
How can we set different background colors to the issue rows depending on their status? We store the color codes in a “Map”
of which the keys are their status data:
Map issueColors = new HashMap(); issueColors.put( "OPEN", "#E2C8C8" ); issueColors.put( "FIX", "#C1E212" );
we access this map with an expression language pattern while determining the background color of the issue row:
<tr style="background-color: ${issueColors[item.status]}">
How can we set different background colors to the issue rows depending on their status? We store the color codes in a “Map”
of which the keys are their status data:
Map issueColors = new HashMap(); issueColors.put( "OPEN", "#E2C8C8" ); issueColors.put( "FIX", "#C1E212" );
we access this map with an expression language pattern while determining the background color of the issue row:
<tr style="background-color: ${issueColors[item.status]}">
We use the JSTL fmt (format) tag in order to format the issue “createDate” date variable:
<td><fmt:formatDate value="${item.createDate}" pattern="dd-MM-yyyy HH:mm" /></td>
We do not want the “fix button” being active if the issue status is already ‘FIX’ and in a same manner, the “reopen button” should be active if the issue status is not ‘OPEN’. We provide it inserting JSTL “if statement” in the button HTML code and put disabled="disabled" code if the relevant condition is true:
<td><input type="button" <c:if test="${item.status == 'FIX'}"> disabled="disabled" </c:if> ...
In the example project, there is a simple “Java bean” class like below:
package com.javacodegeeks.examples.jspexample.db.entity;
public class Company {
private String name;
private String establishYear;
public String getName() {
return name;
}
public void setName( final String name ) {
this.name = name;
}
public String getEstablishYear() {
return establishYear;
}
public void setEstablishYear( final String establishYear ) {
this.establishYear = establishYear;
}
}
To give an example of Jsp actions, we write a string “A company since 1998” in the page. “A” refers to the “name” variable and “1998” refers to the “establishYear” variable of the “Company” java bean. useBean jsp action uses the current java bean instance or creates new one if it does not exist. setProperty jsp action enables to set value to the property of the bean. getProperty jsp action inserts the property of a JavaBean into the output. In the example code, we print the values of the “Company” bean properties ( name and establishYear ) after setting values ( “A”, “1998” ) to them:
To give an example of Jsp actions, we write a string “A company since 1998” in the page. “A” refers to the “name” variable and “1998” refers to the “establishYear” variable of the “Company” java bean. useBean jsp action uses the current java bean instance or creates new one if it does not exist. setProperty jsp action enables to set value to the property of the bean. getProperty jsp action inserts the property of a JavaBean into the output. In the example code, we print the values of the “Company” bean properties ( name and establishYear ) after setting values ( “A”, “1998” ) to them:
<div>
<jsp:useBean id="companyBean" class="com.javacodegeeks.examples.jspexample.db.entity.Company" />
<jsp:setProperty property="name" name="companyBean" value="A"/>
<jsp:setProperty property="establishYear" name="companyBean" value="1998"/>
<b><jsp:getProperty property="name" name="companyBean"/></b> company since
<b><jsp:getProperty property="establishYear" name="companyBean"/></b>
</div>
Now I would like to mention the Servlets in the example. When we click on the “submit” button in the form, the “doPost” method of the “AddIssueServlet” servlet evaluates this action. The parameter values are transported via the request object. In this “doPost” method, these parameter values are taken and used to insert a new issue record in the database. Then the servlet invokes the jsp page to render again with the Servlet sendRedirect method. The name of the our JSP page is “index.jsp”. Please note that “index.jsp” page is the default welcome page, so you do not have to write it explicitly. Thus we only set “/jspexample/” ( context root name of the application ) as the parameter of the “sendRedirect” method call:
Now I would like to mention the Servlets in the example. When we click on the “submit” button in the form, the “doPost” method of the “AddIssueServlet” servlet evaluates this action. The parameter values are transported via the request object. In this “doPost” method, these parameter values are taken and used to insert a new issue record in the database. Then the servlet invokes the jsp page to render again with the Servlet sendRedirect method. The name of the our JSP page is “index.jsp”. Please note that “index.jsp” page is the default welcome page, so you do not have to write it explicitly. Thus we only set “/jspexample/” ( context root name of the application ) as the parameter of the “sendRedirect” method call:
package com.javacodegeeks.examples.jspexample.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.javacodegeeks.examples.jspexample.db.DbOperations;
@WebServlet( value = "/addIssue" )
public class AddIssueServlet extends HttpServlet {
private static final long serialVersionUID = -1L;
@Override
protected void doPost( final HttpServletRequest request, final HttpServletResponse response )
throws ServletException, IOException {
final String title = request.getParameter( "title" );
final String openedBy = request.getParameter( "openedby" );
final String priority = request.getParameter( "priority" );
final String comments = request.getParameter( "comments" );
DbOperations.getTheInstance().addNewIssueRecord( title, openedBy, priority, comments );
response.sendRedirect( "/jspexample/" );
}
}
Clicking the “fix”, “close” and “reopen” buttons in the issue list rows fires another Servlet event in order to update the
status of the current issue:
package com.javacodegeeks.examples.jspexample.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.javacodegeeks.examples.jspexample.db.DbOperations;
@WebServlet( value = "/updateIssue" )
public class UpdateIssueServlet extends HttpServlet {
private static final long serialVersionUID = -1L;
@Override
protected void doGet( final HttpServletRequest request, final HttpServletResponse response )
throws ServletException, IOException {
final String newStatus = request.getParameter( "newStatus" );
final String id = request.getParameter( "id" );
DbOperations.getTheInstance().updateIssueRecord( id, newStatus );
response.sendRedirect( "/jspexample/" );
}
}
cool..keep it up :)
ReplyDeletethank you for your support!!
Delete