Spring + Ajax with DWR (Revolution)

이전 글의 예제 코드는 DWR을 그대로 사용했을 뿐, Spring은 사용하지 않았습니다. 다시말하면, Spring Container로 부터 bean을 가져온 것이 아니라, new라는 생성기를 사용하여 자바스크립트를 생성했습니다.

스프링 컨테이너가 관리하는 bean으로 자바스크립트를 생성하는 방법은 두 가지가 있습니다.
1. spring 생성기 사용하기.
2. 스프링 설정 파일에서 dwr 네임스페이스 사용하기.(스프링 2.0 이상에서 사용가능)

1. spring 생성기 사용하기.

dwr.xml을 다음과 같이 수정합니다.
new 생성기 대신 spring 생성기 사용하도록 수정.
class 송성 대신 beanName이라는 속성에 bean의 이름을 설정합니다.

<dwr>
    <allow>
        <convert converter=”bean” match=”whiteship.domain.Member” />
        <create creator=”spring” javascript=”MemberService”>
            <param name=”beanName” value=”memberService” />
        </create>
    </allow>
</dwr>

그리고 Spring 설정 파일에 memberService라는 bean을 등록해야겠죠. 이 전 예제에서는 등록하지 않았었습니다.

    <bean id=”memberService” class=”whiteship.service.MemberServiceImpl” />

