- Model은 데이터(테이블, 뷰, 데이터베이스 사용자 등) 액세스 및 수정 작업과 관련된 비즈니스 데이터 및 규칙을 나타냅니다.
- View는 사용자 인터페이스(웹 페이지, WAP 인터페이스, SOAP 등)입니다.
- Controller는 사용자의 입력을 수신하고 데이터 요청으로 전환한 다음 사용자의 데이터에 대한 적절한 뷰를 선택합니다.
이 패턴이 페이지 플로우의 기초가 됩니다. 페이지 플로우에서 클라이언트 브라우저는 HTTP get 또는 post를 통해 페이지 플로우에 정보를 요청합니다. 페이지 플로우(controller의 역할을 함)는 사용자 요청을 처리하고, 해당되는 경우 데이터베이스, 레거시 시스템 등(model의 역할을 함)의 데이터를 요청합니다. 반환된 데이터는 표시(View의 역할을 함)를 하기 위해 해당 JSP 페이지로 보내기 전에 처리될 수 있습니다. 이것을 다이어그램으로 보면 아래와 같습니다.

이 문서에서는 WebLogic Workshop 8.0 베타의 새로운 페이지 플로우 기술을 사용하여 데이터베이스 테이블의 컨텐츠에 액세스하여 사용자에게 표시하는 방법의 예제를 살펴보겠습니다. 데이터 커넥션이 이미 올바로 설정되어 있고 독자 여러분들이 Java, JSP 및 TSQL 사용에 익숙하다는 가정 하에, 이 문서에서는 samples/workshop 도메인에 포함되어 있는 cgDataSource를 사용할 것입니다.
WebLogic Workshop에 "DataTutorial"라는 비어 있는 새로운 애플리케이션을 만드는 것부터 시작해보겠습니다. "samples/workshop" 도메인을 마우스 오른쪽 단추로 클릭하고 "Properties"를 선택한 다음 "WebLogic Server" 섹션을 클릭하여 새로운 애플리케이션이 "samples/workshop" 도메인을 사용하도록 설정합니다. 서버 홈 디렉터리가 "<install location>\weblogic81b\samples\workshop"이어야 합니다. 이제 "Tools/WebLogic Server/Start Server"를 클릭하여 서버를 시작합니다.
새로운 애플리케이션에서 "DataTutorial" 폴더를 마우스 오른쪽 단추로 클릭하고 "ItemsTable"이라는 웹 프로젝트를 만듭니다. 새로운 ItemsTable 프로젝트 폴더를 마우스 오른쪽 단추로 클릭하고 "New/Choose File Type..."을 선택하고 "Business Logic" 그룹에서 "Database Control"을 선택합니다. 그러면 데이터베이스 컨트롤 마법사가 나타납니다. 이제 새로운 데이터베이스 컨트롤인 "DataModel"을 호출하고 cgDataSource를 사용할 것입니다. Data Source 드롭다운에 cgDataSource가 표시되지 않을 경우 서버를 제대로 시작했는지 그리고 samples/workshop 도메인을 사용하고 있는지 확인하십시오. next를 클릭하고 "Don't create methods"를 선택한 다음 "Create"를 클릭합니다. 일반적으로 작동 방법을 이해하기 위한 것만 아니라면 마법사에서 테이블 액세스 메서드를 만드는 것이 좋지만 여기서는 직접 해 보겠습니다.
datamodel 폴더에서 새로운 DataModel.jcx 파일을 두 번 클릭하고 "Source View"를 선택합니다. 여기서 몇 가지 버그를 처리해야 합니다. 첫째, "data-source-jndi-name"을 "DATA_SOURCE_JNDI"에서 "cgDataSource"로 변경합니다. 그런 다음 마법사가 추가한 스키마를 삭제합니다. 이 자습서에서는 이 스키마를 사용하지 않습니다. 이제 DataModel 컨트롤 코드가 다음과 같이 표시됩니다.
package datamodel; import java.sql.SQLException; import javax.sql.RowSet; import weblogic.jws.control.DatabaseControl; import weblogic.jws.control.DatabaseFilter; /** *@jc:connection data-source-jndi-name="cgDataSource" */ public interface DataModel extends DatabaseControl { } |
이제 "Cajun" 스키마의 "Items" 테이블에서 모든 행을 가져오기 위한 메서드를 추가할 것입니다. 그러나 우선 가져오려는 데이터에 쉽게 액세스하기 위해 "Item" 객체를 만들어야 합니다. "datamodel" 폴더를 마우스 오른쪽 단추로 클릭하고 "New/Java Class"를 선택합니다. 이 클래스를 "Item"이라고 하겠습니다. Items 테이블의 각 행에는 항목 번호, 항목 이름, 사용 가능한 수량 및 가격이 포함되어 있습니다. 이러한 정보를 유지하기 위해 Item 클래스에 공용 멤버를 추가할 것입니다. 실제 Java 클래스라면 변수 설정 및 검색을 처리하기 위해 getter, setter 및 creator 메서드를 추가하겠지만 이 문서는 Java 클래스 생성에 관한 내용이 아니기 때문에 신속하고 간단하게 하겠습니다. 여기서는 "java.io.Serializable" 인터페이스를 구현하여 그것을 요청 스트림에 전달만 합니다. 이제 Item.java 파일이 다음과 같이 표시됩니다.
package datamodel; public class Item implements java.io.Serializable { public Integer ItemNumber; public String ItemName; public Integer QuantityAvailable; public Double Price; } |
이제 새로운 Item 클래스를 사용하여 Items 테이블의 모든 행을 가져오기 위해 데이터베이스 컨트롤에 메서드를 구축하겠습니다. DataModel.jcx에서 Design View로 이동하고, 컨트롤에서 마우스 오른쪽 단추를 클릭하고, "getItems"라는 새로운 메서드를 추가합니다. 새로운 메서드를 마우스 오른쪽 단추로 클릭하고 "Edit SQL"을 선택합니다. 여기에 원하는 데이터를 가져오기 위한 SQL 쿼리를 넣습니다. Cajun 스키마에서 Items 테이블의 모든 열을 가져오려면 다음 코드를 SQL 상자에 넣습니다.
SELECT ITEMNUMBER, ITEMNAME, QUANTITYAVAILABLE, PRICE FROM CAJUN.ITEMS |
그러면 테이블의 모든 항목을 반환하므로, 반환 형식을 구축한 Item 클래스의 Items 어레이로 설정합니다. Java 상자에서 코드를 다음과 같이 설정합니다.
public Item[] getItems() |
이제 Source View로 이동하면 DataModel 컨트롤의 코드가 다음과 같이 표시됩니다.
package datamodel; import java.sql.SQLException; import javax.sql.RowSet; import weblogic.jws.control.DatabaseControl; import weblogic.jws.control.DatabaseFilter; /** *@jc:connection data-source-jndi-name="cgDataSource" */ public interface DataModel extends DatabaseControl { /** * @jc:sql statement="SELECT ITEMNUMBER, ITEMNAME, QUANTITYAVAILABLE, PRICE FROM CAJUN.ITEMS" */ public Item[] getItems(); } |
이제 페이지 플로우에서 컨트롤을 사용할 준비가 되었습니다. ItemsTable 프로젝트에 index.jsp, error.jsp 및 Controller.jpf 파일 세 개가 표시됩니다. 이 컨트롤러 파일이 Model-View-Controller 패턴의 controller 부분이고 .JSP 파일은 view에 해당됩니다.
Controller.jpf를 두 번 클릭하고 "Flow View"에 있는지 확인하십시오. 이제 DataModel.jsx를 페이지 플로우로 드래그합니다. 그러면 액세스할 수 있는 페이지 플로우에 컨트롤의 인스턴스가 생깁니다. 이제 페이지 뷰의 모습이 다음과 같아집니다.

