Java EE Web Application (JSP/Servlet, EJB, JPA, SQL Server, Glassfish) Full Tutorial

Hướng dẫn đầy đủ về Ứng dụng Web Java EE (JSP / Servlet, EJB, JPA, SQL Server, Glassfish)


Vũ khí cần chuẩn bị để thực hiện ở bài viết này:

NetBeans IDE 8.2
Glassfish 4.1.2
SQL Server 2021 Management Studito
mssql-jdbc-9.2.1.jre8.jar

Nội dung chủ yếu:

- Tạo database với SQL Server 2021 Management Studito
- Tạo JDBC Connection Pool và JDBC Resource riêng để tái sử dụng với Glassfish Server
- Tạo project EJB CRUD

Tạo database với SQL Server 2021 Management Studito:

Tạo database tên Shopee và copy đoạn script bên dưới chạy:
USE [Shopee]
GO
/****** Object:  Table [dbo].[category]    Script Date: 6/1/2021 11:13:07 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[category](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [varchar](50) NULL,
 CONSTRAINT [PK_category] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[product]    Script Date: 6/1/2021 11:13:07 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[product](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [varchar](50) NULL,
	[price] [float] NULL,
	[cat_id] [int] NULL,
 CONSTRAINT [PK_product] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[category] ON 
INSERT [dbo].[category] ([id], [name]) VALUES (1, N'phone')
INSERT [dbo].[category] ([id], [name]) VALUES (2, N'laptop')
SET IDENTITY_INSERT [dbo].[category] OFF
SET IDENTITY_INSERT [dbo].[product] ON 
INSERT [dbo].[product] ([id], [name], [price], [cat_id]) VALUES (1, N'iphone sx 2021', 20000, 1)
INSERT [dbo].[product] ([id], [name], [price], [cat_id]) VALUES (2, N'lenovo w540', 50000, 2)
INSERT [dbo].[product] ([id], [name], [price], [cat_id]) VALUES (3, N'samsung galaxy', 25000, 1)
SET IDENTITY_INSERT [dbo].[product] OFF
ALTER TABLE [dbo].[product]  WITH CHECK ADD  CONSTRAINT [FK_product_category] FOREIGN KEY([cat_id])
REFERENCES [dbo].[category] ([id])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[product] CHECK CONSTRAINT [FK_product_category]
GO

Tạo JDBC Connection Pool và JDBC Resource với Glassfish Server:

Copy mssql-jdbc-9.2.1.jre8.jar bỏ vào glassfish4\glassfish\lib


Chạy server lên vào glassfish4\bin click chạy asadmin.bat 


Sau khi chạy file asadmin.bat gõ lệnh như dưới ảnh để chạy domain1 mặc định và enter

Kết quả như ảnh dưới sau khi chạy lệnh

Tiếp theo mở trình duyệt gõ http://localhost:4848/

Chọn JDBC/JDBC Connection Pools và click vào new theo ảnh dưới

Giao diện sau khi nhấn new và điền thông tin như ảnh dưới sau đó nhấn next

Tiếp đến, tập trung vào Additional Properties và thêm vào như ảnh dưới sau đó nhấn Finish để hoàn tất tạo JDBC Connection Pools
+ User: sa
+ Password: <mật khẩu sa>
+ URL: jdbc:sqlserver://localhost:1433;databaseName=Shopee

Sau khi hoàn thành click vào SQLPool check ping ra chữ Ping Succeeded như ảnh dưới là thành công


Tạo JDBC Resources, tìm  đến JDBC/JDBC Resources để ra click vào new như ảnh dưới

Giao diện sau khi chọn new và điền thông tin như ảnh dưới và click ok

JDBC Resource sau khi hoàn thành

Tạo project EJB CRUD:

New Project => Java EE => Enterprise Application => Next

Nhập tên project ProductDB, nơi lưu trữ và nhấn next

Có thể thay đổi server khác, sau đó nhấn finish

Cấu trúc source tạo ra được như ảnh

Tạo connection tới database ShopeeServices như hướng dẫn bên dưới





Quay trở về Project, tại hình hạt đậu tạo Entity Classes from Database như hướng dẫn dưới







Tiếp hình hạt đậu, tạo Session Beans For Entity Classes như hướng dẫn dưới




Chúng ta sẽ tập chung viết code xử lý với database ở các file CategoryFacade.java, ProductFacade.java
CategoryFacade.java
package com.fpt.bean;

import com.fpt.entity.Category;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class CategoryFacade extends AbstractFacade<Category> implements CategoryFacadeLocal {

    @PersistenceContext(unitName = "ProductDB-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public CategoryFacade() {
        super(Category.class);
    }
    
}

ProductFacade.java
package com.fpt.bean;

import com.fpt.entity.Product;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class ProductFacade extends AbstractFacade<Product> implements ProductFacadeLocal {

    @PersistenceContext(unitName = "ProductDB-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public ProductFacade() {
        super(Product.class);
    }
    
}

quả địa cầu thêm thư viện JSTL có sẵng ở NetBeans support vào

Tiếp tới, tạo các view file ,jsp như ảnh dưới bên trong quả địa cầu

Tại quả địa cầu tạo các Servlet để xử ý request, response (minh hoạ cho một Servlet tạo và Call Enterprise Bean)




Các code xử lý ở Servlet, JSP:

Hiển thị tất cả dữ liệu:

index.jsp
<jsp:forward page="ShowServlet" />

ShowServlet.java
package com.fpt.controller;

import com.fpt.bean.ProductFacadeLocal;
import com.fpt.entity.Product;
import java.io.IOException;
import java.util.List;
import javax.ejb.EJB;
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(name="ShowServlet", urlPatterns={"/ShowServlet"})
public class ShowServlet extends HttpServlet {

    @EJB
    private ProductFacadeLocal productFacade;
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        List<Product> products = productFacade.findAll();
        request.setAttribute("products", products);
        request.getRequestDispatcher("show.jsp").forward(request, response);
    } 

    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

Show.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Product Management</title>
    </head>
    <body>
        <h1>List Products</h1>
        <hr/>
        <a href="CreateServlet">Create new product</a>
        <table border="1">
            <tr>
                <td>ID</td>
                <td>Name</td>
                <td>Price</td>
                <td>Category</td>
                <td>Action</td>
            </tr>
            <c:forEach items="${products}" var="product">
                <tr>
                    <td>${product.id}</td>
                    <td>${product.name}</td>
                    <td>${product.price}</td>
                    <td>${product.catId.name}</td>
                    <td>
                        <a href="DelServlet?id=${product.id}">Del</a> | 
                        <a href="EditServlet?id=${product.id}">Edit</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>

Kết quả:

Xoá sản phẩm:

DelServlet.java
package com.fpt.controller;

import com.fpt.bean.ProductFacadeLocal;
import com.fpt.entity.Product;
import java.io.IOException;
import javax.ejb.EJB;
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(name="DelServlet", urlPatterns={"/DelServlet"})
public class DelServlet extends HttpServlet {

    @EJB
    private ProductFacadeLocal productFacade;
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        int id = Integer.valueOf(request.getParameter("id"));
        Product product = productFacade.find(id);
        productFacade.remove(product);
        
        response.sendRedirect("ShowServlet");
    } 

    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

Kết quả:


Thêm sản phẩm:

CreateServlet.java
package com.fpt.controller;

import com.fpt.bean.CategoryFacadeLocal;
import com.fpt.entity.Category;
import java.io.IOException;
import java.util.List;
import javax.ejb.EJB;
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(name="CreateServlet", urlPatterns={"/CreateServlet"})
public class CreateServlet extends HttpServlet {

    @EJB
    private CategoryFacadeLocal categoryFacade;
   
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        List<Category> categorys = categoryFacade.findAll();
        request.setAttribute("categorys", categorys);
        request.getRequestDispatcher("create.jsp").forward(request, response);
    } 

    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

create.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Product Management</title>
    </head>
    <body>
        <h1>Create New Product</h1>
        <hr/>
        <form action="InsertServlet" method="post">
            <table>
                <tr>
                    <th>Name</th>
                    <td><input type="text" name="name" /></td>
                </tr>
                <tr>
                    <th>Price</th>
                    <td><input type="text" name="price" /></td>
                </tr>
                <tr>
                    <th>Category</th>
                    <td>
                        <select name="catId">
                            <c:forEach items="${categorys}" var="category">
                                <option value="${category.id}">${category.name}</option>
                            </c:forEach>
                        </select>
                    </td>
                </tr>
            </table>
            <button type="submit">Save</button>
        </form>
    </body>
</html>

Giao diện:


InsertServlet.java
Giao diện nhập dữ liệu:

package com.fpt.controller;

import com.fpt.bean.CategoryFacadeLocal;
import com.fpt.bean.ProductFacadeLocal;
import com.fpt.entity.Category;
import com.fpt.entity.Product;
import java.io.IOException;
import javax.ejb.EJB;
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(name="InsertServlet", urlPatterns={"/InsertServlet"})
public class InsertServlet extends HttpServlet {

    @EJB
    private ProductFacadeLocal productFacade;

    @EJB
    private CategoryFacadeLocal categoryFacade;
   
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        String name = request.getParameter("name");
        double price = Double.valueOf(request.getParameter("price"));
        int catId = Integer.valueOf(request.getParameter("catId"));
        
        Category category = categoryFacade.find(catId);
        
        Product product = new Product();
        product.setCatId(category);
        product.setName(name);
        product.setPrice(price);
        
        productFacade.create(product);
        
        response.sendRedirect("ShowServlet");
    } 

    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

Kết quả:

Chỉnh sửa sản phẩm:

EditServlet.java
package com.fpt.controller;

import com.fpt.bean.CategoryFacadeLocal;
import com.fpt.bean.ProductFacadeLocal;
import com.fpt.entity.Category;
import com.fpt.entity.Product;
import java.io.IOException;
import java.util.List;
import javax.ejb.EJB;
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(name="EditServlet", urlPatterns={"/EditServlet"})
public class EditServlet extends HttpServlet {

    @EJB
    private ProductFacadeLocal productFacade;

    @EJB
    private CategoryFacadeLocal categoryFacade;
   
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        int id = Integer.valueOf(request.getParameter("id"));
        
        Product product = productFacade.find(id);
        List<Category> categorys = categoryFacade.findAll();
        
        request.setAttribute("product", product);
        request.setAttribute("categorys", categorys);
        request.getRequestDispatcher("edit.jsp").forward(request, response);
    } 

    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

edit.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Product Management</title>
    </head>
    <body>
        <h1>Edit Product</h1>
        <hr/>
        <form action="UpdateServlet" method="post">
            <input type="hidden" name="id" value="${product.id}" />
            <table>
                <tr>
                    <th>Name</th>
                    <td><input type="text" name="name" value="${product.name}" /></td>
                </tr>
                <tr>
                    <th>Price</th>
                    <td><input type="text" name="price" value="${product.price}" /></td>
                </tr>
                <tr>
                    <th>Category</th>
                    <td>
                        <select name="catId">
                            <c:forEach items="${categorys}" var="category">
                                <option value="${category.id}" ${category.id == product.catId.id ? 'selected' : '' } >${category.name}</option>
                            </c:forEach>
                        </select>
                    </td>
                </tr>
            </table>
            <button type="submit">Save</button>
        </form>
    </body>
</html>

Giao diện nhận được:

Giao diện chỉnh sửa:

UpdateServlet.java
package com.fpt.controller;

import com.fpt.bean.CategoryFacadeLocal;
import com.fpt.bean.ProductFacadeLocal;
import com.fpt.entity.Category;
import com.fpt.entity.Product;
import java.io.IOException;
import javax.ejb.EJB;
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(name="UpdateServlet", urlPatterns={"/UpdateServlet"})
public class UpdateServlet extends HttpServlet {
   
    @EJB
    private ProductFacadeLocal productFacade;

    @EJB
    private CategoryFacadeLocal categoryFacade;
    
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        int id = Integer.valueOf(request.getParameter("id"));
        String name = request.getParameter("name");
        double price = Double.valueOf(request.getParameter("price"));
        int catId = Integer.valueOf(request.getParameter("catId"));
        
        Category category = categoryFacade.find(catId);
        
        Product product = productFacade.find(id);
        product.setCatId(category);
        product.setName(name);
        product.setPrice(price);
        
        productFacade.edit(product);
        
        response.sendRedirect("ShowServlet");
        
    } 

    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

}

Kết quả:

Cấu trúc source Servlet, JSP:

Lưu ý: sau khi code xong hoặc fix code, chỉ cần Clean and Build, sau đó Run module kim tử tháp là chạy được

Nhận xét

Bài đăng phổ biến từ blog này

Build validation using VanillaJS for Form Submit

Java EE Web Application (JavaServer Faces, EJB, JPA, SQL Server, Glassfish) Full Tutorial