DWR

Programming/DWR 2007.11.26 14:33

원본글 : http://wiki.javajigi.net/display/WEB20/dwr


Direct Web Remoting

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

<servlet>
        <servlet-name>dwr-invoker</servlet-name>
        <display-name>DWR Servlet</display-name>
        <description>Direct Web Remoter Servlet</description>
        <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
        <init-param>
             <param-name>debug</param-name>
             <param-value>true</param-value>
        </init-param>
</servlet>
        
<servlet-mapping>
        <servlet-name>dwr-invoker</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

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

dwr.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
  <allow>
        <convert converter="bean" match="com.tmax.spring.domain.Apartment"/>
        <create creator="new" javascript="ApartmentDAO" >
          <param name="class" value="com.tmax.spring.ibatis.ApartmentDAO"/>
           <include method="findApartments"/>
            <include method="countApartments"/>
        </create>
  </allow>
</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

 <script src='dwr/interface/ApartmentDAO.js'></script>
 <script src='dwr/engine.js'></script>
 <script src='dwr/util.js'></script>
.
.
.

 <script language="javascript">
 function updateTotal() {
    $("resultTable").style.display = 'none';
    var bedrooms = document.getElementById("bedrooms").value;
    var bathrooms = document.getElementById("bathrooms").value;
    var price = document.getElementById("price").value;
    ApartmentDAO.countApartments(loadTotal, bedrooms, bathrooms, price);
 }

 function loadTotal(data) {
    document.getElementById("totalRecords").innerHTML = data;
 }
</script>
.
.
.

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 이
    <dwr>
        <allow>
            <convert converter="bean" match="dwr.sample.Apartment"/>
            <create creator="new" javascript="ApartmentDAO" class="dwr.sample.ApartmentDAO">
                <include method="findApartments"/>
                <include method="countApartments"/>
            </create>
      </allow>
    </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

<bean
      id="productDwr"
      class="com.tmax.tody.dwr.tody.ProductDwr"
  >
    <property name="moduleService">
      <ref bean="moduleService"/>
    </property>
    <property name="versionService">
      <ref bean="versionService"/>
    </property>
  </bean>

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

   <create creator="spring" javascript="ProductDwr"> 
                <param name="beanName" value="productDwr"/> 
   </create>

   <convert converter="bean" match="com.tmax.tody.domain.tody.*"/>

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

<script type='text/javascript' src='dwr/interface/ProductDwr.js'></script>
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>

<script type="text/javascript">
    function setSubVersion(mainVersionCode, systemCode, userId) {
      var productCode = $("productCode").value;
      ProductDwr.findSearchSubVersions(productCode, systemCode, userId, mainVersionCode,listMainVersionProcess);
    }
</script>

<select name="mainVersionCode" class="input" onchange="*setSubVersion*
(this.value, '${sessionScope.currentSystem}', '${sessionScope.user.id}');" style="width:48%;">
        <option value="">::: 선택 :::</option>
        <c:if test="${not empty mainVersions}">
                <c:forEach var="mv" items="${mainVersions}">
                        <option value="${mv.versionCode}" ${(param.mainVersionCode ==  mv.versionCode)? 'selected':''}>${mv.versionName}</option>
                </c:forEach>
        </c:if>
</select>
<c:choose>
        <c:when test="${not empty subVersions}">
                <select name="subVersionCode" class="input" style="width:50%;">
                        <option value="">::: 선택 :::</option>
                        <c:if test="${not empty subVersions}">
                                <c:forEach var="sv" items="${subVersions}">
                                        <option value="${sv.versionCode}" ${(param.subVersionCode == sv.versionCode)? 'selected':''}>${sv.versionName}</option>
                                </c:forEach>
                        </c:if>
                </select>
        </c:when>
        <c:otherwise>
                <select name="subVersionCode" class="input" style="width:50%; display:'none';">
                        <option value="">::: 선택 :::</option>
                </select>
        </c:otherwise>
</c:choose>

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

applicationContext.xml

<beans
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.directwebremoting.org/schema/spring-dwr
       http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">
       

    <dwr:configuration>
        <dwr:convert match="com.tmax.tody.domain.tody.*" type="bean"/> 
    </dwr:configuration>
 
    <bean id="productDwr" class="com.tmax.tody.dwr.tody.ProductDwr">
        <dwr:remote javascript="ProductDwr" />
             <property name="moduleService">
                <ref bean="moduleService"/>
             </property>
             <property name="versionService">
                <ref bean="versionService"/>
             </property>
    </bean>

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

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

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


참고할 링크

  1.  http://blog.empas.com/acher00/12704857
  2. http://wiki.javajigi.net/display/WEB20/Direct+Web+Remoting#DirectWebRemoting-DWR%EC%9D%80%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0%2C%EC%99%9CDWR%EC%9D%B8%EA%B0%80%3F
  3. http://getahead.org/dwr 


이 글은 스프링노트에서 작성되었습니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programming > DWR' 카테고리의 다른 글

URL Validation  (0) 2008.01.02
DWR에서 여러개의 Converter 설정하기  (0) 2007.11.26
DWR  (0) 2007.11.26

[DIY스킨] 움직이는 사이드바

