Java Web Servlet Annotation Example
Create a Simple Java Web Application Using Servlet, JSP and JDBC
- Introduction
- The principle when programming Servlet + JSP
- View Demo of Web Application will do
- Prepare database
- Create WebApp Project
- Configuring the runtime environment
- Run application for first time
- Download and declare JDBC library
- Download and declare JSTL library
- Javabean classes simulated tables in the database
- Database Connection Utility classes
- The utility class & manipulate data
- Create Servlet Filter connect to Database
- Servlet Filter reads Cookies to automatically login
- EncodingFilter Servlet
- Pages reuse
- Home Page
- Login Page - LoginServlet
- Product List Page
- Add Product Page
- Edit Product Page
- Delete Product
1- Introduction
This document is based on:
- Eclipse 4.5 MARS
- Tomcat 8.x
In this document, I will guide step by step how to create a simple web application with the combiantion ofServlet+JSP+Filter+JSP EL + JDBC.Make sure that you've masteredServlet, JSP andFilter andJDBCbefore the start. If not, you can refer to:
NOTE: In this post I only introduce about CRUD, "Login" and "Remember Me" function. And do not handle the security of the pages. If you want to have an application, secure each page, please refer to the article below:
2- The principle when programming Servlet + JSP
These are the principles that you should keep in mind to be able to build a Web application usingServlet + JSP satisfying criteria: code is simple, easy to understand and easy to maintain.
The principles:
- Never allow users to directly access to your JSP page.
- JSP is only considered as the place to display interface.
- Servlet acts as the controller of the application flows and program logical processing.
- Open the JDBC connection and transaction management in Filter (Optional).
According to the principle 1:
Never allow users to directly access to your JSP page, it means that all user's requests are:
- Another source of static data (images, css, js, ...)
- Or a servlet.
Therefore, you must hide your JSP files in a place where the user can not access. For instance, set it in the WEB-INF folder or its subdirectories. In this example, I hide the jsp files in the WEB-INF/views.
When the user requests to a Servlet, it will dispose user's requirements, such insert, update and query the data, eventually forward to the JSP page to display the data. Thus, each servlet has 0 or multiple corresponding JSP pages (Usually only need 1).
Principle 2:
JSP is only considered as the place to display data, which means that you should not handle the application logic on the JSP, such as update, insert, delete, .., and not navigate on the JSP page.
3- View Demo of Web Application will do
You can preview Demo Web application will do:
4- Prepare database
In this document, I instruct you to work with one of 3 databases: Oracle, MySQL or SQL Server. You need to run scripts to create some tables and necessary data for this example.
ORACLE:
-- Create table create table USER_ACCOUNT ( USER_NAME VARCHAR2(30) not null, GENDER VARCHAR2(1) not null, PASSWORD VARCHAR2(30) not null, primary key (USER_NAME) ); -- Create table create table PRODUCT ( CODE VARCHAR2(20) not null, NAME VARCHAR2(128) not null, PRICE FLOAT not null, primary key (CODE) ) ; -- Insert data: --------------------------------------------------------------- insert into user_account (USER_NAME, GENDER, PASSWORD) values ('tom', 'M', 'tom001'); insert into user_account (USER_NAME, GENDER, PASSWORD) values ('jerry', 'M', 'jerry001'); insert into product (CODE, NAME, PRICE) values ('P001', 'Java Core', 100); insert into product (CODE, NAME, PRICE) values ('P002', 'C# Core', 90); -- Commit Commit;
MYSQL:
-- Create table create table USER_ACCOUNT ( USER_NAME VARCHAR(30) not null, GENDER VARCHAR(1) not null, PASSWORD VARCHAR(30) not null, primary key (USER_NAME) ); -- Create table create table PRODUCT ( CODE VARCHAR(20) not null, NAME VARCHAR(128) not null, PRICE FLOAT not null, primary key (CODE) ) ; -- Insert data: --------------------------------------------------------------- insert into user_account (USER_NAME, GENDER, PASSWORD) values ('tom', 'M', 'tom001'); insert into user_account (USER_NAME, GENDER, PASSWORD) values ('jerry', 'M', 'jerry001'); insert into product (CODE, NAME, PRICE) values ('P001', 'Java Core', 100); insert into product (CODE, NAME, PRICE) values ('P002', 'C# Core', 90);
SQL SERVER:
-- Create table create table USER_ACCOUNT ( USER_NAME VARCHAR(30) not null, GENDER VARCHAR(1) not null, PASSWORD VARCHAR(30) not null, primary key (USER_NAME) ); -- Create table create table PRODUCT ( CODE VARCHAR(20) not null, NAME VARCHAR(128) not null, PRICE FLOAT not null, primary key (CODE) ) ; -- Insert data: --------------------------------------------------------------- insert into user_account (USER_NAME, GENDER, PASSWORD) values ('tom', 'M', 'tom001'); insert into user_account (USER_NAME, GENDER, PASSWORD) values ('jerry', 'M', 'jerry001'); insert into product (CODE, NAME, PRICE) values ('P001', 'Java Core', 100); insert into product (CODE, NAME, PRICE) values ('P002', 'C# Core', 90);
5- Create WebApp Project
In Eclipse select:
- File/New/Other...
Project was created.
Add index.html
index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Simple Web Application</title> </head> <body> <h2>Simple Login Web Application using JSP/Servlet</h2> <ul> <li><a href="home">Home</a></li> <li><a href="login">Login</a></li> <li><a href="productList">Product List</a> </ul> </body> </html>
6- Configuring the runtime environment
The application needs to run on a WebServer, such asTomcat Server, you can refer to download and declaration instructions ofServer Tomcat inEclipse at:
Right-click the SimpleWebApp select Properties.
7- Run application for first time
Right-click on SimpleWebApp, select:
- Run As/Run on Server
Application has been run:
OK, here everything is fine. We'll start programming a real Web application.
8- Download and declare JDBC library
You have to download JDBC library to driving the connection with the Database. In this document, I download both of 3 JDBC libraries for Oracle, MySQL, SQL Server, in practice, you only need JDBC library corresponding to the type of database you are using.
You can see download instruction of JDBC driver at:
Or download here:
- some-jdbc-drivers.zip (MySQL + SQL Server + Oracle) o7planning link.
Results downloaded:
Copy these libraries into the WEB-INF/lib:
9- Download and declare JSTL library
You need to download 2 JSTL libraries to be able to use them in the JSP:
- javax.servlet.jsp.jstl-*.jar
- javax.servlet.jsp.jslt-api-*.jar
Copy 2 jar files that you just downloaded into the /WEB-INF/lib:
10- Javabean classes simulated tables in the database
Create 2 JavaBean classes, wherein each class simulated a table in the database:
UserAccount.java
package org.o7planning.simplewebapp.beans; public class UserAccount { public static final String GENDER_MALE ="M"; public static final String GENDER_FEMALE = "F"; private String userName; private String gender; private String password; public UserAccount() { } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
Product.java
package org.o7planning.simplewebapp.beans; public class Product { private String code; private String name; private float price; public Product() { } public Product(String code, String name, float price) { this.code = code; this.name = name; this.price = price; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
11- Database Connection Utility classes
MySQLConnUtils.java
package org.o7planning.simplewebapp.conn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class MySQLConnUtils { public static Connection getMySQLConnection() throws ClassNotFoundException, SQLException { // Note: Change the connection parameters accordingly. String hostName = "localhost"; String dbName = "mytest"; String userName = "root"; String password = "12345"; return getMySQLConnection(hostName, dbName, userName, password); } public static Connection getMySQLConnection(String hostName, String dbName, String userName, String password) throws SQLException, ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); // URL Connection for MySQL: // Example: // jdbc:mysql://localhost:3306/simplehr String connectionURL = "jdbc:mysql://" + hostName + ":3306/" + dbName; Connection conn = DriverManager.getConnection(connectionURL, userName, password); return conn; } }
OracleConnUtils.java
package org.o7planning.simplewebapp.conn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class OracleConnUtils { public static Connection getOracleConnection() throws ClassNotFoundException, SQLException { // Note: Change the connection parameters accordingly. String hostName = "localhost"; String sid = "db12c"; String userName = "mytest"; String password = "12345"; return getOracleConnection(hostName, sid, userName, password); } public static Connection getOracleConnection(String hostName, String sid, String userName, String password) throws ClassNotFoundException, SQLException { Class.forName("oracle.jdbc.driver.OracleDriver"); // URL Connection for Oracle // Example: // jdbc:oracle:thin:@localhost:1521:db11g // jdbc:oracle:thin:@//HOSTNAME:PORT/SERVICENAME String connectionURL = "jdbc:oracle:thin:@" + hostName + ":1521:" + sid; Connection conn = DriverManager.getConnection(connectionURL, userName, password); return conn; } }
SQLServerConnUtils_JTDS.java
package org.o7planning.simplewebapp.conn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SQLServerConnUtils_JTDS { // Connect to SQLServer // (Using JDBC Driver of JTDS library) public static Connection getSQLServerConnection_JTDS() // throws SQLException, ClassNotFoundException { // Note: Change the connection parameters accordingly. String hostName = "localhost"; String sqlInstanceName = "SQLEXPRESS"; String database = "mytest"; String userName = "sa"; String password = "12345"; return getSQLServerConnection_JTDS(hostName, sqlInstanceName, database, userName, password); } // Connect to SQLServer, using JTDS library private static Connection getSQLServerConnection_JTDS(String hostName, // String sqlInstanceName, String database, String userName, String password) throws ClassNotFoundException, SQLException { Class.forName("net.sourceforge.jtds.jdbc.Driver"); // Example: // jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS String connectionURL = "jdbc:jtds:sqlserver://" + hostName + ":1433/" // + database + ";instance=" + sqlInstanceName; Connection conn = DriverManager.getConnection(connectionURL, userName, password); return conn; } }
SQLServerConnUtils_SQLJDBC.java
package org.o7planning.simplewebapp.conn; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SQLServerConnUtils_SQLJDBC { // Connect to SQL Server. // (Using JDBC Driver: SQLJDBC) public static Connection getSQLServerConnection_SQLJDBC() // throws ClassNotFoundException, SQLException { // Note: Change the connection parameters accordingly. String hostName = "localhost"; String sqlInstanceName = "SQLEXPRESS"; String database = "mytest"; String userName = "sa"; String password = "12345"; return getSQLServerConnection_SQLJDBC(hostName, sqlInstanceName, database, userName, password); } // Connect to SQLServer, using SQLJDBC Library. private static Connection getSQLServerConnection_SQLJDBC(String hostName, // String sqlInstanceName, String database, String userName, String password)// throws ClassNotFoundException, SQLException { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // Example: // jdbc:sqlserver://ServerIp:1433/SQLEXPRESS;databaseName=simplehr String connectionURL = "jdbc:sqlserver://" + hostName + ":1433" // + ";instance=" + sqlInstanceName + ";databaseName=" + database; Connection conn = DriverManager.getConnection(connectionURL, userName, password); return conn; } }
ConnectionUtils.java
package org.o7planning.simplewebapp.conn; import java.sql.Connection; import java.sql.SQLException; public class ConnectionUtils { public static Connection getConnection() throws ClassNotFoundException, SQLException { // Here I using Oracle Database. // (You can change to use another database.) return OracleConnUtils.getOracleConnection(); // return OracleConnUtils.getOracleConnection(); // return MySQLConnUtils.getMySQLConnection(); // return SQLServerConnUtils_JTDS.getSQLServerConnection_JTDS(); // return SQLServerConnUtils_SQLJDBC.getSQLServerConnection_SQLJDBC(); // return PostGresConnUtils.getPostGresConnection(); } public static void closeQuietly(Connection conn) { try { conn.close(); } catch (Exception e) { } } public static void rollbackQuietly(Connection conn) { try { conn.rollback(); } catch (Exception e) { } } }
12- The utility class & manipulate data
MyUtils.java
package org.o7planning.simplewebapp.utils; import java.sql.Connection; import javax.servlet.ServletRequest; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.o7planning.simplewebapp.beans.UserAccount; public class MyUtils { public static final String ATT_NAME_CONNECTION = "ATTRIBUTE_FOR_CONNECTION"; private static final String ATT_NAME_USER_NAME = "ATTRIBUTE_FOR_STORE_USER_NAME_IN_COOKIE"; // Store Connection in request attribute. // (Information stored only exist during requests) public static void storeConnection(ServletRequest request, Connection conn) { request.setAttribute(ATT_NAME_CONNECTION, conn); } // Get the Connection object has been stored in attribute of the request. public static Connection getStoredConnection(ServletRequest request) { Connection conn = (Connection) request.getAttribute(ATT_NAME_CONNECTION); return conn; } // Store user info in Session. public static void storeLoginedUser(HttpSession session, UserAccount loginedUser) { // On the JSP can access via ${loginedUser} session.setAttribute("loginedUser", loginedUser); } // Get the user information stored in the session. public static UserAccount getLoginedUser(HttpSession session) { UserAccount loginedUser = (UserAccount) session.getAttribute("loginedUser"); return loginedUser; } // Store info in Cookie public static void storeUserCookie(HttpServletResponse response, UserAccount user) { System.out.println("Store user cookie"); Cookie cookieUserName = new Cookie(ATT_NAME_USER_NAME, user.getUserName()); // 1 day (Converted to seconds) cookieUserName.setMaxAge(24 * 60 * 60); response.addCookie(cookieUserName); } public static String getUserNameInCookie(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (ATT_NAME_USER_NAME.equals(cookie.getName())) { return cookie.getValue(); } } } return null; } // Delete cookie. public static void deleteUserCookie(HttpServletResponse response) { Cookie cookieUserName = new Cookie(ATT_NAME_USER_NAME, null); // 0 seconds (This cookie will expire immediately) cookieUserName.setMaxAge(0); response.addCookie(cookieUserName); } }
DBUtils.java
package org.o7planning.simplewebapp.utils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.o7planning.simplewebapp.beans.Product; import org.o7planning.simplewebapp.beans.UserAccount; public class DBUtils { public static UserAccount findUser(Connection conn, // String userName, String password) throws SQLException { String sql = "Select a.User_Name, a.Password, a.Gender from User_Account a " // + " where a.User_Name = ? and a.password= ?"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, userName); pstm.setString(2, password); ResultSet rs = pstm.executeQuery(); if (rs.next()) { String gender = rs.getString("Gender"); UserAccount user = new UserAccount(); user.setUserName(userName); user.setPassword(password); user.setGender(gender); return user; } return null; } public static UserAccount findUser(Connection conn, String userName) throws SQLException { String sql = "Select a.User_Name, a.Password, a.Gender from User_Account a "// + " where a.User_Name = ? "; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, userName); ResultSet rs = pstm.executeQuery(); if (rs.next()) { String password = rs.getString("Password"); String gender = rs.getString("Gender"); UserAccount user = new UserAccount(); user.setUserName(userName); user.setPassword(password); user.setGender(gender); return user; } return null; } public static List<Product> queryProduct(Connection conn) throws SQLException { String sql = "Select a.Code, a.Name, a.Price from Product a "; PreparedStatement pstm = conn.prepareStatement(sql); ResultSet rs = pstm.executeQuery(); List<Product> list = new ArrayList<Product>(); while (rs.next()) { String code = rs.getString("Code"); String name = rs.getString("Name"); float price = rs.getFloat("Price"); Product product = new Product(); product.setCode(code); product.setName(name); product.setPrice(price); list.add(product); } return list; } public static Product findProduct(Connection conn, String code) throws SQLException { String sql = "Select a.Code, a.Name, a.Price from Product a where a.Code=?"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, code); ResultSet rs = pstm.executeQuery(); while (rs.next()) { String name = rs.getString("Name"); float price = rs.getFloat("Price"); Product product = new Product(code, name, price); return product; } return null; } public static void updateProduct(Connection conn, Product product) throws SQLException { String sql = "Update Product set Name =?, Price=? where Code=? "; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, product.getName()); pstm.setFloat(2, product.getPrice()); pstm.setString(3, product.getCode()); pstm.executeUpdate(); } public static void insertProduct(Connection conn, Product product) throws SQLException { String sql = "Insert into Product(Code, Name,Price) values (?,?,?)"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, product.getCode()); pstm.setString(2, product.getName()); pstm.setFloat(3, product.getPrice()); pstm.executeUpdate(); } public static void deleteProduct(Connection conn, String code) throws SQLException { String sql = "Delete From Product where Code= ?"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, code); pstm.executeUpdate(); } }
13- Create Servlet Filter connect to Database
In JDBCFilter, I checked which requests actually referred to a Servlet, so that you can see the picture below to find it easy to understand, it describes the relationship between the concepts of Servlet.
JDBCFilter with url-pattern = /* means that all requests of users have go through this filter.
JDBCFilter will check the request to ensure that it only opens JDBC connection for the necessary request, eg for Servlet, avoid opening JDBC connection to common requests like image, css, js, html
JDBCFilter.java
package org.o7planning.simplewebapp.filter; import java.io.IOException; import java.sql.Connection; import java.util.Collection; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import org.o7planning.simplewebapp.conn.ConnectionUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebFilter(filterName = "jdbcFilter", urlPatterns = { "/*" }) public class JDBCFilter implements Filter { public JDBCFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { } @Override public void destroy() { } // Check the target of the request is a servlet? private boolean needJDBC(HttpServletRequest request) { System.out.println("JDBC Filter"); // // Servlet Url-pattern: /spath/* // // => /spath String servletPath = request.getServletPath(); // => /abc/mnp String pathInfo = request.getPathInfo(); String urlPattern = servletPath; if (pathInfo != null) { // => /spath/* urlPattern = servletPath + "/*"; } // Key: servletName. // Value: ServletRegistration Map<String, ? extends ServletRegistration> servletRegistrations = request.getServletContext() .getServletRegistrations(); // Collection of all servlet in your Webapp. Collection<? extends ServletRegistration> values = servletRegistrations.values(); for (ServletRegistration sr : values) { Collection<String> mappings = sr.getMappings(); if (mappings.contains(urlPattern)) { return true; } } return false; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; // Only open connections for the special requests. // (For example, the path to the servlet, JSP, ..) // // Avoid open connection for commons request. // (For example: image, css, javascript,... ) // if (this.needJDBC(req)) { System.out.println("Open Connection for: " + req.getServletPath()); Connection conn = null; try { // Create a Connection. conn = ConnectionUtils.getConnection(); // Set outo commit to false. conn.setAutoCommit(false); // Store Connection object in attribute of request. MyUtils.storeConnection(request, conn); // Allow request to go forward // (Go to the next filter or target) chain.doFilter(request, response); // Invoke the commit() method to complete the transaction with the DB. conn.commit(); } catch (Exception e) { e.printStackTrace(); ConnectionUtils.rollbackQuietly(conn); throw new ServletException(); } finally { ConnectionUtils.closeQuietly(conn); } } // With commons requests (images, css, html, ..) // No need to open the connection. else { // Allow request to go forward // (Go to the next filter or target) chain.doFilter(request, response); } } }
14- Servlet Filter reads Cookies to automatically login
In case, the user logined and remembered information in previous access (for example the day before). And now the user return, this Filter will check the Cookie information stored by the browser and automatic Login.
CookieFilter.java
package org.o7planning.simplewebapp.filter; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.o7planning.simplewebapp.beans.UserAccount; import org.o7planning.simplewebapp.utils.DBUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebFilter(filterName = "cookieFilter", urlPatterns = { "/*" }) public class CookieFilter implements Filter { public CookieFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpSession session = req.getSession(); UserAccount userInSession = MyUtils.getLoginedUser(session); // if (userInSession != null) { session.setAttribute("COOKIE_CHECKED", "CHECKED"); chain.doFilter(request, response); return; } // Connection was created in JDBCFilter. Connection conn = MyUtils.getStoredConnection(request); // Flag check cookie String checked = (String) session.getAttribute("COOKIE_CHECKED"); if (checked == null && conn != null) { String userName = MyUtils.getUserNameInCookie(req); try { UserAccount user = DBUtils.findUser(conn, userName); MyUtils.storeLoginedUser(session, user); } catch (SQLException e) { e.printStackTrace(); } // Mark checked Cookies. session.setAttribute("COOKIE_CHECKED", "CHECKED"); } chain.doFilter(request, response); } }
NOTE:
JDBCFilter & CookieFilterhave the sameurl-pattern =/*,you must be configured to ensure that JDBCFilterisexecuted first. Therefore, you need to declare the order in web.xml (There is no way to declare the order by Annotation).
<filter-mapping> <filter-name>jdbcFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>cookieFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
See full web.xml :
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SimpleWebApp</display-name> <filter-mapping> <filter-name>jdbcFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>cookieFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>home</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
15- EncodingFilter Servlet
EncodingFilter.java
package org.o7planning.simplewebapp.filter; import java.io.IOException; import java.sql.Connection; import java.util.Collection; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import org.o7planning.simplewebapp.conn.ConnectionUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebFilter(filterName = "encodingFilter", urlPatterns = { "/*" }) public class EncodingFilter implements Filter { public EncodingFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } }
16- Pages reuse
Some JSP pages will be used to embed into other JSP page at Runtime, through the use of:
<jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <jsp:include page="_footer.jsp"></jsp:include>
/WEB-INF/views/_header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div style="background: #E0E0E0; height: 55px; padding: 5px;"> <div style="float: left"> <h1>My Site</h1> </div> <div style="float: right; padding: 10px; text-align: right;"> <!-- User store in session with attribute: loginedUser --> Hello <b>${loginedUser.userName}</b> <br/> Search <input name="search"> </div> </div>
/WEB-INF/views/_menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div style="padding: 5px;"> <a href="${pageContext.request.contextPath}/">Home</a> | <a href="${pageContext.request.contextPath}/productList">Product List</a> | <a href="${pageContext.request.contextPath}/userInfo">My Account Info</a> | <a href="${pageContext.request.contextPath}/login">Login</a> </div>
/WEB-INF/views/_footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div style="background: #E0E0E0; text-align: center; padding: 5px; margin-top: 10px;"> @Copyright o7planning.org </div>
17- Home Page
When entering the default path, eg enter the site's domain name it will display the home page (Case contextPath = "") , you need to declare your home page in <welcome-file-list> of web.xml
Link below is showing the content of the page index.html
You need to design a home page as a JSP page to display dynamic information instead of a html page that contains static information.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SimpleWebApp</display-name> <filter-mapping> <filter-name>jdbcFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>cookieFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>home</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
HomeServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns = { "/home"}) public class HomeServlet extends HttpServlet { private static final long serialVersionUID = 1L; public HomeServlet() { super(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Forward to /WEB-INF/views/homeView.jsp // (Users can not access directly into JSP pages placed in WEB-INF) RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/views/homeView.jsp"); dispatcher.forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
/WEB-INF/views/homeView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Home Page</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Home Page</h3> This is demo Simple web application using jsp,servlet & Jdbc. <br><br> <b>It includes the following functions:</b> <ul> <li>Login</li> <li>Storing user information in cookies</li> <li>Product List</li> <li>Create Product</li> <li>Edit Product</li> <li>Delete Product</li> </ul> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
Rerun your application, and try two URLs:
NOTE: For whatever reason, the link http: //localhost:8080/SimpleWebApp/ is still displayed content of index.html, you can delete or rename theindex.htmlfile, for example, you can change it into _index.html
18- Login Page - LoginServlet
This is a model of Login function:
LoginServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.RequestDispatcher; 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 javax.servlet.http.HttpSession; import org.o7planning.simplewebapp.beans.UserAccount; import org.o7planning.simplewebapp.utils.DBUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebServlet(urlPatterns = { "/login" }) public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; public LoginServlet() { super(); } // Show Login page. @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Forward to /WEB-INF/views/loginView.jsp // (Users can not access directly into JSP pages placed in WEB-INF) RequestDispatcher dispatcher // = this.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp"); dispatcher.forward(request, response); } // When the user enters userName & password, and click Submit. // This method will be executed. @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName = request.getParameter("userName"); String password = request.getParameter("password"); String rememberMeStr = request.getParameter("rememberMe"); boolean remember = "Y".equals(rememberMeStr); UserAccount user = null; boolean hasError = false; String errorString = null; if (userName == null || password == null || userName.length() == 0 || password.length() == 0) { hasError = true; errorString = "Required username and password!"; } else { Connection conn = MyUtils.getStoredConnection(request); try { // Find the user in the DB. user = DBUtils.findUser(conn, userName, password); if (user == null) { hasError = true; errorString = "User Name or password invalid"; } } catch (SQLException e) { e.printStackTrace(); hasError = true; errorString = e.getMessage(); } } // If error, forward to /WEB-INF/views/login.jsp if (hasError) { user = new UserAccount(); user.setUserName(userName); user.setPassword(password); // Store information in request attribute, before forward. request.setAttribute("errorString", errorString); request.setAttribute("user", user); // Forward to /WEB-INF/views/login.jsp RequestDispatcher dispatcher // = this.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp"); dispatcher.forward(request, response); } // If no error // Store user information in Session // And redirect to userInfo page. else { HttpSession session = request.getSession(); MyUtils.storeLoginedUser(session, user); // If user checked "Remember me". if (remember) { MyUtils.storeUserCookie(response, user); } // Else delete cookie. else { MyUtils.deleteUserCookie(response); } // Redirect to userInfo page. response.sendRedirect(request.getContextPath() + "/userInfo"); } } }
UserInfoServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; 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 javax.servlet.http.HttpSession; import org.o7planning.simplewebapp.beans.UserAccount; import org.o7planning.simplewebapp.utils.MyUtils; @WebServlet(urlPatterns = { "/userInfo" }) public class UserInfoServlet extends HttpServlet { private static final long serialVersionUID = 1L; public UserInfoServlet() { super(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); // Check User has logged on UserAccount loginedUser = MyUtils.getLoginedUser(session); // Not logged in if (loginedUser == null) { // Redirect to login page. response.sendRedirect(request.getContextPath() + "/login"); return; } // Store info to the request attribute before forwarding. request.setAttribute("user", loginedUser); // If the user has logged in, then forward to the page // /WEB-INF/views/userInfoView.jsp RequestDispatcher dispatcher // = this.getServletContext().getRequestDispatcher("/WEB-INF/views/userInfoView.jsp"); dispatcher.forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
/WEB-INF/views/loginView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Login Page</h3> <p style="color: red;">${errorString}</p> <form method="POST" action="${pageContext.request.contextPath}/login"> <table border="0"> <tr> <td>User Name</td> <td><input type="text" name="userName" value= "${user.userName}" /> </td> </tr> <tr> <td>Password</td> <td><input type="text" name="password" value= "${user.password}" /> </td> </tr> <tr> <td>Remember me</td> <td><input type="checkbox" name="rememberMe" value= "Y" /> </td> </tr> <tr> <td colspan ="2"> <input type="submit" value= "Submit" /> <a href="${pageContext.request.contextPath}/">Cancel</a> </td> </tr> </table> </form> <p style="color:blue;">User Name: tom, password: tom001 or jerry/jerry001</p> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
/WEB-INF/views/userInfoView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>User Info</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Hello: ${user.userName}</h3> User Name: <b>${user.userName}</b> <br /> Gender: ${user.gender } <br /> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
Running your application:
19- Product List Page
Model:
ProductListServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import javax.servlet.RequestDispatcher; 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 org.o7planning.simplewebapp.beans.Product; import org.o7planning.simplewebapp.utils.DBUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebServlet(urlPatterns = { "/productList" }) public class ProductListServlet extends HttpServlet { private static final long serialVersionUID = 1L; public ProductListServlet() { super(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = MyUtils.getStoredConnection(request); String errorString = null; List<Product> list = null; try { list = DBUtils.queryProduct(conn); } catch (SQLException e) { e.printStackTrace(); errorString = e.getMessage(); } // Store info in request attribute, before forward to views request.setAttribute("errorString", errorString); request.setAttribute("productList", list); // Forward to /WEB-INF/views/productListView.jsp RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/productListView.jsp"); dispatcher.forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
/WEB-INF/views/productListView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Product List</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Product List</h3> <p style="color: red;">${errorString}</p> <table border="1" cellpadding="5" cellspacing="1" > <tr> <th>Code</th> <th>Name</th> <th>Price</th> <th>Edit</th> <th>Delete</th> </tr> <c:forEach items="${productList}" var="product" > <tr> <td>${product.code}</td> <td>${product.name}</td> <td>${product.price}</td> <td> <a href="editProduct?code=${product.code}">Edit</a> </td> <td> <a href="deleteProduct?code=${product.code}">Delete</a> </td> </tr> </c:forEach> </table> <a href="createProduct" >Create Product</a> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
Rerun Application:
20- Add Product Page
Model:
CreateProductServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.RequestDispatcher; 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 org.o7planning.simplewebapp.beans.Product; import org.o7planning.simplewebapp.utils.DBUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebServlet(urlPatterns = { "/createProduct" }) public class CreateProductServlet extends HttpServlet { private static final long serialVersionUID = 1L; public CreateProductServlet() { super(); } // Show product creation page. @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/createProductView.jsp"); dispatcher.forward(request, response); } // When the user enters the product information, and click Submit. // This method will be called. @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = MyUtils.getStoredConnection(request); String code = (String) request.getParameter("code"); String name = (String) request.getParameter("name"); String priceStr = (String) request.getParameter("price"); float price = 0; try { price = Float.parseFloat(priceStr); } catch (Exception e) { } Product product = new Product(code, name, price); String errorString = null; // Product ID is the string literal [a-zA-Z_0-9] // with at least 1 character String regex = "\\w+"; if (code == null || !code.matches(regex)) { errorString = "Product Code invalid!"; } if (errorString == null) { try { DBUtils.insertProduct(conn, product); } catch (SQLException e) { e.printStackTrace(); errorString = e.getMessage(); } } // Store infomation to request attribute, before forward to views. request.setAttribute("errorString", errorString); request.setAttribute("product", product); // If error, forward to Edit page. if (errorString != null) { RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/createProductView.jsp"); dispatcher.forward(request, response); } // If everything nice. // Redirect to the product listing page. else { response.sendRedirect(request.getContextPath() + "/productList"); } } }
/WEB-INF/views/createProductView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Create Product</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Create Product</h3> <p style="color: red;">${errorString}</p> <form method="POST" action="${pageContext.request.contextPath}/createProduct"> <table border="0"> <tr> <td>Code</td> <td><input type="text" name="code" value="${product.code}" /></td> </tr> <tr> <td>Name</td> <td><input type="text" name="name" value="${product.name}" /></td> </tr> <tr> <td>Price</td> <td><input type="text" name="price" value="${product.price}" /></td> </tr> <tr> <td colspan="2"> <input type="submit" value="Submit" /> <a href="productList">Cancel</a> </td> </tr> </table> </form> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
21- Edit Product Page
Model:
EditProductServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.RequestDispatcher; 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 org.o7planning.simplewebapp.beans.Product; import org.o7planning.simplewebapp.utils.DBUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebServlet(urlPatterns = { "/editProduct" }) public class EditProductServlet extends HttpServlet { private static final long serialVersionUID = 1L; public EditProductServlet() { super(); } // Show product edit page. @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = MyUtils.getStoredConnection(request); String code = (String) request.getParameter("code"); Product product = null; String errorString = null; try { product = DBUtils.findProduct(conn, code); } catch (SQLException e) { e.printStackTrace(); errorString = e.getMessage(); } // If no error. // The product does not exist to edit. // Redirect to productList page. if (errorString != null && product == null) { response.sendRedirect(request.getServletPath() + "/productList"); return; } // Store errorString in request attribute, before forward to views. request.setAttribute("errorString", errorString); request.setAttribute("product", product); RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/editProductView.jsp"); dispatcher.forward(request, response); } // After the user modifies the product information, and click Submit. // This method will be executed. @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = MyUtils.getStoredConnection(request); String code = (String) request.getParameter("code"); String name = (String) request.getParameter("name"); String priceStr = (String) request.getParameter("price"); float price = 0; try { price = Float.parseFloat(priceStr); } catch (Exception e) { } Product product = new Product(code, name, price); String errorString = null; try { DBUtils.updateProduct(conn, product); } catch (SQLException e) { e.printStackTrace(); errorString = e.getMessage(); } // Store infomation to request attribute, before forward to views. request.setAttribute("errorString", errorString); request.setAttribute("product", product); // If error, forward to Edit page. if (errorString != null) { RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/editProductView.jsp"); dispatcher.forward(request, response); } // If everything nice. // Redirect to the product listing page. else { response.sendRedirect(request.getContextPath() + "/productList"); } } }
/WEB-INF/views/editProductView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Edit Product</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Edit Product</h3> <p style="color: red;">${errorString}</p> <c:if test="${not empty product}"> <form method="POST" action="${pageContext.request.contextPath}/editProduct"> <input type="hidden" name="code" value="${product.code}" /> <table border="0"> <tr> <td>Code</td> <td style="color:red;">${product.code}</td> </tr> <tr> <td>Name</td> <td><input type="text" name="name" value="${product.name}" /></td> </tr> <tr> <td>Price</td> <td><input type="text" name="price" value="${product.price}" /></td> </tr> <tr> <td colspan = "2"> <input type="submit" value="Submit" /> <a href="${pageContext.request.contextPath}/productList">Cancel</a> </td> </tr> </table> </form> </c:if> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
22- Delete Product
Model:
DeleteProductServlet.java
package org.o7planning.simplewebapp.servlet; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.RequestDispatcher; 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 org.o7planning.simplewebapp.utils.DBUtils; import org.o7planning.simplewebapp.utils.MyUtils; @WebServlet(urlPatterns = { "/deleteProduct" }) public class DeleteProductServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DeleteProductServlet() { super(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = MyUtils.getStoredConnection(request); String code = (String) request.getParameter("code"); String errorString = null; try { DBUtils.deleteProduct(conn, code); } catch (SQLException e) { e.printStackTrace(); errorString = e.getMessage(); } // If has an error, redirecte to the error page. if (errorString != null) { // Store the information in the request attribute, before forward to views. request.setAttribute("errorString", errorString); // RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/deleteProductErrorView.jsp"); dispatcher.forward(request, response); } // If everything nice. // Redirect to the product listing page. else { response.sendRedirect(request.getContextPath() + "/productList"); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
/WEB-INF/views/deleteProductErrorView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Delete Product</title> </head> <body> <jsp:include page="_header.jsp"></jsp:include> <jsp:include page="_menu.jsp"></jsp:include> <h3>Delete Product</h3> <p style="color: red;">${errorString}</p> <a href="productList">Product List</a> <jsp:include page="_footer.jsp"></jsp:include> </body> </html>
Maybe you are interested
These are online courses outside the o7planning website that we introduced, which may include free or discounted courses.
Source: https://o7planning.org/10285/create-a-simple-java-web-application-using-servlet-jsp-and-jdbc
0 Response to "Java Web Servlet Annotation Example"
Post a Comment