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 đủ



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 SQLPoolbà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


Sau khi thêm JSF Framework nó sẽ thêm web.xml:
<?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

Tạo các file JSF Page(New => Orther => JavaServer Faces => JSF Page) create.xhtml, edit.xhtml

Xử lý CRUD :D

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> &nbsp;&nbsp;
                <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;" />

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

Nhận xét

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

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

Build validation using VanillaJS for Form Submit