Using JPA to build a J2EE 3-tier Web Application
January 7, 2013 Leave a comment
The purpose of this entry is to demonstrate a full J2EE web application. The application will generate:
- a Java Persistence API (JPA) entity modeled on an existing database table
- an Enterprise JavaBean (EJB) which will query the database through the JPA
- a Servlet coupled with a JavaServer Faces (JSF) 2 framework for information display
- a Representational State Transfer (REST) resource capable of providing the JPA entities as web resources
The project will be built in Netbeans 7.2.1 and hosted on Glassfish 3.2.1
Start off by creating a Web Application project and specify the Glassfish Server. Then, clicking on the project, create a new Entity Class from Database (under Persistence) and specify the datasource along with the required tables. Specify a package. Check the NamedQuery, JAXB and Persistence Unit boxes.
Next, create a new stateless EJB in the package (with the annotation @Stateless). We will be using JPA entities as RESTful resources, so tell netbeans to register all REST resources to the javax.ws.rs.Application class automatically and add a Jersey Library (JAX-RS implementation).
@javax.inject.Named @Path("/customers") @Stateless public class CustomerSessionBean { @PersistenceContext EntityManager em; public List<Customer> getCustomers() { return (List<Customer>)em.createNamedQuery("Customer.findAll").getResultList(); } //RESTful resource, access at http://localhost:8080/JavaEE6SampleApp/webresources/customers/customer/1 @GET @Path("/customer/{id}") @Produces("application/xml") public Customer getCustomer(@PathParam("id")Integer id) { return (Customer)em.createNamedQuery("Customer.findByCustomerId") .setParameter("customerId", id).getSingleResult(); } }
Next, create the servlet that uses the EJB.
@WebServlet(name = "TestServlet", urlPatterns = {"/TestServlet"}) public class TestServlet extends HttpServlet { @EJB CustomerSessionBean ejb; // Access at http://localhost:8080/JavaEE6SampleApp/TestServlet protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("<html>"); out.println("<head>"); out.println("<title>Servlet TestServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Servlet TestServlet at " + request.getContextPath () + "</h1>"); out.println(ejb.getCustomers()); out.println("</body>"); out.println("</html>"); } finally { out.close(); } } // HTTPServlet Methods go here }
Next, we will go about creating the Context and Dependency Injection (CDI) which allows the EJB to support the JSF pages. Create a beans.xml file in the project and set the project framework to JSF. Create a Facelets Template (JSF) in the WEB-INF folder using one of the CSS layouts. Edit it to become:
<?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:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="./../resources/css/default.css" rel="stylesheet" type="text/css" /> <link href="./../resources/css/cssLayout.css" rel="stylesheet" type="text/css" /> <title>Facelets Template</title> </h:head> <h:body> <div id="top"> <ui:insert name="top"><h1>Java EE 6 Sample App</h1></ui:insert> </div> <div id="content" class="center_content"> <ui:insert name="content">Content</ui:insert> </div> <div id="bottom"> <ui:insert name="bottom"><center>DEMO!</center></ui:insert> </div> </h:body> </html>
Delete the old index.xhtml file and replace it with a new Facelets Template Client copy. In this case, the root tag used is :
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" template="./WEB-INF/template.xhtml" xmlns:h="http://java.sun.com/jsf/html"> <ui:define name="content"> <h:dataTable value="#{customerSessionBean.customers}" var="c"> <h:column>#{c.name}</h:column> <h:column>#{c.customerId}</h:column> </h:dataTable> </ui:define> </ui:composition>
And we are done. The final results are: