[ETC] Direct Web Remoting

황제낙엽 2009.03.12 02:51 조회 수 : 28 추천:88

sitelink1  
sitelink2  
sitelink3  
extra_vars4  
extra_vars5  
extra_vars6  
http://wiki.javajigi.net/display/WEB20/dwr#dwr-DWR%EC%9D%B4%EB%9E%80%3F

Table of Contents

DWR이란?

DWR은 쉬운 방법으로 AJAX 와 XMLHttpRequest를 사용하길 원하는 개발자를 위한 오픈 소스 솔루션이다.
DWR 은 Direct Web Remoting 의 약자로 클라이언트 쪽의 AJAX 관련 자바스크립트 라이브러리 뿐만 아니라 서버쪽의 웹 어플리케이션 라이브러리 까지 포함하고 있다.

참고 : http://www.javapassion.com/ajaxcodecamp/#Direct_Web_Remoting_DWR

DWR은 크게 두 개의 파트로 구성되어 있다.

  • Javascript를 이용하여 AJAX의 구조를 이용하여 web-server기반의 서블릿으로 부터 data 검색이 가능하도록 하는 Code
  • 웹개발자들로 하여금 검색된 data를 이용하여 동적으로 웹 페이지를 update하는 것을 용이하게 하기 위한 JavaScript library
Useful Information

DWR 웹 어플리케이션은 크게 모든 요청을 처리하는 컨트롤러 역할을 하는 DWRServlet 과 클라이언트의 요청을 처리할 빈들로 구성되어 있다.DWRServlet 은 웹 어플리케이션의 /WEB-INF/web.xml 에서 설정이 가능하고 요청들을 처리할 빈( bean) 객체들은 /WEB-INF/dwr.xml 에서 설정할 수 있다.

설정방법 및 샘플

아래 샘플파일은 참고자료에서 다운받은 것을 기준으로 작성되었다.

  1. dwr.jar 를 다운로드 받은 후 WEB-INF/lib 아래 둔다.
  2. web.xml에 DWRServlet 관련 설정을 한다.
  3. WEB-INF/dwr.xml 파일을 작성한다.
  4. 호출하는 클라이언트 프로그램을 작성한다.(여기선 jsp)

web.xml

