Enterprise Application Development in Java EE
Lab 12
Concurrency, Listeners and Caching
Mục tiêu
- Optimistic locking dùng version attribute
- Tạo Web Client để test Concurrent truy cập vào Entity Class
Phần I Bài tập step by step
Bài 8.1
Xây dựng ứng dụng tích điểm thưởng cho khách hàng
Step 1: Tạo table Customer trong Database ConcurrencyDB
Step 2: Tạo JDBC ConnectionPool ConcurrencyPool và JDBC Resources jdbc/Concurrency
IT Research Department
@BKAP 2015
Page 1 / 20
Enterprise Application Development in Java EE
Step 3: Tạo ứng dụng Enterprise ConcurrencyApp
Step 4: Tạo Entity Class Customer.java từ JDBC Resources jdbc/Concurrency
ConcurrencyApp-ejb Source Packages Persistence Entity Class (Package: entity)
Customer.java
IT Research Department
@BKAP 2015
Page 2 / 20
Enterprise Application Development in Java EE
package entity;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Version;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Quang
*/
@Entity
@Table(name = "Customer")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Customer.findAll", query = "SELECT c FROM Customer c"),
@NamedQuery(name = "Customer.findById", query = "SELECT c FROM Customer c WHERE c.id = :customerId"),
@NamedQuery(name = "customer.findByCustomerName", query = "SELECT c FROM Customer c WHERE
c.customerName like :customerName"),
@NamedQuery(name = "customer.findByRewardPts", query = "SELECT c FROM Customer c WHERE c.rewardPts =
:rewardPts")
})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "CustomerId")
private Long id;
@Column(name = "CustomerName")
private String customerName;
@Column(name = "RewardPts")
private int rewardPts;
@Version
private Long vesion;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCustomerName() {
return customerName;
}
IT Research Department
@BKAP 2015
Page 3 / 20
Enterprise Application Development in Java EE
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public int getRewardPts() {
return rewardPts;
}
public void setRewardPts(int rewardPts) {
this.rewardPts = rewardPts;
}
public Long getVesion() {
return vesion;
}
public void setVesion(Long vesion) {
this.vesion = vesion;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Customer)) {
return false;
}
Customer other = (Customer) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "entity.Customer[ id=" + id + " ]";
}
}
Step 5: Tạo Stateless Session Bean với Local Interface tên là RewardPtsModify
ConcurrencyApp-ejb Source Packages new Other Enterprise JavaBeans
Session Bean
IT Research Department
@BKAP 2015
Page 4 / 20
Enterprise Application Development in Java EE
RewardPtsModifyLocal.java
package beanpack;
IT Research Department
@BKAP 2015
Page 5 / 20
Enterprise Application Development in Java EE
import entity.Customer;
import javax.ejb.Local;
/**
*
* @author Quang
*/
@Local
public interface RewardPtsModifyLocal {
public void multiplyPts(Customer customer, int modifier);
public void addPts(Customer customer, int modifier);
public void addCustomer(String customerName, int startPoints);
public void rapidMultiply(Customer customer, int times) throws Exception;
public void rapidAdd(Customer customer, int times) throws Exception;
public Customer getCustomer(String customerName);
public void resetPoints(Customer customer);
public void setLocking(boolean lockingEnable);
}
RewardPtsModify.java
package beanpack;
import entity.Customer;
import entity.Customer_;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
/**
*
* @author Quang
*/
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class RewardPtsModify implements RewardPtsModifyLocal {
@PersistenceContext(unitName = "ConcurrencyApp-ejbPU")
EntityManager em;
IT Research Department
@BKAP 2015
Page 6 / 20
Enterprise Application Development in Java EE
private boolean lockingEnable;
@Override
public void multiplyPts(Customer customer, int modifier) {
customer.setRewardPts(customer.getRewardPts() * modifier);
}
@Override
public void addPts(Customer customer, int modifier) {
customer.setRewardPts(customer.getRewardPts() + modifier);
}
@Override
public void addCustomer(String customerName, int startPoints) {
Customer customer = new Customer();
customer.setCustomerName(customerName);
customer.setRewardPts(startPoints);
em.persist(customer);
}
@Override
public void rapidMultiply(Customer customer, int times) throws Exception {
//Get a managable entity reference
customer = em.getReference(Customer.class, customer.getId());
//If locking is set as enabled, set an OPTIMISTIC Lock
if (lockingEnable) {
em.lock(customer, LockModeType.OPTIMISTIC);
}
//Repeatedely multiply the point with the modifier of 2
for (int i = 0; i < times; i++) {
multiplyPts(customer, 2);
Thread.sleep(2000);
}
if (lockingEnable) {
em.lock(customer, LockModeType.NONE);
}
}
@Override
public void rapidAdd(Customer customer, int times) throws Exception {
//Get a managable entity reference
customer = em.getReference(Customer.class, customer.getId());
//If locking is set as enabled, set an OPTIMISTIC Lock
if (lockingEnable) {
em.lock(customer, LockModeType.OPTIMISTIC);
}
//Repeatedely increment the points with the modifier of 1
for (int i = 0; i < times; i++) {
addPts(customer, 1);
Thread.sleep(2000);
}
if (lockingEnable) {
em.lock(customer, LockModeType.NONE);
}
}
IT Research Department
@BKAP 2015
Page 7 / 20
Enterprise Application Development in Java EE
@Override
public Customer getCustomer(String customerName) {
Predicate cond = null;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
Root<Customer> cust = cq.from(Customer.class);
cond = cb.like(cust.get(Customer_.customerName), "%" + customerName + "%");
cq.select(cust);
cq.where(cond);
TypedQuery<Customer> query = em.createQuery(cq);
return query.getResultList().get(0);
}
@Override
public void resetPoints(Customer customer) {
customer = em.getReference(Customer.class, customer.getId());
//Reset the points
customer.setRewardPts(1);
}
@Override
public void setLocking(boolean lockingEnable) {
this.lockingEnable = lockingEnable;
}
Step 6: Tạo các trang jsp ở ConcurrencyApp-war
ConcurrencyApp-war New Other Web JSP
CustomerForm.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Form</title>
</head>
<body>
Customer Form
<div id="error" style="color: red"></div>
<form name="CustForm" method="POST" action="CustomerServlet">
<table colspan="2">
<tr><td>Customer Name:</td><td><input type="text" name="customerName"/></td></tr>
<tr><td>Reward Points:</td><td><input type="text" name="rewardPts"/></td></tr>
<tr><td colspan="2" align='center'><input type="submit" value="Submit"/></td></tr>
</table>
</form>
</body>
</html>
CustomerInfo.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
IT Research Department
@BKAP 2015
Page 8 / 20
Enterprise Application Development in Java EE
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Search Page</title>
</head>
<body>
<form name="CustSearchForm" method="POST" action="CustomerSearchServlet">
<table colspan="2" width="60%">
<tr>
<td>Customer Name: </td>
<td><input type="text" size="20" name="customerName"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Search"/></td>
</tr>
</table>
</form>
</body>
</html>
CustomerReward.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Search</title>
</head>
<body>
Increment Reward Points
<form name="CustSearchForm" method="POST" action="CustomerReward">
<table colspan="2">
<tr>
<td>Customer Name:</td>
<td><input type="text" name="customerName"></td>
</tr>
<tr>
<td>Locking Enable:</td>
<td>
<select name="locking">
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</td>
</tr>
<tr>
<td>Add Times:</td>
<td><input type="text" name="add"></td>
</tr>
<tr>
<td>Multiply Times:</td>
IT Research Department
@BKAP 2015
Page 9 / 20
Enterprise Application Development in Java EE
<td><input type="text" name="multiply"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Search"></td>
</tr>
</table>
</form>
</body>
</html>
CustomerReset.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Search</title>
</head>
<body>
Customer Search
<form name="CustSearchForm" method="POST" action="CustomerReset">
<table colspan="2">
<tr>
<td>Customer Name:</td>
<td><input type="text" name="customerName"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Reset"/></td>
</tr>
</table>
</form>
</body>
</html>
Step 7: Tạo các Servlet
ConcurrencyApp-war Source Paclages New Other Web Servlet (package
servlet)
CustomerInfo.java
package servlet;
import beanpack.RewardPtsModifyLocal;
import entity.Customer;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
IT Research Department
@BKAP 2015
Page 10 / 20
Enterprise Application Development in Java EE
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Quang
*/
public class CustomerInfo extends HttpServlet {
@EJB
private RewardPtsModifyLocal rewardPtsModify;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String customerName = request.getParameter("customerName");
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet CustomerInfo</title>");
out.println("</head>");
out.println("<body>");
Customer customer = rewardPtsModify.getCustomer(customerName);
out.println("<table><tr><th>Customer Name</th><th>Reward Points</th></tr>");
out.println("<tr><td>" + customer.getCustomerName() + "</td><td>" + customer.getRewardPts() +
"</td></tr>");
out.println("</body>");
out.println("</html>");
}
}
//
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
IT Research Department
@BKAP 2015
Page 11 / 20
Enterprise Application Development in Java EE
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}
}
CustomerReset.java
package servlet;
import beanpack.RewardPtsModifyLocal;
import entity.Customer;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Quang
*/
public class CustomerReset extends HttpServlet {
@EJB
private RewardPtsModifyLocal rewardPtsModify;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
IT Research Department
@BKAP 2015
Page 12 / 20
Enterprise Application Development in Java EE
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String custName = request.getParameter("customerName");
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet CustomerReset</title>");
out.println("</head>");
out.println("<body>");
Customer customer = rewardPtsModify.getCustomer(custName);
rewardPtsModify.resetPoints(customer);
out.println("Customer Points reset!");
out.println("</body>");
out.println("</html>");
}
}
//
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
IT Research Department
@BKAP 2015
Page 13 / 20
Enterprise Application Development in Java EE
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
CustomerReward.java
package servlet;
import beanpack.RewardPtsModifyLocal;
import entity.Customer;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Quang
*/
public class CustomerReward extends HttpServlet {
@EJB
private RewardPtsModifyLocal rewardPtsModify;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String customerName = request.getParameter("customerName");
boolean lockingEnable = false;
String lockStr = request.getParameter("locking");
if (lockStr.equals("Yes")) {
lockingEnable = true;
}
int addTimes = Integer.parseInt(request.getParameter("add"));
int multiplyTimes = Integer.parseInt(request.getParameter("multiply"));
IT Research Department
@BKAP 2015
Page 14 / 20
Enterprise Application Development in Java EE
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet CustomerReward</title>");
out.println("</head>");
out.println("<body>");
Customer customer = rewardPtsModify.getCustomer(customerName);
rewardPtsModify.setLocking(lockingEnable);
try {
rewardPtsModify.rapidAdd(customer, addTimes);
rewardPtsModify.rapidMultiply(customer, multiplyTimes);
} catch (Exception ex) {
Logger.getLogger(CustomerReward.class.getName()).log(Level.SEVERE, null, ex);
}
out.println("New Customer Details
");
customer = rewardPtsModify.getCustomer(customerName);
out.println("<table border='1'><tr><th>Customer Name</th><th>Reward Point</th></tr>");
out.println("<tr><td>" + customer.getCustomerName() + "</td><td>" + customer.getRewardPts() +
"</td></tr>");
out.println("</table>");
out.println("</body>");
out.println("</html>");
}
}
//
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
IT Research Department
@BKAP 2015
Page 15 / 20
Enterprise Application Development in Java EE
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
CustomerServlet.java
package servlet;
import beanpack.RewardPtsModifyLocal;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Quang
*/
public class CustomerServlet extends HttpServlet {
@EJB
private RewardPtsModifyLocal rewardPtsModify;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String customerName = request.getParameter("customerName");
int rewardPts = Integer.parseInt(request.getParameter("rewardPts"));
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet CustomerServlet</title>");
out.println("</head>");
IT Research Department
@BKAP 2015
Page 16 / 20
Enterprise Application Development in Java EE
out.println("<body>");
rewardPtsModify.addCustomer(customerName, rewardPts);
out.println("Customer Created!
");
out.println("Customer Name: "+customerName+"
");
out.println("Starting points: "+rewardPts);
out.println("</body>");
out.println("</html>");
}
}
//
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Ứng dụng sau khi hoàn thành
IT Research Department
@BKAP 2015
Page 17 / 20
Enterprise Application Development in Java EE
Step 8: Build and Run Application
IT Research Department
@BKAP 2015
Page 18 / 20
Enterprise Application Development in Java EE
IT Research Department
@BKAP 2015
Page 19 / 20
Enterprise Application Development in Java EE
IT Research Department
@BKAP 2015
Page 20 / 20