Java EE Web Application (JavaServer Faces, EJB, JPA, SQL Server, Glassfish) Full Tutorial
Ứng dụng Web Java EE (JavaServer Faces, EJB, JPA, SQL Server, Glassfish) Hướng dẫn đầy đủ
Xem phần khởi tạo connection pool với grassfish4 và tạo project EJB tại đây: Java EE Web Application (JSP/Servlet, EJB, JPA, SQL Server, Glassfish) Full Tutorialot.com/2021/06/java-ee-web-application-jsp-servlet-ejb-jpa-sql-server-glassfish.html
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 hoặc thay đổi tên database connection pool với grassfish4 tái sử dụng SQLPool ở bài trước:
Tạo project EJB:
Chọn File => New Project... => Java EE => Enterprise Application => Next
Tạo Entity Classes from Database:
Tại ProductManagement-ejb => chuột phải chọn New => Other... => Persistence => Entity Classes from Database => Next
Tạo Session Beans For Entity Classes...:
Tại ProductManagement-ejb => chuột phải vào New => Orther... => Enterprise JavaBeans => Session Beans For Entity Classes => Next
Thêm JSF Framework: chuột phải vào ProductManagement-war => Properties => Frameworks => Add => JavaServer Faces
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> </web-app>
Tạo JSF Managed Bean: chuột phải vào ProductManagement-war => New => Orther... => JavaServer Faces => Next
ProductManagedBean,java
package controller; import bean.CategoryFacadeLocal; import bean.ProductFacadeLocal; import entity.Category; import entity.Product; import javax.inject.Named; import javax.enterprise.context.SessionScoped; import java.io.Serializable; import java.util.List; import javax.ejb.EJB; @Named(value = "product") @SessionScoped public class ProductManagedBean implements Serializable { @EJB private CategoryFacadeLocal categoryFacade; @EJB private ProductFacadeLocal productFacade; private int crudCatId; private Product crudProduct; public ProductManagedBean() { crudCatId = 0; } public Product getCrudProduct() { return crudProduct; } public void setCrudProduct(Product crudProduct) { this.crudProduct = crudProduct; } public int getCrudCatId() { return crudCatId; } public void setCrudCatId(int crudCatId) { this.crudCatId = crudCatId; } public List<Product> getProducts() { List<Product> products = productFacade.findAll(); if(crudCatId != 0 ) { products = (List<Product>) categoryFacade.find(crudCatId).getProductCollection(); } return products; } public List<Category> getCategorys() { return categoryFacade.findAll(); } public String create() { crudProduct = new Product(); return "create?faces-redirect=true"; } public String insert() { Category category = categoryFacade.find(crudCatId); crudProduct.setCatId(category); productFacade.create(crudProduct); crudCatId = 0; return "index?faces-redirect=true"; } public String edit() { crudCatId = crudProduct.getCatId().getId(); return "edit?faces-redirect=true"; } public String update() { Category category = categoryFacade.find(crudCatId); crudProduct.setCatId(category); productFacade.edit(crudProduct); crudCatId = 0; return "index?faces-redirect=true"; } public String delete() { productFacade.remove(crudProduct); return "index?faces-redirect=true"; } }
index.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"> <h:head> <title>Product Management</title> </h:head> <h:body> <f:view> <h:form> Category: <h:selectOneMenu value="#{product.crudCatId}"> <f:selectItem itemLabel="All" itemValue="0" /> <f:selectItems value="#{product.categorys}" var="category" itemLabel="#{category.name}" itemValue="#{category.id}"/> </h:selectOneMenu> <h:commandButton value="Filter" action="index"/> <h1><h:outputText value="Products List"/></h1> <h4><h:commandLink value="Create new product" action="#{product.create()}"/></h4> <c:if test="${product.products.size() > 0}"> <h:dataTable value="#{product.products}" var="item" border="1"> <h:column> <f:facet name="header"> <h:outputText value="Id"/> </f:facet> <h:outputText value="#{item.id}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Name"/> </f:facet> <h:outputText value="#{item.name}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Price"/> </f:facet> <h:outputText value="#{item.price}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="CatId"/> </f:facet> <h:outputText value="#{item.catId.name}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Action"/> </f:facet> <h:commandLink value="Delete" action="#{product.delete()}"> <f:setPropertyActionListener target="#{product.crudProduct}" value="#{item}"/> </h:commandLink> | <h:commandLink value="Edit" action="#{product.edit()}"> <f:setPropertyActionListener target="#{product.crudProduct}" value="#{item}"/> </h:commandLink> </h:column> </h:dataTable> </c:if> <c:if test="${product.products.size() == 0}"> <p style="color: red;">Not Found!</p> </c:if> </h:form> </f:view> </h:body> </html>
create.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>Product Management</title> </h:head> <h:body> <f:view> <h:form> <h1><h:outputText value="Create"/></h1> <h:panelGrid columns="3"> <h:outputLabel value="Name:" for="name" /> <h:inputText id="name" value="#{product.crudProduct.name}" title="Name" required="true" requiredMessage="not blank" /> <h:message for="name" style="color: red;" /> <h:outputLabel value="Price:" for="price" /> <h:inputText id="price" value="#{product.crudProduct.price}" title="Price" required="true" requiredMessage="not blank" converterMessage="must be is number"> <f:convertNumber integerOnly="true" type="number" /> </h:inputText> <h:message for="price" style="color: red;" /> <h:outputLabel value="CatId:" for="catId" /> <h:selectOneMenu id="catId" value="#{product.crudCatId}" required="true" requiredMessage="select is blank"> <f:selectItem itemLabel="--- SELECT ---" itemValue="#{null}" noSelectionOption="true" /> <f:selectItems value="#{product.categorys}" var="category" itemLabel="#{category.name}" itemValue="#{category.id}"/> </h:selectOneMenu> <h:message for="catId" style="color: red;" /> </h:panelGrid> <h:commandButton value="Save" action="#{product.insert()}" /> </h:form> </f:view> </h:body> </html>
edit.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>Product Management</title> </h:head> <h:body> <f:view> <h:form> <h1><h:outputText value="Edit"/></h1> <h:panelGrid columns="3"> <h:outputLabel value="Id:" for="id" /> <h:inputText id="id" value="#{product.crudProduct.id}" title="Id" readonly="true"/> <h:message for="id" style="color: red;" /> <h:outputLabel value="Name:" for="name" /> <h:inputText id="name" value="#{product.crudProduct.name}" title="Name" required="true" requiredMessage="not blank" /> <h:message for="name" style="color: red;" /> <h:outputLabel value="Price:" for="price" /> <h:inputText id="price" value="#{product.crudProduct.price}" title="Price" required="true" requiredMessage="not blank" converterMessage="must be is number"> <f:convertNumber integerOnly="true" type="number" /> </h:inputText> <h:message for="price" style="color: red;" /> <h:outputLabel value="CatId:" for="catId" /> <h:selectOneMenu id="catId" value="#{product.crudCatId}" required="true" requiredMessage="select is blank"> <f:selectItem itemLabel="--- SELECT ---" itemValue="#{null}" noSelectionOption="true" /> <f:selectItems value="#{product.categorys}" var="category" itemLabel="#{category.name}" itemValue="#{category.id}"/> </h:selectOneMenu> <h:message for="catId" style="color: red;" /> </h:panelGrid> <h:commandButton value="Save" action="#{product.update()}" /> </h:form> </f:view> </h:body> </html>
Giao diện hiển thị:
Giao diện thêm/sửa:
Xử lý validate:
Bắt lỗi rỗng:
<h:outputLabel value="Name:" for="name" /> <h:inputText id="name" value="#{product.crudProduct.name}" title="Name" required="true" requiredMessage="not blank" /> <h:message for="name" style="color: red;" />
Bắt lỗi check number và rỗng:
<h:outputLabel value="Price:" for="price" /> <h:inputText id="price" value="#{product.crudProduct.price}" title="Price" required="true" requiredMessage="not blank" converterMessage="must be is number"> <f:convertNumber integerOnly="true" type="number" /> </h:inputText> <h:message for="price" style="color: red;" />
Bắt lỗi không chọn select/option:
<h:outputLabel value="CatId:" for="catId" /> <h:selectOneMenu id="catId" value="#{product.crudCatId}" required="true" requiredMessage="select is blank"> <f:selectItem itemLabel="--- SELECT ---" itemValue="#{null}" noSelectionOption="true" /> <f:selectItems value="#{product.categorys}" var="category" itemLabel="#{category.name}" itemValue="#{category.id}"/> </h:selectOneMenu> <h:message for="catId" style="color: red;" />
Nhận xét
Đăng nhận xét