HelpDesk Application Using JSF
HelpDesk is a web based customer support system. It allows customers to do the following:
- Customer must first register the product. We have one-to-one relationship between prodcut and customers. At the time of registration, customer details and
product serial number are taken.
- Customer can login after registration.
- Customer can post an issue related to the proudct he registered.
- Customer can reply to an issue posted by other customers. They can also reply to a reply given by support personal
- Customer can change his/her password
- If customer forgets password, customer can recover the password
- Customer can search for issues based on title of the issue and see all the details of the issue.
Technologies and Products Used
In order to develop this application we are going to use the following technologies.
- JSF framework
- JDBC
- DAO design pattern to access database
- Oracle database 10g Express Edition
- JavaMail API
- Mail Server - CMail Server
Tables Structure
The following are the tables required for this application.
CUSTOMERS Table
Contains details of all registered customers. Create this table using CREATE TABLE command as follows:
create table customers
(
customerid number(5) primary key,
loginname varchar(20) unique,
password varchar(10),
reg_date date,
email varchar(50) unique,
serialno varchar(50) unique
);
ISSUES Table
Stores all issues posted by customers. Create this table with the following CREATE TABLE command.
create table Issues
(
Issueid number(5) primary key,
customerid number(5) references customers(customerid),
issuetitle varchar(100),
issuedescription varchar(2000),
postedon date,
status char(1),
resolvedon date,
supportperson varchar(20)
);
ISSUERESPONSES Table
Stores all responses given either by support persons or by customers.
create table IssueResponses
(
IRId number(5) primary key,
Issueid number(5) references issues(issueid),
IRTitle varchar(100),
IRDescription varchar(2000),
Postedon date,
Postedby varchar(20)
);
Sequences
Oracle supports database object called sequence which can be used to get numbers in a sequence. This application uses three seqences - one for
customer id , one for issue id and another for issue response id. Create these sequences as follows:
create sequence customerid start with 1 increment by 1 nocache;
create sequence issueid start with 1 increment by 1 nocache;
create sequence irid start with 1 increment by 1 nocache;
Create Web Project using NetBeans IDE
Create a web application using NetBeans by following the steps given below:
- Start Netbeans IDE
- Select File->New Project
- Select web from categories and select Web application
- Click on Next
- Enter helpdesk as project name, select Bundled Tomcat as server
- Click on Next
- Check JavaServer Faces from Frameworks window
- Click on Finsh
Registration
Registration allows a customer to register the product he purchased. Along with serial number of the product, customer provides loginname,
password, email address etc.
It uses the following pages and methods of the project.
- register.jsp
- CustomerBean.register() method
- CustomerDAO.register() method
- CUSTOMERS table
- customerid sequence
all/register.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registration</title>
<link href="../styles.css" rel="stylesheet"/>
</head>
<body>
<center>
<f:view>
<div class="head">OnLine Help Desk</div>
<h:form>
<h3>Registration</h3>
<table>
<tr align="left">
<td>Login Name : </td>
<td> <h:inputText id="loginname" required="true" size="20" value="#{CustomerBean.loginname}" />
<h:message id="m1" for="loginname" /> </td>
</tr>
<tr align="left">
<td>Password : </td>
<td> <h:inputSecret id="password" required="true" size="20" style="width:150px" value="#{CustomerBean.password}" />
<h:message id="m2" for="password" />
</td>
</tr>
<tr align="left">
<td>Confirm Password : </td>
<td> <h:inputSecret id="confirmpassword" required="true" size="20" style="width:150px" value="#{CustomerBean.confirmpassword}" />
<h:message id="m3" for="confirmpassword" /> </td>
</tr>
<tr align="left">
<td>Email Address : </td>
<td><h:inputText id="email" required="true" size="20" value="#{CustomerBean.email}" />
<h:message id="m4" for="email" /> </td>
</tr>
<tr align="left">
<td>Serail No. : </td>
<td><h:inputText id="serialno" required="true" size="20" value="#{CustomerBean.serialno}" />
<h:message id="m5" for="serialno" /> </td>
</tr>
</table>
<p/>
<h:commandButton value="Register" actionListener="#{CustomerBean.register}" />
<p/>
<h4> <h:outputText escape="false" value="#{CustomerBean.message}"/> </h4>
</h:form>
</f:view>
</center>
</body>
</html>
/WEB-INF/classes/beans/CustomerBean.java
package beans;
import dao.CustomerDAO;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.jstl.sql.Result;
public class CustomerBean {
private String loginname,oldpassword,password,confirmpassword,email,serialno, message;
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmpassword() {
return confirmpassword;
}
public void setConfirmpassword(String confirmpassword) {
this.confirmpassword = confirmpassword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSerialno() {
return serialno;
}
public void setSerialno(String serialno) {
this.serialno = serialno;
}
public void register(ActionEvent evt){
if (! password.equals(confirmpassword)) {
message="Password and confirm password do not match!";
return;
}
boolean done = CustomerDAO.register(loginname,password,email,serialno);
if ( done)
message= "Registration Completed. Use <a href=../login.jsp>Login Page</a> to login.";
else
message= "Sorry! Could not complete registration.";
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Result getIssues() {
try {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
return CustomerDAO.getIssues( session.getAttribute("customerid").toString());
} catch(Exception ex) {
System.out.println(ex.getMessage());
return(null);
}
}
public void recoverPassword(ActionEvent evt) {
// get password
String password = CustomerDAO.getPassword(email);
if ( password == null)
message = "Sorry! Could not get password for the given email address";
else {
try {
// send mail to user
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);
// construct the message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("admin@homepc.com"));
msg.setRecipient(Message.RecipientType.TO,new InternetAddress(email));
msg.setDataHandler( new DataHandler(new String("<html><body>Dear Customer,<p/>Use the following password to login. <p/>Password:" + password + "<p/>Webmaster,<br>onlinehelpdesk.com<body></html>"),
"text/html"));
msg.setSubject("Password Recovery");
// send message
Transport.send(msg);
message = "Password is sent to your email address. Use that password to login!";
}
catch(Exception ex) {
message = "Sorry! Could not send mail!";
}
}
}
public void changePassword(ActionEvent evt) {
if (! password.equals(confirmpassword)) {
message="Error --> New password and confirm password do not match!";
return;
}
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
String status = CustomerDAO.changePassword(
session.getAttribute("customerid").toString(),getOldpassword(), password);
if ( status == null)
message="Password Has Been Changed Successfully";
else
message = "Error -->" + status;
}
public String login(){
String customerid = CustomerDAO.login(loginname,password);
if ( customerid == null) { // login failed
message="Sorry! Invalid Login!";
return "failed";
} else {
// get current session
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
session.setAttribute("customerid", customerid);
session.setAttribute("loginname",loginname);
return "success";
}
}
public String getOldpassword() {
return oldpassword;
}
public void setOldpassword(String oldpassword) {
this.oldpassword = oldpassword;
}
}
Note : Remeber CustomerBean.java is used as Managed bean for other JSF forms also. Method register() is used to call register() method of
CustomerDAO.java. Create CustomerDAO class in dao package as follows.
/WEB-INF/classes/dao/CustomerDAO.java
package dao;
import dao.Database;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.jsp.jstl.sql.Result;
import javax.servlet.jsp.jstl.sql.ResultSupport;
public class CustomerDAO {
public static String getPassword(String email) {
try {
Connection con = Database.getConnection();
PreparedStatement ps = con.prepareStatement("select password from customers where email = ?");
ps.setString(1,email);
ResultSet rs = ps.executeQuery();
String password = null;
if ( rs.next() )
password = rs.getString("password");
rs.close();
con.close();
return password;
} catch(Exception ex) {
return null;
}
}
public static Result getIssues(String customerid) throws Exception {
Connection con = Database.getConnection();
Statement statement = con.createStatement();
ResultSet resultSet = statement.executeQuery("select * from issues where customerid = " + customerid + " order by issueid desc");
System.out.println("got data");
return( ResultSupport.toResult(resultSet));
}
public static String login(String lname, String pwd) {
try {
Connection con = Database.getConnection();
if ( con == null )
return null;
PreparedStatement ps = con.prepareStatement("select customerid from customers where loginname = ? and password = ?");
ps.setString(1,lname);
ps.setString(2,pwd);
ResultSet rs = ps.executeQuery();
String customerid=null;
if ( rs.next() ) // found - return fullname
customerid = rs.getString(1);
rs.close();
con.close();
return customerid;
}
catch(Exception ex) {
return null;
}
}
public static String changePassword( String customerid, String oldpwd, String newpwd) {
try {
Connection con = Database.getConnection();
PreparedStatement ps = con.prepareStatement
("update customers set password = ? where customerid = ? and password = ?");
ps.setString(1, newpwd);
ps.setString(2, customerid);
ps.setString(3, oldpwd);
int count = ps.executeUpdate();
ps.close();
con.close();
if ( count == 1)
return null;
else
return "Invalid Old Password!";
} catch(Exception ex) {
return ex.getMessage();
}
}
public static String postIssue(String customerid, String title,String description) {
try {
Connection con = Database.getConnection();
PreparedStatement ps = con.prepareStatement("insert into issues values(issueid.nextval,?,?,?,sysdate,'o',null,null)");
ps.setString(1,customerid);
ps.setString(2,title);
ps.setString(3,description);
ps.executeUpdate();
return null;
} catch(Exception ex) {
return ex.getMessage();
}
}
public static String postReply(String issueid,String customer,String title,String description) {
try {
Connection con = Database.getConnection();
PreparedStatement ps = con.prepareStatement("insert into issueresponses values( irid.nextval,?,?,?,sysdate,?)");
ps.setString(1,issueid);
ps.setString(2,title);
ps.setString(3,description);
ps.setString(4,customer);
ps.executeUpdate();
return null;
} catch(Exception ex) {
return ex.getMessage();
}
}
public static boolean register(String loginname,String password, String email,String serialno) {
try {
Connection con = Database.getConnection();
PreparedStatement ps = con.prepareStatement("insert into customers values( customerid.nextval,?,?,sysdate,?,?)");
ps.setString(1,loginname);
ps.setString(2,password);
ps.setString(3,email);
ps.setString(4,serialno);
ps.executeUpdate();
return true;
} catch(Exception ex) {
System.out.println(ex.getMessage());
return false;
}
}
}
/WEB-INF/classes/dao/Database.java
package dao;
import java.sql.Connection;
import oracle.jdbc.pool.OracleDataSource;
public class Database {
static final String USERNAME="helpdesk";
static final String PASSWORD="helpdesk";
public static Connection getConnection()
{
try {
OracleDataSource ods = new OracleDataSource();
ods.setDriverType("thin");
ods.setServerName("localhost");
ods.setNetworkProtocol("tcp");
ods.setDatabaseName("xe");
ods.setPortNumber(1521);
ods.setUser(USERNAME);
ods.setPassword( PASSWORD);
Connection con = ods.getConnection();
return con;
}
catch(Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
}
Note: Make sure Oracle's JDBC driver is added to project using libraries node in NetBeans project. Oracle JDBC driver is found in ojdbc14.jar file.
Logging
Take customer's loginname and password and check whether the given details are found in CUSTOMERS table. JSP login.jsp (given below) takes
customer to home.jsp otherwise display error message.
- login.jsp
- CustomerBean.login() method
- CustomerDAO.login() method
- CUSTOMERS table
/login.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<center>
<f:view>
<div class="head">OnLine Help Desk</div>
<h:form>
<h3>Login </h3>
<table>
<tr>
<td align="right">Login Name : </td>
<td align="left"> <h:inputText id="loginname" required="true" style="width:150px" value="#{CustomerBean.loginname}" />
<h:message id="m1" for="loginname" />
</td>
</tr>
<tr>
<td align="right">Password : </td>
<td align="left"> <h:inputSecret id="password" required="true" style="width:150px" value="#{CustomerBean.password}" />
<h:message id="m2" for="password" /> </td>
</tr>
</table>
<p/>
<h:outputText value="#{CustomerBean.message}"/>
<p/>
<h:commandButton value="Login" action="#{CustomerBean.login}" />
</h:form>
<a href="./all/forgotpassword.jsp">Forgot Password </a>
<br/>
<a href="./all/register.jsp">Register New Product </a>
</f:view>
</center>
</body>
</html>
Home Page
This page is represented by home.jsp. It takes content from menu.jsp, myissues.jsp. All these files are given below.
- home.jsp
- menu.jsp
- myissues.jsp
- CustomerBean.getIssues() method
- CustomerDAO.getIssues() method
- ISSUES table
/home.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Home Page</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<table border="0" width="100%" height="600px">
<tr>
<td class="menu" valign="top" width="20%">
<%@include file="menu.jsp"%>
</td>
<td valign="top">
<jsp:include page="myissues.jsp"/>
</td>
</tr>
</table>
</html>
/menu.jsp
<h4>Welcome ${sessionScope.loginname} </h4>
<a href="postissue.jsp">Post Issue</a>
<p/>
<a href="search.jsp">Search Issues </a>
<p/>
<a href="home.jsp">My Issues </a>
<p/>
<a href="changepassword.jsp">Change Password </a>
<p/>
<a href="logout.jsp">Logout</a>
<p/>
/myissues.jsp
<h2>Pending Issues</h1>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<f:view>
<h:form>
<h:dataTable rendered="#{CustomerBean.issues.rowCount > 0}" value="#{CustomerBean.issues}" var="issue" width="100%" border="1" >
<h:column>
<f:facet name="header"> <f:verbatim>Title</f:verbatim> </f:facet>
<h:outputText value="#{issue.issuetitle}"/>
</h:column>
<h:column>
<f:facet name="header"> <f:verbatim>PostedOn</f:verbatim> </f:facet>
<h:outputText value="#{issue.postedon}"/>
</h:column>
<h:column>
<f:facet name="header"><f:verbatim>Status</f:verbatim> </f:facet>
<h:outputText value="#{issue.status == 'o' ? 'Open' : 'Closed'}"/>
</h:column>
<h:column>
<f:facet name="header"><f:verbatim> </f:verbatim></f:facet>
<h:outputLink value="showissue.jsp">
<h:outputText value="Details"/>
<f:param name="issueid" value="#{issue.issueid}"/>
</h:outputLink>
</h:column>
</h:dataTable>
</h:form>
</f:view>
Posting an Issue
JSP postissue.jsp allows customer to post an issue. It uses PostIssueBean.java, which uses CustomerDAO.postIssue() method.
- postissue.jsp
- PostIssueBean.postIssue() method
- CustomerDAO.postIssue() method
- ISSUES table
- issueid sequence
/postissue.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Post Issue</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<table border="0" width="100%" height="600px">
<tr>
<td class="menu" valign="top" width="20%">
<%@include file="menu.jsp"%>
</td>
<td valign="top">
<h2>Post Issue </h2>
<f:view>
<h:form>
<table>
<tr>
<td>Isseue Title : </td>
<td> <h:inputText id="title" required="true" size="50" value="#{PostIssueBean.title}" />
<h:message id="m1" for="title" />
</td>
</tr>
<tr>
<td valign="top">Isseue Description : </td>
<td> <h:inputTextarea id="description" rows="5" cols="50" value="#{PostIssueBean.description}" />
<h:message id="m2" for="description" />
</tr>
</table>
<p/>
<h:commandButton value="Post Issue" actionListener="#{PostIssueBean.postIssue}" />
<p/>
<h:outputText value="#{PostIssueBean.message}"/>
</h:form>
</f:view>
</td>
</tr>
</table>
</html>
/WEB-INF/classes/beans/PostIssueBean.java
package beans;
import dao.CustomerDAO;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpSession;
public class PostIssueBean {
private String title;
private String description;
private String message = "";
public PostIssueBean() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void postIssue(ActionEvent evt) {
// post issue here
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
String status = CustomerDAO.postIssue( session.getAttribute("customerid").toString(),
title, description);
if ( status == null)
message="Issue Has Been Posted Successfully";
else
message = "Error -->" + status;
}
}
Displaying Details of an Issue
You can click on Details link for an Issue in home page or in search page to get details of an issue. JSP showissue.jsp is used to display
details of an issue. It also contains a link to post reply to an issue.
- showissue.jsp
- IssueDAO.getDetails() method
- Issue and Reply classes
- CUSTOMERS, ISSUES and ISSUERESPONSES tables
/showissue.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8" import="dao.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Issue Details</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<table border="0" width="100%" height="600px">
<tr>
<td class="menu" valign="top" width="20%">
<%@include file="menu.jsp"%>
</td>
<td valign="top">
<h2>Issue Details</h2>
<div class="issue">
<%
String issueid = request.getParameter("issueid");
Issue issue = IssueDAO.getDetails(issueid);
if (issue == null)
return;
session.setAttribute("title",issue.getTitle()); // used by postreply.jsp
session.setAttribute("issueid",issue.getIssueid()); // used by postreply.jsp
%>
<h4><%= issue.getTitle() %> </h4>
<pre><%=issue.getDescription()%></pre>
Posted By : <%= issue.getCustomer()%> <br/>
Posted On : <%= issue.getPostedon()%>
<%
if ( issue.getStatus().equals("c") ) {
out.println("<br/>Closed On : " + issue.getResolvedon() + " By " + issue.getSupportperson());
}
else
out.println("<p/><a href=postreply.jsp>Post Reply </a> <p/>");
%>
</div>
<%
if ( issue.getReplies().size() == 0 )
return;
%>
<h3>Replies </h3>
<%
for(Reply r : issue.getReplies()) {
out.println("<div class=reply>");
out.println( "<h4>" + r.getTitle() + "</h4>");
out.println("<pre>" + r.getDescription() + "</pre>");
out.println( "Posted on " + r.getPostedon() + " by " + r.getPostedby());
out.println("</div> <p/>");
}
%>
</td>
</tr>
</table>
%>
</body>
</html>
/WEB-INF/classes/dao/IssueDAO.java
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.servlet.jsp.jstl.sql.Result;
import javax.servlet.jsp.jstl.sql.ResultSupport;
public class IssueDAO {
public static Issue getDetails(String issueid) {
Connection con=null;
PreparedStatement ps =null;
try {
con = Database.getConnection();
ps = con.prepareStatement("select i.*, loginname from issues i, customers c where issueid = ? and c.customerid = i.customerid");
ps.setString(1,issueid);
ResultSet rs = ps.executeQuery();
if (! rs.next() ) return null;
Issue issue = new Issue();
issue.setIssueid(issueid);
issue.setCustomerid( rs.getString("customerid"));
issue.setCustomer( rs.getString("loginname"));
issue.setTitle( rs.getString("issuetitle"));
issue.setDescription( rs.getString("issuedescription"));
issue.setPostedon( rs.getString("postedon"));
issue.setStatus( rs.getString("status"));
issue.setResolvedon( rs.getString("resolvedon"));
issue.setSupportperson( rs.getString("supportperson"));
rs.close();
// get replies
ps = con.prepareStatement("select * from issueresponses where issueid = ?");
ps.setString(1,issueid);
ArrayList<Reply> replies = new ArrayList<Reply>();
rs = ps.executeQuery();
while ( rs.next()){
Reply r = new Reply();
r.setTitle( rs.getString("irtitle"));
r.setDescription( rs.getString("irdescription"));
r.setPostedon( rs.getString("postedon"));
r.setPostedby( rs.getString("postedby"));
replies.add(r);
}
rs.close();
issue.setReplies(replies);
con.close();
return issue;
} catch(Exception ex) {
System.out.println(ex.getMessage());
return null;
}
finally {
try {
ps.close();
con.close();
}
catch(Exception ex) {}
}
}
public static Result search(String pattern) {
Connection con=null;
PreparedStatement ps =null;
try {
con = Database.getConnection();
ps = con.prepareStatement("select * from issues where upper(issuetitle) like ? order by issueid desc");
ps.setString(1,"%" + pattern.toUpperCase() + "%");
ResultSet rs = ps.executeQuery();
return ResultSupport.toResult(rs);
} catch(Exception ex) {
System.out.println(ex.getMessage());
return null;
}
finally {
try {
ps.close();
con.close();
}
catch(Exception ex) {}
}
} // search
}
/WEB-INF/classes/dao/Issue.java
package dao;
import java.util.ArrayList;
import java.util.List;
public class Issue {
private String issueid, customerid, customer,
title, description, postedon, status,
resolvedon, supportperson;
private ArrayList<Reply> replies;
public String getIssueid() {
return issueid;
}
public void setIssueid(String issueid) {
this.issueid = issueid;
}
public String getCustomerid() {
return customerid;
}
public void setCustomerid(String customerid) {
this.customerid = customerid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPostedon() {
return postedon;
}
public void setPostedon(String postedon) {
this.postedon = postedon;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getResolvedon() {
return resolvedon;
}
public void setResolvedon(String resolvedon) {
this.resolvedon = resolvedon;
}
public String getSupportperson() {
return supportperson;
}
public void setSupportperson(String supportperson) {
this.supportperson = supportperson;
}
public ArrayList<Reply> getReplies() {
return replies;
}
public void setReplies(ArrayList<Reply> replies) {
this.replies = replies;
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
}
/WEB-INF/classes/dao/Reply.java
package dao;
public class Reply {
private String issueid, title,description,
postedon, postedby;
public String getIssueid() {
return issueid;
}
public void setIssueid(String issueid) {
this.issueid = issueid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPostedon() {
return postedon;
}
public void setPostedon(String postedon) {
this.postedon = postedon;
}
public String getPostedby() {
return postedby;
}
public void setPostedby(String postedby) {
this.postedby = postedby;
}
}
Posting a reply
From the details of an issue, customer can post a reply to an issue. JSP
postreply.jsp is used to post reply. At the time of posting a reply customer
provides title and description.
- postreply.jsp
- PostReplyBean.postReply() method
- CustomerDAO.postReply() method
- ISSUERESPONSES Table
- irid sequence
/postreply.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Post Reply</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<table border="0" width="100%" height="600px">
<tr>
<td class="menu" valign="top" width="20%">
<%@include file="menu.jsp"%>
</td>
<td valign="top">
<h2>Post Reply</h2>
<f:view>
<h:form>
<table>
<tr>
<td>Reply Title : </td>
<td> <h:inputText id="title" required="true" size="50" value="#{PostReplyBean.title}" />
<h:message id="m1" for="title" />
</td>
</tr>
<tr>
<td valign="top">Reply Description : </td>
<td> <h:inputTextarea id="description" rows="5" cols="50" value="#{PostReplyBean.description}" />
<h:message id="m2" for="description" />
</tr>
</table>
<p/>
<h:commandButton value="Post Reply" actionListener="#{PostReplyBean.postReply}" />
<p/>
<h:outputText value="#{PostReplyBean.message}"/>
</h:form>
</f:view>
</td>
</tr>
</table>
</html>
/WEB-INF/classes/beans/PostReplyBean.java
package beans;
import dao.CustomerDAO;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class PostReplyBean {
private String issueid, title, description, message, customer;
public PostReplyBean() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
title = "Re: " + (String) session.getAttribute("title");
customer = (String) session.getAttribute("loginname");
issueid = (String) session.getAttribute("issueid");
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void postReply(ActionEvent evt) {
String status = CustomerDAO.postReply(issueid,customer,title, description);
if ( status == null)
setMessage("Reply Has Been Posted Successfully");
else
setMessage("Error -->" + status);
}
}
Searching for Issues
JSP search.jsp is used to search for issues based on the string. It looks for issues that contain the given string in the title.
- search.jsp
- SearchBean.getIssues() method
- IssueDAO.search() method
- ISSSUES Table
/search.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Home Page</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<table border="0" width="100%" height="600px">
<tr>
<td class="menu" valign="top" width="20%">
<%@include file="menu.jsp"%>
</td>
<td valign="top">
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<f:view>
<h:form>
<h2>Search Issues</h1>
Search <h:inputText id="pattern" value="#{SearchBean.pattern}"/>
<h:commandButton value="Search"/>
<p/>
<h:dataTable rendered="#{SearchBean.issues.rowCount > 0}" value="#{SearchBean.issues}" var="issue" width="100%" border="1">
<h:column>
<f:facet name="header"> <f:verbatim>Title</f:verbatim> </f:facet>
<h:outputText value="#{issue.issuetitle}"/>
</h:column>
<h:column>
<f:facet name="header"> <f:verbatim>PostedOn</f:verbatim> </f:facet>
<h:outputText value="#{issue.postedon}"/>
</h:column>
<h:column>
<f:facet name="header"><f:verbatim>Status</f:verbatim> </f:facet>
<h:outputText value="#{issue.status == 'o' ? 'Open' : 'Closed'}"/>
</h:column>
<h:column>
<f:facet name="header"><f:verbatim> </f:verbatim></f:facet>
<h:outputLink value="showissue.jsp">
<h:outputText value="Details"/>
<f:param name="issueid" value="#{issue.issueid}"/>
</h:outputLink>
</h:column>
</h:dataTable>
</h:form>
</f:view>
</td>
</tr>
</table>
</body>
</html>
Changing password
JSP changepassword.jsp is used to change password. It uses changePassword() method of CustomerDAO.
- changepassword.jsp
- CustomerBean.changePassword() method
- CustomerDAO.changePassword() method
- CUSTOMERS table
/changepassword.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Change Password</title>
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<table border="0" width="100%" height="600px">
<tr>
<td class="menu" valign="top" width="20%">
<%@include file="menu.jsp"%>
</td>
<td valign="top">
<h2>Change Password</h2>
<f:view>
<h:form>
<table>
<tr>
<td>Old Password : </td>
<td><h:inputSecret id="oldpassword" required="true" size="20" value="#{CustomerBean.oldpassword}"/>
<h:message id="m1" for="oldpassword" />
</td>
</tr>
<tr>
<td>New Password : </td>
<td> <h:inputSecret id="password" required="true" size="20" value="#{CustomerBean.password}" />
<h:message id="m1" for="password" />
</td>
</tr>
<tr>
<td>Confirm Password : </td>
<td> <h:inputSecret id="confirmpassword" required="true" size="20" value="#{CustomerBean.confirmpassword}" />
<h:message id="m1" for="confirmpwd" />
</td>
</tr>
</table>
<p/>
<h:commandButton value="Change Password" actionListener="#{CustomerBean.changePassword}" />
<p/>
<h:outputText value="#{CustomerBean.message}"/>
</h:form>
</f:view>
</td>
</tr>
</table>
</html>
Recovering password
JSP forgotpassword.jsp takes email address and then sends password of the
customer with that email address as a mail.
- forgotpassword.jsp
- CustomerBean.recoverPassword() method
- CustomerDAO.getPassword() method
- CUSTOMERS table
- Java Mail API
- Mail server - Cmail Server
/all/forgotpassword.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Forgot Password</title>
<link href="../styles.css" rel="stylesheet"/>
</head>
<body>
<center>
<f:view>
<div class="head">OnLine Help Desk</div>
<h:form>
<h3>Forgot Password</h3>
Email Address : <h:inputText id="email" required="true" size="20" value="#{CustomerBean.email}" />
<h:message id="m4" for="email" /> </td>
<p/>
<h:commandButton value="Submit" actionListener="#{CustomerBean.recoverPassword}" />
<p/>
<h4> <h:outputText escape="false" value="#{CustomerBean.message}"/> </h4>
</h:form>
</f:view>
</center>
</body>
</html>
Log out
JSP logout.jsp is used to terminate session and transfer control to login.jsp.
/logout.jsp
<%
session.invalidate();
response.sendRedirect("login.jsp");
%>
Authentication Filter
A filter is used to ensure only authenticated user can access pages in root folder. But pages in all folder, styles.css, and login.jsp can be
accessed even with anonymous users.
/WEB-INF/classes/filter/AuthFilter.java
package filter;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class AuthFilter implements Filter {
private FilterConfig filterConfig = null;
public AuthFilter() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try {
// check whether session variable is set
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession ses = req.getSession(false);
System.out.println( req.getRequestURI());
if ( req.getRequestURI().indexOf("/all/") >= 0 ||
req.getRequestURI().indexOf("/styles.css") >= 0 ||
req.getRequestURI().indexOf("/login.jsp") >=0 ) {
chain.doFilter(request, response);
}
else
if (ses == null || ses.getAttribute("loginname") == null) {
res.sendRedirect(req.getContextPath() + "/faces/login.jsp");
}
else
chain.doFilter(request, response);
}
catch(Throwable t) {
System.out.println( t.getMessage());
}
}
public FilterConfig getFilterConfig() {
return (this.filterConfig);
}
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public void destroy() {
}
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
}
Other important files
This project also contains other files like faces-config.xml, and messages.properties file.
/WEB-INF/faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<!-- =========== FULL CONFIGURATION FILE ================================== -->
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
<managed-bean>
<managed-bean-name>CustomerBean</managed-bean-name>
<managed-bean-class>beans.CustomerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>PostIssueBean</managed-bean-name>
<managed-bean-class>beans.PostIssueBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>PostReplyBean</managed-bean-name>
<managed-bean-class>beans.PostReplyBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>SearchBean</managed-bean-name>
<managed-bean-class>beans.SearchBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<application>
<message-bundle>messages</message-bundle>
</application>
<navigation-rule>
<description>
</description>
<from-view-id>/login.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/home.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
/styles.css
div.head {
background-color: navy;
color: orange;
font-family: arial;
font-size: 30pt;
font-weight: bold;
letter-spacing: 5px
}
div.issue {
background-color: #ffcc00;
border-bottom-style: solid;
border-bottom-width: 1px;
border-left-style: solid;
border-left-width: 1px;
border-right-style: solid;
border-right-width: 1px;
border-top-style: solid;
border-top-width: 1px;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 10pt
}
div.reply {
background-color: #ffff99;
border-bottom-style: solid;
border-bottom-width: 1px;
border-left-style: solid;
border-left-width: 1px;
border-right-style: solid;
border-right-width: 1px;
border-top-style: solid;
border-top-width: 1px;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 10pt
}
body {
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 10pt;
margin:0px;
}
td.menu {
background-color: wheat
}
/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>filter.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
</web-app>
/WEB-INF/classes/messages.properties
# Sample ResourceBundle properties file
javax.faces.component.UIInput.REQUIRED=Value Required!
Steps to download and use this application
You can download the entire helpdesk project as NetBeans project. Then follow the steps given below
to open the project and add required components.
- Unzip helpdesk.zip using WinZip or WinRar. It creates a folder called helpdesk.
- Start NetBeans, select File->Open Project and select helpdesk as the folder to open the project.
- Add JSF, JSTL libraries using Add Library option of popup menu invoked using right click on the project
- Add ojdbc14.jar , activation.jar and mail.jar to project libraries.
- Build project and run login.jsp
Srikanth.