2010년 8월 30일 월요일

Spring에서 DWR 사용하기

DWR(Direct Web Remoting)은 일반 서비스를 Ajax 형태로 제공할 수 있도록 자동 변환해주는 기능을 제공한다.
서버사이드 기능은 DwrServlet에서 처리되고, 클라이언트 기능은 자동 생성되는 자바 스크립트에서 대부분의 기능이 구현된다.

TrafficInfo(도메인객체)를 리턴하는 검색 기능을 제공하는 TrafficService 가 있다고 가정하자
TrafficService를 DWR을 이용하여 개발하는 예제를 살펴보도록 하자.

TrafficInfo.java - 도메인 객체
package com.roadrantz.traffic;

public class TrafficInfo {

  private String summary;
  private String details;
  public TrafficInfo() {
    super();
  }
  public String getSummary() {
    return summary;
  }
  public void setSummary(String summary) {
    this.summary = summary;
  }
  public String getDetails() {
    return details;
  }
  public void setDetails(String details) {
    this.details = details;
  }
}


TrafficService.java - 서비스 인터페이스
package com.roadrantz.traffic;

public interface TrafficService {

  TrafficInfo[] getTrafficInfo(String zipCode, int zoom, int severity);
}


TrafficServiceImpl.java - 서비스 구현클래스
package com.roadrantz.traffic;

public class TrafficServiceImpl implements TrafficService {
  private String appId = "springinaction";
    
  public TrafficServiceImpl() {
    super();
  }

  public String getAppId() {
    return appId;
  }

  public void setAppId(String appId) {
    this.appId = appId;
  }

  @Override
  public TrafficInfo[] getTrafficInfo(String zipCode, int zoom, int severity) {
    try {
      TrafficInfo[] trafficInfo = new TrafficInfo[2];
      
      trafficInfo[0] = new TrafficInfo();
      trafficInfo[0].setSummary("summary 1");
      trafficInfo[0].setDetails("detail 1");
      
      trafficInfo[1] = new TrafficInfo();
      trafficInfo[1].setSummary("summary 2");
      trafficInfo[1].setDetails("detail 2");
      
      return trafficInfo;

    } catch(Exception e) {
      e.printStackTrace(System.out);
      return new TrafficInfo[] {};
    }
  }
}


위의 세 클래스는 보통 스프링에서 서비스를 개발하는 것과 다를게 없다.
이렇게 개발된 서비스를 별도의 컨트롤러나 Restful 개발 프레임웍을 사용하지 않고
AJAX 형태로 서비스를 제공하는 방법을 살펴보자.

먼저 WEB-INF에 web.xml 파일과 dwr.xml파일을 작성해 주어야 한다.

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>simple-dwr-project</display-name>
  
  <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>

</web-app>

/dwr/* 으로 요청된 모든 URL을 DwrServlet이 처리되도록 서블릿을 설정한 예제다.
URL 패턴은 개발환경에 맞게 설정하면된다.

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 match="com.roadrantz.traffic.TrafficInfo" converter="bean"></convert>
    <create javascript="Traffic" creator="new">
      <param name="class" value="com.roadrantz.traffic.TrafficServiceImpl"></param>
      <exclude method="setAppId"/>
      <exclude method="getAppId"/>
    </create>
  </allow>
</dwr>  

위의 설정파일은 TrafficInfo 서비스를 DWR을 이용하여 Ajax로 서비스를 제공할 수 있도록 한다.
서비스와 무관한 setAppId와 getAppId는 ajax서비스에서 배제시킨다.

아래의 소스는 JSP파일에서 JavaScript를 이용해서 DWR 서비스를 호출하는 예제다.
실제로 DWR서비스를 호출하여 패킷을 살펴보면 Json 포맷의 응답이 전달되는 것을 확인할 수 있다.

아래의 예제는 zipCode가 5자리가 될 때 DWR서비스를 호출하는 예제다.
아래의 소스에서 주의깊게 살펴볼 부분은
스크립트 파일을 include하는 부분과 cellFuncs 부분이다.

dwr/engine.js 파일과 dwr/util.js 파일은 DWR에서 공통적으로 제공하는 파일들이고,
dwr/interface/Traffic.js는 TrafficService를 호출하기 위해서 DWR이 생성한 스크립트 파일이다.

cellFuncs는 AJAX로 호출한 결과를 Table의 TD로 설정해 주는 역할을 한다.


샘플 Jsp 파일
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>DWR Sample</title>

<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/interface/Traffic.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>

<script type="text/javascript">

function criteriaChanged() {
  var zipCode = document.trafficForm.zip.value;
  var zoom = document.trafficForm.zoom.value;
  var severity = document.trafficForm.severity.value;

  if(zipCode.length == 5) {
    Traffic.getTrafficInfo(zipCode, zoom, severity, updateTable);
  } else {
    DWRUtil.removeAllRows("trafficTable");
  }
}

var cellFuncs = [
                 function(data) {
                     var cb = document.createElement("input");
                     cb.type = "checkbox";
                     return cb; 
                 },
                 function(data) { return data.summary; },
                 function(data) { return data.details; }
                 ];

function updateTable(results) {
  //alert(results);
  DWRUtil.removeAllRows("trafficTable");
  DWRUtil.addRows("trafficTable", results, cellFuncs);
}


</script>

</head>
<body>

<form name="trafficForm">
<table>
  <tr>
    <td>zip</td>
    <td><input type="text" name="zip" onkeyup="criteriaChanged();"/> </td>
  </tr>
  <tr>
    <td>zoom</td>
    <td><input type="text" name="zoom" onkeyup="criteriaChanged();"/> </td>
  </tr>
  <tr>
    <td>severity</td>
    <td><input type="text" name="severity" onkeyup="criteriaChanged();"/> </td>
  </tr>
  
</table>
</form>

<table width="100%" border="1">
  <thead>
    <tr>
      <td>S</td>
      <td width="100">Summary</td>
      <td>Details</td>
    </tr>
  </thead>
  <tbody id="trafficTable">
  </tbody>
</table>
</body>
</html> 
 
 
 

 

DWR요청













DWR 응답

댓글 없음:

댓글 쓰기