내용 목차
본 장에서는 예제를 이용해서 Stateless Session Bean과 Java Persistence API를 이용하여 Entity를 개발하고 디플로이하는 과정을 설명한다.
Session Bean은 기본적으로 Business Interface와 Bean Class로 구성된다.
다음의 예제 코드는 “Hello EJB”를 출력하는 Business Method를 가진 간단한 Stateless Session Bean 예제이다.
Business Interface
[예 10.1] <<Hello.java>>
package helloejb; import javax.ejb.Remote; @Remote public interface Hello { String sayHello(); }
Bean Class
[예 10.2] <<HelloBean.java>>
package helloejb; import javax.ejb.Stateless; @Stateless(mappedName="helloejb.Hello") public class HelloBean implements Hello { public String sayHello() { return "Hello EJB!"; } }
예제 코드는 다음의 디렉터리에서 찾아볼 수 있다.
JEUS_HOME\samples\getting_started\helloejb\helloejb-ejb\src\java\helloejb
HelloEJB를 호출하는 서블릿 클라이언트를 다음과 같이 구현한다.
[예 10.3] <<HelloClient.java>>
package helloejb; import java.io.*; import javax.ejb.EJB; import javax.servlet.*; import javax.servlet.http.*; public class HelloClient extends HttpServlet { @EJB private Hello hello; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); try { // Call session bean business method. String msg = hello.sayHello(); response.setContentType("text/html"); out.println("<html>"); out.println("<head>"); out.println("<title>HelloClient</title>"); out.println("</head>"); out.println("<body>"); out.println("<center><h1>" + msg + "</h1></center>"); out.println("</body>"); out.println("</html>"); out.close(); } catch(Exception ex){ response.setContentType("text/plain"); ex.printStackTrace(out); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
예제 코드는 다음 위치의 디렉터리에서 찾아볼 수 있다.
JEUS_HOME\samples\getting_started\helloejb\helloejb-war\src\java\helloejb
작성된 예제는 Ant를 이용하여 다음과 같이 빌드할 수 있다.
%JEUS_HOME%\samples\getting_started\helloejb>ant build
빌드가 정상적으로 완료되면 'dist\helloejb.ear' 애플리케이션 EAR 파일이 생성된다.
패키징한 EJB 애플리케이션을 WebAdmin과 콘솔 툴로 디플로이할 수 있다.
다음은 WebAdmin으로 디플로이하는 과정에 대한 설명이다.
커맨드 창에서 jeus 명령을 실행하고, 웹 브라우저로 접속한다.
Node View에서 [어플리케이션 모듈 디플로이]를 선택한다.
Main View에 모듈 디플로이를 위한 초기 화면이 나타난다. [모듈]이나 [절대 경로], [파일 업로드] 탭에서 모듈을 선택하고 [다음] 버튼을 클릭한다.
[1.모듈 선택] 탭에 보이는 것과 같이 디플로이할 대상 모듈을 선택하는 화면으로 3가지 방법을 제공한다.
탭 | 설명 |
---|---|
모듈 | JEUS_HOME\webhome\app_home이나 JEUS_HOME \webhome\autodeploy 아래 있는 모듈을 보여주며, 이들 중 하나를 선택해 디플로이할 수 있다. |
절대 경로 | 디플로이할 모듈이 존재하는 위치를 파일명을 포함해 지정한다. 모듈의 위치는 WebAdmin이 실행되는 머신이 아니고 JEUS가 구동되는 머신의 디렉터리이다. |
파일 업로드 | WebAdmin이 실행되는 머신에서 JEUS가 구동되는 머신으로 파일을 업로드할 수 있다. 업로드할 위치는 JEUS_HOME \webhome\app_home 이나 JEUS_HOME\webhome\autodeploy 중 하나를 선택할 수 있다. |
모듈 선택이 완료되면 디플로이할 대상이 엔진 컨테이너 단위로 나타난다. 디플로이할 대상을 선택하고 [다음] 버튼을 클릭한다.
디플로이할 때 필요한 선택 사항을 입력하는 화면으로, 애플리케이션 설정과 모듈 설정을 할 수 있다. 특별한 설정이 필요 없으므로 [다음] 버튼을 클릭한다.
디플로이할 방식을 선택하고 [디플로이] 버튼을 클릭한다.
디플로이가 성공적으로 완료되면 Node View의 [어플리케이션 모듈] 아래 'helloejb'가 나타난다.
다음은 콘솔 툴을 사용하여 수동으로 디플로이하는 과정에 대한 설명이다.
패키징된 'helloejb.ear' 파일을 다음 JEUS APP_HOME 디렉터리에 복사한다.
JEUS_HOME/webhome/app_home/
콘솔 창에서 jeusadmin이라고 입력해서 실행한다.
C:\TmaxSoft\JEUS6.0\bin>jeusadmin johan Login name>administrator Password> JEUS 6 Jeus Manager Controller node>deploy -con johan_container1 helloejb.ear using the following application info : ... node>applist –con johan_container1 name : helloejb type : J2EEApplication ...
위의 명령을 살펴보면 deploy <module name>을 통해서 HelloEJB 애플리케이션을 디플로이하고, applist를 이용하여 디플로이된 것을 확인했다. 디플로이가 정상적으로 이루어졌다면 exit 명령을 통하여 콘솔 툴을 종료한다.
본 절에서는 Java Persistence API를 통해 Entity를 작성하고 컴파일하여 디플로이하는 과정을 설명한다.
예제는 Product Entity와 이를 다루는 EJB인 ProductManager Session Bean으로 구성되어 있다.
Entity
[예 10.4] <<Product.java>>
package hellojpa; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQuery; @Entity @NamedQuery(name="findAllProducts", query="SELECT p FROM Product p") public class Product implements Serializable { @Id private String productId; private double price; private String description; public Product() { } public Product(String productId, double price, String description){ this.productId = productId; this.price = price; this.description = description; } public String getProductId() { return productId; } public void setProductId(String id) { this.productId = id; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String toString() { return "Product[productId=" + productId + ", price=" + price + ", description=" + description + "]"; } }
Business Interface
[예 10.5] <<ProductManager.java>>
package hellojpa; import java.util.Collection; import javax.ejb.Local; @Local public interface ProductManager { Product createProduct(String productId, double price, String desc); Product getProduct(String productId); Collection findAllProducts(); Collection findProductsByDescription(String desc); Collection findProductsInRange(double low, double high); void updateProduct(Product product); void removeProduct(Product product); void removeAllProducts(); }
Bean Class
[예 10.6] <<ProductManagerBean.java>>
package hellojpa; import java.util.Collection; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; @Stateless(mappedName="hellojpa.ProductManager") public class ProductManagerBean implements ProductManager { @PersistenceContext private EntityManager em; public ProductManagerBean() { } public Product createProduct(String productId, double price, String desc){ Product product = new Product(productId, price, desc); em.persist(product); return product; } public Product getProduct(String productId){ return (Product)em.find(Product.class, productId); } public Collection findAllProducts() { return em.createNamedQuery("findAllProducts").getResultList(); } public Collection findProductsByDescription(String desc){ Query query = em.createQuery("SELECT p FROM Product p WHERE p.description=:desc"); query.setParameter("desc", desc); return query.getResultList(); } public Collection findProductsInRange(double low, double high){ Query query = em.createQuery("SELECT p FROM Product p WHERE p.price between :low and :high"); query.setParameter("low", low).setParameter("high", high); return query.getResultList(); } public void updateProduct(Product product){ Product managed = em.merge(product); em.flush(); } public void removeProduct(Product product){ Product managed = em.merge(product); em.remove(managed); } public void removeAllProducts(){ em.createQuery("DELETE FROM Product p").executeUpdate(); } }
예제 코드는 다음의 디렉터리에서 찾아볼 수 있다.
JEUS_HOME\samples\getting_started\hellojpa\hellojpa-ejb\src\java\hellojpa
ProductManager EJB를 사용하여 DB에 데이터를 저장하고 데이터를 다루는 서블릿 클라이언트를 다음과 같이 구현한다.
[예 10.7] <<ProductManagerClient.java>>
package hellojpa; import java.io.*; import java.util.Collection; import javax.ejb.EJB; import javax.servlet.*; import javax.servlet.http.*; public class ProductManagerClient extends HttpServlet { @EJB private ProductManager productManager; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain"); PrintWriter out = response.getWriter(); out.println("SERVLET CLIENT CONSOLE OUTPUT:\n"); productManager.removeAllProducts(); out.println("Cleaned up existing products.\n"); out.println("Creating products..."); Product p1 = productManager.createProduct("1", 10.00, "Ceramic Dog"); Product p2 = productManager.createProduct("2", 13.00, "Wooden Duck"); Product p3 = productManager.createProduct("3", 19.00, "Ivory Cat"); Product p4 = productManager.createProduct("4", 33.00, "Ivory Cat"); Product p5 = productManager.createProduct("5", 22.00, "Chrome Fish"); Collection products; out.println("Created products:"); products = productManager.findAllProducts(); for(Object product : products){ out.println(product); } out.println(); out.println("Find product with productId 1:"); Product pp1 = productManager.getProduct("1"); out.println("Found = " + pp1.getDescription() + " $" + pp1.getPrice()); out.println("Update the price of this product to 12.00"); pp1.setPrice(12.00); productManager.updateProduct(pp1); Product pp2 = productManager.getProduct("1"); out.println("Product " + pp2.getDescription() + " is now $" + pp2.getPrice()); out.println(); out.println("Find products with description:"); products = productManager.findProductsByDescription("Ivory Cat"); for(Object product : products){ out.println(product); } out.println(); out.println("Find products with price range between 10.00 and 20.00"); products = productManager.findProductsInRange(10.00, 20.00); for(Object product : products){ out.println(product); } out.println(); out.println("Removed all products."); productManager.removeProduct(p1); productManager.removeProduct(p2); productManager.removeProduct(p3); productManager.removeProduct(p4); productManager.removeProduct(p5); out.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
예제코드는 다음의 디렉터리에서 찾아볼 수 있다.
JEUS_HOME\samples\getting_started\hellojpa\hellojpa-war\src\java\hellojpa
Ant를 이용하여 예제 코드를 다음과 같이 빌드할 수 있다. 다음은 컴파일하는 과정에 대한 설명이다.
예제가 작성된 경로에서 다음과 같이 명령어를 입력한다.
C:\jeus\samples\getting_started\hellojpa>ant build
빌드가 정상적으로 완료되면 dist\hellojpa.ear 애플리케이션 EAR 파일이 생성된다.
이번 예제는 DB를 필요로 하므로 Derby를 시작시키도록 한다. 또한 DB가 jdbc/sample 데이터 소스로 설정되어 있어야 한다. 자세한 것은 “제8장 시스템 설정”을 참고한다.
Derby가 시작되었다면 다음과 같이 DB 테이블을 생성하도록 한다. 여기서는 sample 이라고 하는 DB를 사용할 것이다.
CREATE TABLE PRODUCT (PRODUCTID VARCHAR(255) NOT NULL, PRICE FLOAT, DESCRIPTION VARCHAR(255), PRIMARY KEY (PRODUCTID));
다음의 명령어를 입력해서 DB 테이블을 생성한다.
C:\jeus\samples\getting_started\hellojpa>ant setup
이제 빌드와 DB 설정이 완료되었다면 패키징된 모듈을 디플로이할 준비가 완료되었다.
패키징한 EJB 애플리케이션을 WebAdmin과 콘솔 툴로 디플로이할 수 있다.
다음 과정에 따라 패키징된 모듈을 WebAdmin으로 디플로이한다.
WebAdmin으로 접속한다.
Node View에서 [어플리케이션 모듈 디플로이]를 선택한다.
디플로이할 모듈을 선택하고 [다음] 버튼을 클릭한다.
디플로이할 컨테이너를 선택하고 [다음] 버튼을 클릭한다.
디플로이할 때 팔요한 선택 사항을 입력하는 화면으로, 애플리케이션 설정과 모듈 설정을 할 수 있다. 특별한 설정이 필요 없으므로 [다음] 버튼을 클릭한다.
디플로이할 방식을 선택하고 [디플로이] 버튼을 클릭한다.
디플로이가 성공할 경우 [어플리케이션 모듈] 아래 'hellojpa' 가 나타난다.
“8.1.3. 데이터소스 추가”에서 데이터 소스 설정 관련 부분에서 설명했지만, 데이터 소스 설정에서 패스워드가 틀렸거나 IP 주소가 정확하지 않을 경우에 디플로이는 실패하게 된다.
콘솔 툴을 사용하여 수동으로 디플로이하는 방법은 다음과 같다.
패키징된 hellojpa.ear 파일을 다음 JEUS APP_HOME 디렉터리에 복사한다.
JEUS_HOME/webhome/app_home/
콘솔 창에서 jeusadmin이라고 입력해서 콘솔 툴을 실행한다.
C:\>jeusadmin johan Login name>administrator Password> JEUS 6 Jeus Manager Controller node>deploy -con johan_container1 hellojpa.ear using the following application info : ... node>applist –con johan_container1 name : hellojpa type : J2EEApplication ...
모듈이 정상적으로 디플로이되었는지 확인한다.