이 다이어그램을 보면 알 수 있듯이 페이지 플로우로 들어가는 새 사용자는 먼저 'begin' 메서드(데이터베이스에서 데이터를 가져오는 곳)를 실행해야 합니다. 그런 다음 데이터베이스 컨트롤에서 수신하는 데이터를 index.jsp 페이지에서 액세스할 수 있도록 요청 스트림에 넣습니다. 팔레트에 있는 dataModel 멤버에 유의하십시오. 이것은 DataModel 데이터베이스 컨트롤이 페이지 플로우의 모든 이벤트에서 액세스할 수 있음을 의미합니다. 이면에서WebLogic은 페이지 플로우의 액션을 제어하기 위한 Java 서블릿을 생성 및 배포합니다. 그러나 관심을 가져야 할 것은 .jpf 파일에 포함된 기본 코드입니다.
이제 Source View로 전환합니다. Item 클래스를 사용하고 있기 때문에 다음과 같이 imports 섹션에서 클래스에 참조를 추가해야 합니다.
import datamodel.Item; |
마지막으로 데이터베이스에서 항목 목록을 가져옵니다. 그렇게 하려면 begin() 메서드에 dataModel의 getItems() 메서드에 액세스하기 위한 코드를 추가해야 합니다. 오류를 발견하여 서버 창으로 보낼 수 있도록 데이터베이스 컨트롤에 대한 호출은 try/catch 블록으로 묶습니다.
protected Forward begin() { try { Item[] Items = dataModel.getItems(); getRequest().setAttribute( "items", Items ); } catch( Throwable ex ) { ex.printStackTrace(); } return new Forward("index"); } |
데이터베이스 컨트롤에서 getItems() 메서드를 호출하는 중이고 반환 값을 Items의 어레이로 설정했다는 사실을 유의하십시오. 이제 이러한 어레이를 .jsp 페이지에서 액세스할 수 있도록 setAttribute를 사용하여 어레이를 HTTP Request 스트림에 넣습니다. 원할 경우 페이지 플로우에서 바로 dataModel 변수에 액세스할 수도 있지만 컨트롤러(페이지 플로우)를 사용하여 데이터에 대한 액세스 제어, 오류 처리 등을 할 생각이므로 데이터 표시에 대해서는 view(JSP 페이지)에서만 처리하도록 합니다. 전체 Controller.jpf가 다음과 같이 표시됩니다.
import com.bea.wlw.netui.pageflow.PageFlowController; import com.bea.wlw.netui.pageflow.Forward; import datamodel.Item; /** * This is the default controller for a blank web application. */ public class Controller extends PageFlowController { /** * @common:control */ private datamodel.DataModel dataModel; /** * @jpf:action * @jpf:forward name="index" path="index.jsp" */ protected Forward begin() { try { Item[] Items = dataModel.getItems(); getRequest().setAttribute( "items", Items ); } catch( Throwable ex ) { ex.printStackTrace(); } return new Forward("index"); } } |
드디어 데이터베이스에서 데이터를 가져와 요청 스트림에 넣었습니다. 이제 JSP 페이지에 항목 목록을 인쇄할 준비가 되었습니다. index.jsp를 두 번 클릭하고 Source View로 이동합니다. 이 JSP에 Item 클래스를 사용하고 있기 때문에 다시 참조를 해야 합니다. 그렇게 하려면 JSP에서 아래와 같이 페이지 위쪽에 import 구문을 넣습니다.
<%@page import="datamodel.Item"%> |
<title>을 "Items Table"로 변경하고 index.jsp가 다음과 같이 표시되도록 코드를 추가합니다.
<!--Generated by Weblogic Workshop--> <%@ page language="java" contentType="text/html;charset=UTF-8"%> <%@ taglib uri="netui-tags-databinding.tld" prefix="netui-data"%> <%@ taglib uri="netui-tags-html.tld" prefix="netui"%> <%@ taglib uri="netui-tags-template.tld" prefix="netui-template"%> <%@page import="datamodel.Item"%> <html> <head> <title>Items Table</title> </head> <body> Here is our Items Table:<p> <table border=1> <tr><td>Item Number</td><td>Item Name</td><td>Quantity Available</td><td>Price</td></tr> <% // Get the Items from the request stream Item oItem[] = (Item[]) request.getAttribute("items"); // Loop through the items for (int f=0 ; f < oItem.length ; f++) { out.println("<tr><td>" + oItem[f].ItemNumber + "</td><td>" + oItem[f].ItemName + "</td><td>" + oItem[f].QuantityAvailable + "</td><td>$" + oItem[f].Price + "</td></tr>"); } %> </table> </body> </html> |
이 코드를 자세히 살펴보겠습니다. 먼저 다음 코드를 사용하여 요청 스트림에서 Items 어레이를 가져옵니다.
Item oItem[] = (Item[]) request.getAttribute("items"); |
그런 다음 항목을 루핑합니다.
for (int f=0 ; f < oItem.length ; f++) |
각 항목에 대해 테이블 셀의 항목 번호, 항목 이름, 사용 가능한 수량 및 가격을 출력 스트림으로 인쇄합니다.
out.println("<tr><td>" + oItem[f].ItemNumber + "</td><td>" + oItem[f].ItemName + "</td><td>" + oItem[f].QuantityAvailable + "</td><td>$" + oItem[f].Price + "</td></tr>"); |
Item 객체를 사용하여 Items 테이블의 열을 저장했기 때문에 객체 멤버에 쉽게 액세스할 수 있습니다.
이제 메뉴 표시줄에서 Debug/Start를 선택합니다. 마치 시스템에 지원되는 모든 서블릿, 빈, 파일 등을 처음으로 서버에 구축 및 배포한 것처럼 바쁘게 돌아가다가 잠시 후 Workshop 테스트 브라우저에 다음이 표시됩니다.

