서버사이드 기능은 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 응답