Hướng dẫn làm ứng dụng java
Tài liệu được viết dựa trên:
Trong tài liệu này tôi sẽ hướng dẫn từng bước cách tạo một ứng dụng web đơn giản kết hợp Servlet + JSP + Filter + JSP EL + JDBC. Hãy đảm bảo rằng bạn đã nắm vững Servlet, JSP và Filter và JDBC trước khi bắt đầu. Nếu không, bạn có thể tham khảo tại:
Đây là các nguyên tắc mà bạn nên nhớ để có thể xây dựng một ứng dụng Web sử dụng Servlet + JSP thỏa mãn tiêu chí: code đơn giản dễ hiểu và dễ dàng bảo trì.
Không bao giờ cho phép người dùng truy cập trực tiếp vào trang JSP của bạn, điều đó có nghĩa là mọi request của người dùng thường là:
Khi request của người dùng tới một Servlet, nó sẽ sử lý yêu cầu của người dùng, chẳng hạn Insert, update và truy vấn dữ liệu, cuối cùng là chuyển tiếp (forward) tới trang JSP để hiển thị dữ liệu. Như vậy mỗi servlet có 0 hoặc nhiều trang JSP tương ứng (Thường chỉ cần 1). Chỉ coi JSP là nơi hiển thị dữ liệu, điều đó có nghĩa là bạn không nên xử lý logic ứng dụng trên JSP, chẳng hạn như update, insert, delete,.., và không điều hướng trên trang JSP. Bạn có thể xem trước bản giới thiệu (Demo) ứng dụng Web sẽ làm:
Trong tài liệu này tôi hướng dẫn bạn làm việc với một trong 3 cơ sở dữ liệu Oracle, MySQL hoặc SQL Server. Bạn cần chạy các script để tạo một số bảng và dữ liệu cần thiết cho ví dụ này. -- 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; -- 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); -- 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);
Simple Login Web Application using JSP/ServletỨng dụng cần chạy trên một WebServer, chẳng hạn Tomcat Server, bạn có thể tham khảo tài liệu hướng dẫn download và khai báo Server Tomcat vào Eclipse tại: Nhấn phải chuột vào project SimpleWebApp chọn Properties.
Nhấn phải chuột vào Project SimpleWebApp, chọn:
OK, tới đây mọi thứ đều tốt đẹp. Chúng ta sẽ bắt đầu lập trình một ứng dụng Web thực sự. Bạn cần download thư viện JDBC điều khiển việc kết nối với Database. Trong tài liệu này tôi download cả 3 thư viện JDBC cho cả Oracle, MySQL, SQL Server, trong thực hành bạn chỉ cần thư viện JDBC ứng với loại Database bạn đang sử dụng. Bạn có thể xem hướng dẫn download JDBC driver tại:
Copy các thư viện này vào WEB-INF/lib:
Bạn cần download 2 thư viện JSTL để có thể sử dụng chúng trong JSP:
Copy 2 file jar bạn vừa download được vào thư mục /WEB-INF/lib:
Tạo một số class Javabean, mỗi class mô phỏng một bảng trong database:
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; } } 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; } }
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 { // Chú ý: Thay đổi các thông số kết nối cho phù hợp. 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"); // Cấu trúc URL Connection đối với MySQL: // Ví dụ: // jdbc:mysql://localhost:3306/simplehr String connectionURL = "jdbc:mysql://" + hostName + ":3306/" + dbName; Connection conn = DriverManager.getConnection(connectionURL, userName, password); return conn; } } 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 { // Chú ý: Thay đổi các thông số kết nối cho phù hợp. 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"); // Cấu trúc URL Connection đối với Oracle // Ví dụ: // 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 { // Kết nối vào SQLServer. // (Sử dụng thư viện điều khiển JTDS) public static Connection getSQLServerConnection_JTDS() // throws SQLException, ClassNotFoundException { // Chú ý: Thay đổi các thông số kết nối cho phù hợp. String hostName = "localhost"; String sqlInstanceName = "SQLEXPRESS"; String database = "mytest"; String userName = "sa"; String password = "12345"; return getSQLServerConnection_JTDS(hostName, sqlInstanceName, database, userName, password); } // Kết nối tới SQL Server sử dụng thư viện JTDS. 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"); // Cấu trúc URL Connection đối với SQL Server: // Ví dụ: // 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 { // Kết nối vào SQL Server. // (Sử dụng thư viện SQLJDBC) public static Connection getSQLServerConnection_SQLJDBC() // throws ClassNotFoundException, SQLException { // Chú ý: Thay đổi các thông số kết nối cho phù hợp. String hostName = "localhost"; String sqlInstanceName = "SQLEXPRESS"; String database = "mytest"; String userName = "sa"; String password = "12345"; return getSQLServerConnection_SQLJDBC(hostName, sqlInstanceName, database, userName, password); } // Kết nối tới SQLServer, sử dụng thư viện SQLJDBC. 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"); // Cấu trúc URL Connection dành cho SQLServer // Ví dụ: // 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; } }package org.o7planning.simplewebapp.conn; import java.sql.Connection; import java.sql.SQLException; public class ConnectionUtils { public static Connection getConnection() throws ClassNotFoundException, SQLException { // Ở đây tôi kết nối tới Oracle Database. // (Bạn có thể thay đổi sử dụng database khác). 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) { } } }
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"; // Lưu trữ Connection vào attribute của request. // Thông tin lưu trữ này chỉ tồn tại trong thời gian yêu cầu (request) // cho tới khi dữ liệu được trả về trình duyệt người dùng. public static void storeConnection(ServletRequest request, Connection conn) { request.setAttribute(ATT_NAME_CONNECTION, conn); } // Lấy đối tượng Connection đã được lưu trữ trong attribute của request. public static Connection getStoredConnection(ServletRequest request) { Connection conn = (Connection) request.getAttribute(ATT_NAME_CONNECTION); return conn; } // Lưu trữ thông tin người dùng đã login vào Session. public static void storeLoginedUser(HttpSession session, UserAccount loginedUser) { // Trên JSP có thể truy cập thông qua ${loginedUser} session.setAttribute("loginedUser", loginedUser); } // Lấy thông tin người dùng lưu trữ trong Session. public static UserAccount getLoginedUser(HttpSession session) { UserAccount loginedUser = (UserAccount) session.getAttribute("loginedUser"); return loginedUser; } // Lưu thông tin người dùng vào 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 ngày (Đã đổi ra giây) 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; } // Xóa Cookie của người dùng public static void deleteUserCookie(HttpServletResponse response) { Cookie cookieUserName = new Cookie(ATT_NAME_USER_NAME, null); // 0 giây. (Cookie này sẽ hết hiệu lực ngay lập tức) cookieUserName.setMaxAge(0); response.addCookie(cookieUserName); } }
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 Trong JDBCFilter tôi có kiểm tra xem các request nào thực sự gọi tới một Servlet, để dễ hiểu bạn có thể xem hình dưới đây, nó mô tả quan hệ giữa các khái niệm của Servlet.
JDBCFilter với khai báo url-pattern = /*, điều đó có nghĩa là mọi request của người dùng đều phải đi qua filter này. JDBCFilter sẽ kiểm tra request để đảm bảo chỉ mở kết nối JDBC cho các request cần thiết, chẳng hạn cho Servlet, tránh mở kết nối JDBC đối với các request thông thường như image, css, js, html.
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() {
}
// Kiểm tra mục tiêu của request hiện tại là 1 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 Trong trường hợp người dùng đã login và nhớ thông tin trong lần truy cập trước đó (Chẳng hạn hôm trước). Và giờ người dùng quay trở lại, Filter này sẽ kiểm tra thông tin Cookie đã lưu bởi trình duyệt và tự động Login. 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 đã được tạo trong JDBCFilter. Connection conn = MyUtils.getStoredConnection(request); // Cờ (flag) để kiểm tra 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(); } // Đánh dấu đã kiểm tra Cookie. session.setAttribute("COOKIE_CHECKED", "CHECKED"); } chain.doFilter(request, response); } }
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); } } Một số trang JSP sẽ được sử dụng để nhúng vào các trang khác tại thời điểm Runtime, thông qua việc sử dụng:
/WEB-INF/views/_header.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>My Site
Hello ${loginedUser.userName}
Search <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
/WEB-INF/views/_footer.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
@Copyright o7planning.org
Khi gõ đường dẫn mặc định, chẳng hạn gõ tên miền của trang web nó sẽ hiển thị ra trang chủ (Trường hợp contextPath = ""), bạn cần phải khai báo trang chủ trong Đường dẫn dưới đây hiện tại đang hiển thị nội dung của trang index.html Bạn cần thiết kế một trang chủ là một JSP để có được các thông tin động thay vì một trang html vốn chỉ chứa các thông tin tĩnh.
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 toi trang /WEB-INF/views/homeView.jsp // (Người dùng không bao giờ truy cập trực tiếp được vào các trang JSP // đặt trong 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"%>Home PageThis is demo Simple web application using jsp,servlet & Jdbc.It includes the following functions:
Chạy lại ứng dụng của bạn, và thử 2 đường dẫn:
Đây là mô hình chức năng Login:
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(); } // Hiển thị trang Login. @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Forward tới trang /WEB-INF/views/loginView.jsp // (Người dùng không thể truy cập trực tiếp // vào các trang JSP đặt trong thư mục WEB-INF). RequestDispatcher dispatcher // = this.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp"); dispatcher.forward(request, response); } // Khi người nhập userName & password, và nhấn Submit. // Phương thức này sẽ được thực thi. @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 { // Tìm user trong 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(); } } // Trong trường hợp có lỗi, // forward (chuyển hướng) tới /WEB-INF/views/login.jsp if (hasError) { user = new UserAccount(); user.setUserName(userName); user.setPassword(password); // Lưu các thông tin vào request attribute trước khi forward. request.setAttribute("errorString", errorString); request.setAttribute("user", user); // Forward (Chuyển tiếp) tới trang /WEB-INF/views/login.jsp RequestDispatcher dispatcher // = this.getServletContext().getRequestDispatcher("/WEB-INF/views/loginView.jsp"); dispatcher.forward(request, response); } // Trường hợp không có lỗi. // Lưu thông tin người dùng vào Session. // Và chuyển hướng sang trang userInfo. else { HttpSession session = request.getSession(); MyUtils.storeLoginedUser(session, user); // Nếu người dùng chọn tính năng "Remember me". if (remember) { MyUtils.storeUserCookie(response, user); } // Ngược lại xóa Cookie else { MyUtils.deleteUserCookie(response); } // Redirect (Chuyển hướng) sang trang /userInfo. response.sendRedirect(request.getContextPath() + "/userInfo"); } } } 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(); // Kiểm tra người dùng đã đăng nhập (login) chưa. UserAccount loginedUser = MyUtils.getLoginedUser(session); // Nếu chưa đăng nhập (login). if (loginedUser == null) { // Redirect (Chuyển hướng) tới trang login. response.sendRedirect(request.getContextPath() + "/login"); return; } // Lưu thông tin vào request attribute trước khi forward (chuyển tiếp). request.setAttribute("user", loginedUser); // Nếu người dùng đã login thì forward (chuyển tiếp) tới trang // /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"%>Login Page${errorString} User Name: tom, password: tom001 or jerry/jerry001
/WEB-INF/views/userInfoView.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Hello: ${user.userName}User Name: ${user.userName}Gender: ${user.gender }
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
/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" %>Product List${errorString}
Mô hình chức năng thêm sản phẩm:
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(); } // Hiển thị trang tạo sản phẩm. @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); } // Khi người dùng nhập các thông tin sản phẩm, và nhấn Submit. // Phương thức này sẽ được gọi. @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; // Mã sản phẩm phải là chuỗi chữ [a-zA-Z_0-9] // Có ít nhất một ký tự. 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(); } } // Lưu thông tin vào request attribute trước khi forward sang views. request.setAttribute("errorString", errorString); request.setAttribute("product", product); // Nếu có lỗi forward (chuyển tiếp) sang trang 'edit'. if (errorString != null) { RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/createProductView.jsp"); dispatcher.forward(request, response); } // Nếu mọi thứ tốt đẹp. // Redirect (chuyển hướng) sang trang danh sách sản phẩm. 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"%>Create Product${errorString}
Mô hình chức năng sửa thông tin sản phẩm:
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(); } // Hiển thị trang sửa sản phẩm. @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(); } // Không có lỗi. // Sản phẩm không tồn tại để edit. // Redirect sang trang danh sách sản phẩm. if (errorString != null && product == null) { response.sendRedirect(request.getServletPath() + "/productList"); return; } // Lưu thông tin vào request attribute trước khi forward sang views. request.setAttribute("errorString", errorString); request.setAttribute("product", product); RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/editProductView.jsp"); dispatcher.forward(request, response); } // Sau khi người dùng sửa đổi thông tin sản phẩm, và nhấn Submit. // Phương thức này sẽ được thực thi. @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(); } // Lưu thông tin vào request attribute trước khi forward sang views. request.setAttribute("errorString", errorString); request.setAttribute("product", product); // Nếu có lỗi forward sang trang edit. if (errorString != null) { RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/editProductView.jsp"); dispatcher.forward(request, response); } // Nếu mọi thứ tốt đẹp. // Redirect sang trang danh sách sản phẩm. 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"%>Edit Product${errorString}
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(); } // Nếu có lỗi, forward (chuyển tiếp) sang trang thông báo lỗi. if (errorString != null) { // Lưu thông tin vào request attribute trước khi forward sang views. request.setAttribute("errorString", errorString); // RequestDispatcher dispatcher = request.getServletContext() .getRequestDispatcher("/WEB-INF/views/deleteProductErrorView.jsp"); dispatcher.forward(request, response); } // Nếu mọi thứ tốt đẹp. // Redirect (chuyển hướng) sang trang danh sách sản phẩm. 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"%>Delete Product${errorString} Product List |