마지막으로 DWR이 스프링의 설정 파일을 알 수 있도록 설정해야 하는데, 기본으로 ContextLoaderListener를 통해 읽어오려고 합니다. 따라서 web.xml에 다음과 같이 설정되어 있다면, dwr.xml에 별도로 설정해 주지 않아도 됩니다.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/**Context.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

ck130000000001.zip

2. 스프링 설정 파일에서 dwr 네임스페이스 사용하기.

이번에는 dwr.xml 파일 처럼 별도의 DWR 파일을 사용하지 않고, 스프링 설정 파일로만, DWR로 사용할 bean을 지정해 주는 방벙입니다.

먼저, web.xml에서 등록했던 DwrServlet을 DwrSpringServlet으로 변경합니다.(이제 dwr.xml은 삭제해도 됩니다.)
그럼 다음, 스프링 설정 파일에 dwr 네임스페이스를 추가합니다.
마지막으로, 자바스크립트로 노출시킬 bean 내부에 <dwr:remote> 엘리먼트를 사용하여 설정합니다. 그리고 기본 타입이 아닌 데이터를 변환하기 위해 사용했던 convertor를 등록합니다.

    <servlet>
        <servlet-name>dwr</servlet-name>
        <servlet-class>
            org.directwebremoting.spring.DwrSpringServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
    xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
    xmlns:util=”http://www.springframework.org/schema/util”
    xmlns:p=”http://www.springframework.org/schema/p”
    xmlns:aop=”http://www.springframework.org/schema/aop”
    xmlns:tx=”http://www.springframework.org/schema/tx”
    xmlns:lang=”http://www.springframework.org/schema/lang”
    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-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.0.xsd
http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd
    default-autowire=”byName”>

    <bean id=”memberService” class=”whiteship.service.MemberServiceImpl”>
        <dwr:remote javascript=”MemberService” />
    </bean>

    <dwr:configuration>
        <dwr:convert type=”bean” class=”whiteship.domain.Member” />
    </dwr:configuration>

</beans>

ck130000000002.zip
클라이언트 코드는 수정할 것이 없습니다.

이렇게 하면, 스프링의 DI와 AOP를 적용한 자바 객체를 자바스크립트 형태로 변환해주고(DWR이), 이것을 클라이언트 자바스크립트에서 호출할 수 있게 됩니다.

2007/11/08 – [Spring In Action/16. Integrating with other web frameworks] – Spring + Ajax with DWR (Coding)
2007/11/08 – [Spring In Action/16. Integrating with other web frameworks] – Spring + Ajax with DWR

Spring + Ajax with DWR (Coding)

다음의 순서대로 코딩을 할 수 있습니다.(꼭 이 순서를 지켜야 하는 것은 아닙니다.)

0. POJO로 Ajax (자바스크립트로 노출시킬) 서비스 구현.
1. web.xml에 DWR Servlet 등록하기.
2. dwr.xml 작성하기.
3. 클라이언트 코드 작성하기.
    3-1. 자바스크립트 등록하기.
    3-2. 요청하기.
    3-3. 요청 처리하기.

0. POJO로 Ajax (자바스크립트로 노출시킬) 서비스 구현.
사용자 삽입 이미지매우 단순하게 구현했으며, MemberService 인터페이스에서는 Member의 이름으로 회원을 검색하여 결과를 리스트 형태로 반환하는 메소드를 가지고 있습니다.

1. web.xml에 DWR Servlet 등록하기.

web.xml에 다음과 같은 코드를 추가합니다.

    <servlet>
        <servlet-name>dwr</servlet-name>
        <servlet-class>
            org.directwebremoting.servlet.DwrServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dwr</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>

/dwr/ 로 시작하는 모든 요청을 DwrServlet이 처리하도록 설정하였습니다.

2. dwr.xml 작성하기.

WEB-INF/ 폴더에 dwr.xml 파일을 다음과 같이 작성합니다.

<!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=”whiteship.domain.Member” />
        <create creator=”new” javascript=”MemberService”>
            <param name=”class”
                value=”whiteship.service.MemberServiceImpl” />
        </create>
    </allow>
</dwr>

Member 타입으로 캐스팅 할 수 있도록, converter를 등록해줍니다.
new 생성기를 사용하여, MemberService라는 이름의 자바스크립트를 생성합니다. 이 자바스크립트는 MemberServiceImpl 자바 클래스를 가지고 작성합니다.

=================================================================================
이제 서버쪽에서 설정해야 할 내용은 끝입니다. 이것으로 클라이언트 쪽에서 자바 객체의 메소드를 자바스크립트에서 호출할 수 있습니다. 어떻게 호출하는지 살펴보겠습니다.

3. 클라이언트 코드 작성하기.

3-1. 자바스크립트 등록하기.

View에서 사용할 자바스크립트를 등록합니다.

<script type=’text/javascript’ src=’dwr/engine.js’></script>
<script type=’text/javascript’ src=’dwr/interface/MemberService.js’></script>
<script type=’text/javascript’ src=’dwr/util.js’></script>

맨 아래 한 줄은 옵션입니다. 위의 두 줄은 필수이며, 위의 자바스크립트 파일들이 없다고 걱정하시지 않아도 됩니다. web.xml에서 설정한 dwr/ 경로를 통해 DwrServlet이 알아서 처리할 것입니다.

두 번째 자바스크립트 파일의 이름은 dwr.xml에서 자바 클래스를 자바스크립트로 변환할 때 사용하기로 한 이름으로 설정해주시면 됩니다.

3-2. 요청하기.

폼에서 다음과 같은 input 엘리먼트가 있고, 해당 엘리먼트에서 자바스크립트를 호출합니다.

<form name=”memberForm”>
    <input type=”text” name=”name” maxlength=”10″ onkeyup=”inputChanged();” />
</form>

function inputChanged() {
    var name = document.memberForm.name.value;
    if(name.length > 1) {
        MemberService.get(name, updateTable);
    } else {
        DWRUtil.removeAllRows(“memberTable”);
    }
}

3-3. 요청 처리하기.

위의 자바스크립트에서 updateTable이 바로 요청의 결과를 처리할 자바스크립트 입니다. 다음과 같이 작성합니다.

function updateTable(results) {
    DWRUtil.removeAllRows(“memberTable”);
    DWRUtil.addRows(“memberTable”, results, cellFuncs);
}

var cellFuncs = [
    function(data) { return data.name; },
    function(data) { return data.email; }
];

요청의 결과를 가져와서 테이블을 채워줄 때 해당 데이터에서 어떤 필드로 테이블을 채워야 하는지 정의하기 위해 cellFuncs 라는 구조체(?)를 정의해 주었습니다.

ck130000000000.zip참조 : Spring In Action 16장

Spring + Ajax with DWR

DWR은 Direct Web Remoting의 약어로 자바 객체를 기반으로 자바스크립트 코드를 생성하여, 클라이언트 자바스크립트에서 (생성한 자바스크립트를 사용하여) 서버쪽 자바 객체의 메소드를 호출할 수 있도록 해주는 프레임워크입니다.

수많은 Ajax 프레임워크 중에서 DWR이 Spring와 밀접한 관계가 된 것은 DWR 자체에서 Spring을 지원하는 기능을 구현했기 때문입니다. 따라서 매우 간단하게 Spring와 연동하여 사용할 수 있습니다. 연동한다는 의미를 좀 더 구체적으로 서술하면, Spring Container가 관리하는 bean을 DWR을 사용하여 자바스크립트로 노출시킬 수 있다는 것입니다.

Spring MVC를 사용하든, Spring Web Flow를 사용하든 관계가 없습니다. 어차피 요청은 자바스크립트에서 할 것이고, 이 요청을 처리하는 녀석은 DWR Servlet이지, Spring의 Dispatcher Servlet이 아닙니다. 특정 요청들을 한 곳으로 집중한다는 측면에서 둘은 비슷하지만, View Resolving, Hadler Mapping 까지 관장하는 Spring의 Dispatcher Servlet과는 전혀 다른 일을 합니다. DWR Servlet에 등록되어 있는 자바 객체를 바탕으로 요청을 처리할 자바스크립 코드를 생성하고, 그것으로 처리한 결과를 다시 (클라이언트)웹브라우저에게 돌려주는 역할을 합니다.

사용자 삽입 이미지
클라이언트 자바스크립트에서 특정 요청을 호출하면, 해당 요청을 Dwr Servlet이 받아들이고, Dwr Servlet은 drm.xml에 설정된 정보를 바탕으로 해당 요청을 처리할 자바 객체의 자바스크립트(DWR이 알아서 생성합니다.)를 호출하고 그 결과를 다시 돌려주게 됩니다. 그럼 돌려받은 정보로 비동기식으로 화면에 보여주는 것은 클라이언트쪽에서 알아서 하겠죠.

위 그림에서 Spring이 낑겨들어가는 쪽은 바로 녹색 네모 둘을 연결한 빨간 선입니다. creator는 자바스크립트 생성기를 말하는데, 자바스크립트 코드로 생성할 자바 객체를 지정해 주는데, 이 객체를 Spring Container에 있는 bean을 가져와서 생성할 수 있도록 설정할 수 있습니다.

왜? 스프링 컨테이너가 관리하는 bean으로 설정하려고 할까요? 스프링이 제공하는 DI와 AOP와 같은 기능을 사용할 수 있기 때문입니다. 그런 기능들을 사용하지 못한다면, 자바스크립트로 노출하고 싶어하는 자바 객체 내부에 해당 객체가 필요로 하는 모든 것들이 들어있어야합니다.(new를 많이 사용해서 코딩했겠죠.) 스프링을 사용한다면, 그럴 필요가 없어집니다. 이 말은 더욱 유연하고 유지관리하기 편리한 객체를 자바스크립트로 노출 시킬 수 있다는 뜻입니다.

설명은 이만하고, 다음 글에서 코딩을 해보겠습니다.