Infomation/Computer 2007.06.20 08:00
네이버 블로그에서 티스토리로 이사중에 티스토리의 스킨의 모든 코드를 내마음데로 바꿀수도 있다는것을 알았다. 이런이런 또 발동이다.
남들과 같은것은 참을수 없는 나의 성격. 뭔가 하나라도 남들과는 달라보여야 한다.!!
디자인이 안되면 기술로 승부하자!

그 첫손질로 오른쪽에 위치한

사이드바의 위치를 드래그 & 드랍으로 마음껏 위치이동하고 싶다.

사용자 삽입 이미지

옮기고 싶은 사이드바



그래서 눈을 부릅뜨고 아래 소스코드를 열심히 뒤지다가 눈깔이 빠질까 두려워 좀 편리한 도구를 쓰기로 결심한다.
사용자 삽입 이미지

[관리메뉴의 스킨>스킨선택>편집하기를 누르면 위와같은 스킨의 소스 편집창이 보인다.]

그 편리한 삽질도구의 선두주자 두명을 소개하고자 한다. 그 첫째는 MS에서 제공하는 IEDevToolBar
불여우(FireFox - 이하 파폭)의 플러그인중 하나인 Firbug (동영상).
그중 나는 주로 Firebug를 사용한다. 왠지 더 편하다.-_-;

파폭에서 F12를 눌러 firbug를 Enable시킨 후 Inspect를 클릭하고 화면에 커서를 가져가면 각각의 요소에대한 태그 정보가 적나라하게 나타난다.
사용자 삽입 이미지

파폭의 firebug 실행화면



찾았다. 사이드바의 <div>태그의 id는....sidebar...-_-a
조금 허무하다..;

아무튼 목적하는바를 달성했으니 step2로 gogo싱~

step2. 이제 핵심 소스를 포함시킬 차례다.

invalid-file

자바스크립트 소스

이 블로그에 포함시키는 소스는 최범균씨가 쓴 AJAX PROGRAMMING 기초부터 중급까지라는 책에서 소스를 조금 얻어서 사용했음을 밝힌다. 또한 내 나름데로 수정도 많이 가해졌다.
마음껏 가져가서 사용해도 무방하지만 출처를 속이지는 말길 바란다.^-^*


자 이제 스킨편집창으로 돌아가서. *skin.html 영역의 스킨을 자세히 보면 <head>...</head>이라는 부분이 보인다. 이 헤드 태그 사이에 자바스크립트를 삽입해야 한다. 위 소스코드를 다운로드 받아서 노트패드나 editplus등등의 편집기를 이용해서 열어보면 어지러운  자바스크립트가 보인다.
여기서 수정해야 할 부분은 아랫부분이다.

window.onload=function(){
        var drag1=new ajax.dnd.SimpleDragSource("sidebar");
}

소스코드의 제일 아랫부분에 위 코드가 위치한다.
위에서 단지 고칠곳은 "sidebar" 이곳.
이곳에 setp1에서 찾은 사이드바의 div id를 넣어준 후
 소스를 스윽~긁어서 복사한다. 그리고 스킨편집창의 *skin.html에서 </head> 태그 바로 윗줄에 붙여넣기 하자.

다.됬.다!

이제 한번 저장하기를 누른후 블로그로 돌아가서 마우스를 꾹~누지르고 이동해보자!!
오오~~사이드바가 움직이는게 보이시는가~!+_+

그런데 이런 뭔가 좀 이상하다....

그렇다. 마우스 커서가 화살표 모양이다. 보통 창을 움직이는것을 뜻하는 마우스 포인터는 십자가 모양이지 않은가?? 이건 딱 이렇다고 정해진것은 아니나... 오래전부터 MS의 빌아저씨가 그렇게 만들었으므로 우리의 뇌릿속엔 이미 이렇게 박혀있다.

step3. 마우스 커서의 스타일을 한번 병경시켜보자.

다시 스킨편집 페이지로 돌아가자. 그리고 편집창에서 소스코드를 눈 부릅뜨고 잘 찾아보자~라고 무식한 방법 쓰지 말고..;;
Ctrl+F를 누르면 글자를 찾을수 있으니 이것을 이용하여 sidebar div를 찾아보자.
이런한 태그가 보이는가~?
<div id ="sidebar" style="cursor:move">
......
</div>


div태그 옆에 빨간 글씨의 속성을 지정해주면 마우스커서가 십자가 모양으로 변할것이니~~

다음시간에는 큰 사진도 문제 없다! 메인창 넓이를 마음데로! 라는 주제로 글을 써볼까 합니다.
특시 사진을 즐겨 찍으시는 분들...
큰사진을 올리면 사진이 사이드가 잘려버리는 큰 사태가 발생하여 2단 스킨만을 사용하고 계신분들을 위해..
이런분들도 3단 스킨을 맘놓고 편히 사용하라는 뜻에서 적어보고자 합니다.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Infomation > Computer' 카테고리의 다른 글

누구냐 넌?  (6) 2007.12.08
블로그에 MSN메신저 달기  (1) 2007.12.07
[flickr] 플리커와 테터툴즈 연동!!  (0) 2007.12.02
[DIY스킨] 움직이는 사이드바  (2) 2007.06.20


티스토리 툴바