·미리보기 | 소스복사·
  1. <servlet>  
  2.     <servlet-name>dwr-invoker</servlet-name>  
  3.     <display-name>DWR Servlet</display-name>  
  4.     <description>Direct Web Remoter Servlet</description>  
  5.     <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>  
  6.     <init-param>  
  7.          <param-name>debug</param-name>  
  8.          <param-value>true</param-value>  
  9.     </init-param>  
  10. </servlet>  
  11.        
  12. <servlet-mapping>  
  13.     <servlet-name>dwr-invoker</servlet-name>  
  14.     <url-pattern>/dwr/*</url-pattern>  
  15. </servlet-mapping>  

보면 DWR 웹 어플리케이션에서는 모든 요청을 일단 DWRServlet 이 받아서 처리하게 되는데 그 요청을 처리할 객체나 데이터 타입의 맵핑, 보안등의 설정은 모두 dwr.xml 의 설정을 바탕으로 한다

dwr.xml

·미리보기 | 소스복사·
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">  
  3.   
  4. <dwr>  
  5.   <allow>  
  6.         <convert converter="bean" match="com.tmax.spring.domain.Apartment"/>  
  7.         <create creator="new" javascript="ApartmentDAO" >  
  8.           <param name="class" value="com.tmax.spring.ibatis.ApartmentDAO"/>  
  9.        <include method="findApartments"/>  
  10.             <include method="countApartments"/>  
  11.         </create>  
  12.   </allow>  
  13. </dwr>  
DWR에서 요청을 처리할 빈(bean) 객체를 지정하는 부분이 <create />이다.
create 요소에는 creator,javascript,scope의 3가지 속성이 지정될 수 있다 creator 속성은 요청을 처리할 빈 객체가 생성되는 방식을 지정하는데 직접 클래스의 이름을 지정하여 생성할 수도 있고 빈 셸 스크립트를 이용하거나 Spring framework 에 객체 생성을 위임할 수도 있다. 기본적으로 가장 많이 사용되는 create 속성인 new 는 지정된 클래스의 인스턴스를 생성하여 클라이언트 쪽에서 오는 자바스크립트 요청과 지정된 인스턴스의 메소드를 맵핑해준다.
Scope 속성 은 creator 로 지정된 객체의 라이프싸이클 범위를 지정하는 것으로 J2EE 서블릿 스펙에서 정의된 scope 와 동일하게 application, page, request,session 중 하나의 값을 가질 수 있다.
creator 는 include 혹은 exclude 요소를 가질 수 있는데 DWR 서비스 빈 객체에서 호출할 수 있는 메소드를 제한하는데 사용할 수 있다.

ApartmentDAO : 쿼리를 가져오는 실제 메소드가 들어있는 클래스
Apartment : id,bedrooms,bathrooms,price,address,city,province를 가진 도메인 객체

search.jsp

·미리보기 | 소스복사·
  1.  <script src='dwr/interface/ApartmentDAO.js'></script>  
  2.  <script src='dwr/engine.js'></script>  
  3.  <script src='dwr/util.js'></script>  
  4. .   
  5. .   
  6. .   
  7.   
  8.  <script language="javascript">  
  9.  function updateTotal() {   
  10.     $("resultTable").style.display = 'none';   
  11.     var bedrooms = document.getElementById("bedrooms").value;   
  12.     var bathrooms = document.getElementById("bathrooms").value;   
  13.     var price = document.getElementById("price").value;   
  14.     ApartmentDAO.countApartments(loadTotal, bedrooms, bathrooms, price);   
  15.  }   
  16.   
  17.  function loadTotal(data) {   
  18.     document.getElementById("totalRecords").innerHTML = data;   
  19.  }   
  20. </script>  
  21. .   
  22. .   
  23. .  
DWR은 클라이언트가 서버단의 서비스 객체를 호출하기 위한 일종의 스텁 스크립트를 자동으로 생성해준다.
dwr/interface/*는 서버단의 서비스 객체를 호출하기 위한 자바스크립트를 만들어주는 URL이다. 그렇기 때문에 ApartmentDAO객체를 클라이언트 쪽에서 사용하기 위해서는 미리 ApartmentDAOrk 정의 되어 있는 자바스크립트를 소스에 포함시켜야 한다.
<script src='dwr/interface/ApartmentDAO.js'></script>
그러면 ApartmentDAO의 메소드를 스크립트 안에서 사용할 수 있다.

ApartmentDAO.countApartments(loadTotal, bedrooms, bathrooms, price);
parameter 중 맨 앞은 countApartment가 수행한 뒤 호출되야 하는 callback 메소드, 그 뒤는 countApartment 메소드의 parameter 이다.
callback 메소드 에서 처리를 할 수 있다.

document.getElementById("totalRecords").innerHTML = data
countApartments 메소드를 수행하고 나온 결과를 totalRecords 라는 태그에 innerHTML로 설정한다.

사용예제 참고사항

  • 사용한 샘플을 돌릴때 에러가 발생하였다.
    다운로드 받은 jw-0620-dwr.war안에 dwr.xml 이
    ·미리보기 | 소스복사·
    1. <dwr>  
    2.     <allow>  
    3.         <convert converter="bean" match="dwr.sample.Apartment"/>  
    4.         <create creator="new" javascript="ApartmentDAO" class="dwr.sample.ApartmentDAO">  
    5.             <include method="findApartments"/>  
    6.             <include method="countApartments"/>  
    7.         </create>  
    8.   </allow>  
    9. </dwr>  

로 되어있다. 하지만 <create/>는 class 를 attribute 로 가지지 않는다. 그래서 에러 발생..

<create creator="new" javascript="ApartmentDAO" class="dwr.sample.ApartmentDAO"> 를
<create creator="new" javascript="ApartmentDAO" >
<param name="class" value="com.tmax.spring.ibatis.ApartmentDAO"/>
</create>

으로 변경한 뒤 정상적으로 수행이 되었다.

수행한 결과

  • 사용예제는 렌트할 아파트를 구하는 예제이다.

원하는 방 갯수, 화장실 갯수, 가격 대를 선택하면 조건에 맞는 아파트의 수가 나오고 show results 라는 버튼을 클릭하면 주소,방갯수,화장 실갯수,가격등의 정보가 조회된다.


만일 예제와 같은 결과를 얻기 위해 DWR 를 이용하지 않았다면 XMLHttpRequest 객체를 얻는 과정부터 소스를 작성했어야 할 것이다.
하지만 DWR을 사용함으로써 이전의 과정은 모두 DWR 에 맡기고 실제 작동하는 서버 클래스 작성, dwr.xml 작성에만 신경을 쓸 수 있게 되었다.

DWR2.0

이전방식

예를 들어
com.tmax.tody.dwr.tody.ProductDwr 클래스가 dwr 에서 사용할 클래스 인 경우
dwr.xml , applicationContext.xml 에 모두 관련 내용을 작성해야 했다.

우선 applicationContext.xml 에 사용하는 클래스에 대한 bean 선언을 해야 한다.
application.xml

·미리보기 | 소스복사·
  1. <bean  
  2.       id="productDwr"  
  3.       class="com.tmax.tody.dwr.tody.ProductDwr"  
  4.   >  
  5.     <property name="moduleService">  
  6.       <ref bean="moduleService"/>  
  7.     </property>  
  8.     <property name="versionService">  
  9.       <ref bean="versionService"/>  
  10.     </property>  
  11.   </bean>  

dwr.xml 에 create 요소의 creator 속성 중 spring 을 이용하여 해당 bean 을 가져다 쓸 수 있도록 선언을 해야 한다.
dwr.xml

·미리보기 | 소스복사·
  1. <create creator="spring" javascript="ProductDwr">    
  2.     <param name="beanName" value="productDwr"/>    
  3. </create>  
  4.   
  5. <convert converter="bean" match="com.tmax.tody.domain.tody.*"/>  

선언을 한 후 실제 사용하는 jsp 에서는

·미리보기 | 소스복사·
  1. <script type='text/javascript' src='dwr/interface/ProductDwr.js'></script>  
  2. <script type='text/javascript' src='dwr/engine.js'></script>  
  3. <script type='text/javascript' src='dwr/util.js'></script>  
  4.   
  5. <script type="text/javascript">  
  6.     function setSubVersion(mainVersionCode, systemCode, userId) {   
  7.       var productCode = $("productCode").value;   
  8.       ProductDwr.findSearchSubVersions(productCode, systemCode, userId, mainVersionCode,listMainVersionProcess);   
  9.     }   
  10. </script>  
  11.   
  12. <select name="mainVersionCode" class="input" onchange="*setSubVersion*   
  13. (this.value, '${sessionScope.currentSystem}', '${sessionScope.user.id}');" style="width:48%;">  
  14.     <option value="">::: 선택 :::</option>  
  15.     <c:if test="${not empty mainVersions}">  
  16.         <c:forEach var="mv" items="${mainVersions}">  
  17.             <option value="${mv.versionCode}" ${(param.mainVersionCode ==  mv.versionCode)? 'selected':''}>${mv.versionName}</option>  
  18.         </c:forEach>  
  19.     </c:if>  
  20. </select>  
  21. <c:choose>  
  22.     <c:when test="${not empty subVersions}">  
  23.         <select name="subVersionCode" class="input" style="width:50%;">  
  24.             <option value="">::: 선택 :::</option>  
  25.             <c:if test="${not empty subVersions}">  
  26.                 <c:forEach var="sv" items="${subVersions}">  
  27.                     <option value="${sv.versionCode}" ${(param.subVersionCode == sv.versionCode)? 'selected':''}>${sv.versionName}</option>  
  28.                 </c:forEach>  
  29.             </c:if>  
  30.         </select>  
  31.     </c:when>  
  32.     <c:otherwise>  
  33.         <select name="subVersionCode" class="input" style="width:50%; display:'none';">  
  34.             <option value="">::: 선택 :::</option>  
  35.         </select>  
  36.     </c:otherwise>  
  37. </c:choose>  

DWR2.0+Spring
DWR2.0과 Spring2.0이 나오면서 Spring의 context.xml에 XML Namespace 형식으로 DWR를 적용할 수 있게 되었다.

applicationContext.xml

·미리보기 | 소스복사·
  1. <beans  
  2.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.    xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"  
  4.    xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.        http://www.springframework.org/schema/beans/spring-beans.xsd   
  6.        http://www.directwebremoting.org/schema/spring-dwr   
  7.        http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">  
  8.           
  9.   
  10.     <dwr:configuration>  
  11.         <dwr:convert match="com.tmax.tody.domain.tody.*" type="bean"/>    
  12.     </dwr:configuration>  
  13.     
  14.     <bean id="productDwr" class="com.tmax.tody.dwr.tody.ProductDwr">  
  15.     <dwr:remote javascript="ProductDwr" />  
  16.          <property name="moduleService">  
  17.         <ref bean="moduleService"/>  
  18.          </property>  
  19.          <property name="versionService">  
  20.         <ref bean="versionService"/>  
  21.          </property>  
  22.     </bean>  

설정 면에서도 간편해져서 사용하기에 좀 더 편리하게 되었다.

이 외에도 DWR2.0 이 되면서 더욱더 많은 장점을 가지게 되었다.
그것은.. http://getahead.org/dwr/changelog/dwr20 을 보면 자세히 나와있다.

util.js, engine.js 에서도 다양한 함수들을 사용할 수 있다.
http://getahead.org/dwr/browser/util


번호 제목 글쓴이 날짜 조회 수
41 GWT-yui-ext Demo 황제낙엽 2009.03.12 24
40 YUI 응용프로그램 만들기 (Writing Your First YUI Application) 황제낙엽 2009.03.12 32
39 MethodChain이란? 황제낙엽 2009.03.12 33
38 DWR2.x 와 Spring2.x에서 설정 황제낙엽 2009.03.12 15
37 [guni] DWR 사용시 Session 값 얻기 황제낙엽 2009.03.12 18
36 [guni] Spring + DWR 을 이용한 Form Submission처리... 황제낙엽 2009.03.12 9
35 [Whiteship's Note] Spring + Ajax with DWR (Revolution) file 황제낙엽 2009.03.12 68
34 [Whiteship's Note] Spring + Ajax with DWR (Coding) file 황제낙엽 2009.03.12 52
33 [Whiteship's Note] Spring + Ajax with DWR 황제낙엽 2009.03.12 24
32 [흰둥이와 백설이] DWR - Reverse Ajax part 2 : Configuring Reverse Ajax 황제낙엽 2009.03.12 39
31 [흰둥이와 백설이] DWR - Reverse Ajax part1 황제낙엽 2009.03.12 31
30 [흰둥이와 백설이] DWR 사용을 위한 web.xml 설정 방법 황제낙엽 2009.03.12 52
29 [흰둥이와 백설이] Overview Of DWR - DWR : JAVA를 위한 쉬운 AJAX 황제낙엽 2009.03.12 18
» Direct Web Remoting 황제낙엽 2009.03.12 28
27 자바스크립트 압축 황제낙엽 2009.03.11 17
26 Ajaxim (웹 인스턴트 메신저), DatePicker (슬라이딩 데이트), Starbox (별점추천 UI 라이브러리), Tablekit (테이블을 데이터 그리드로) 황제낙엽 2009.03.11 78
25 Prototype, Script.aculo.us 스크랩 황제낙엽 2009.03.11 73
24 [펌] 1. Dojo toolkit Example 황제낙엽 2009.03.11 15
23 [펌] 2. Dojo Event Model 황제낙엽 2009.03.11 17
22 [펌] 3. DOJO Built-in Widgets (달력) 황제낙엽 2009.03.11 8