오류 페이지가 표시되는 경우 begin 메서드 코드의 첫 번째 줄에 중단점을 설정하고 다시 실행하십시오. 코드를 살펴보면 오류가 발생한 위치를 알 수 있습니다.
애플리케이션의 URL이 index.jsp가 아니라 Controller.jpf인 점에 유의하십시오. 말했다시피 표시를 렌더링해야 하는 경우 컨트롤러는 JSP 파일을 호출하는 실제 Java 서블릿이지만 핵심 "컨트롤러" 기능은 JPF에 포함되어 있습니다. 데이터 액세스는 데이터베이스 컨트롤 아니 어떤 면에서는 데이터베이스 자체에 캡슐화되어 있습니다.
지금까지 샘플 예제이긴 하지만 웹 페이지의 데이터에 액세스하고 사용자를 위해 데이터를 포맷하는 것이 얼마나 간단한지 알 수 있었습니다. 여기서 애플리케이션의 기능을 세 가지 역할로 구분했는데, 데이터베이스 컨트롤은 데이터베이스에 대한 액세스를 제어하고 데이터베이스의 결과를 다시 처리하는 "model"이었고, controller는 Controller.jpf라는 페이지 플로우 자체였습니다. 페이지 플로우에서 사용자의 요청(이 사례의 경우 메인 페이지에 대한 요청)을 처리하고 Model에서 데이터를 요청하고 뷰에서 사용할 수 있도록 데이터를 포맷한 다음 마지막으로 view 즉, index.jsp로 보내 데이터를 가져와 사용자에게 표시했습니다. 데이터를 요청하는 사용자가 휴대폰 브라우저를 사용하는 경우 컨트롤러 파일은 간단히 휴대폰의 다른 뷰로 전달할 수 있습니다. 데이터베이스 컨트롤은 다른 페이지 플로우 또는 웹 서비스에서 쉽게 재사용할 수 있습니다. 재사용성은 MVC 설계 패턴 사용 시 얻어지는 또 다른 이점입니다. 질문 사항이나 버그, 의견은 dev2dev@bea.com의 dev2dev로 문의하십시오.