W2U開発wiki - DWRとSpringの連携


今回の目標

  • SpringとDWRを連携させる。
  • Springアノテーション、DWRアノテーションを使う。

  • 開発環境構築まではSpringDWRのページ参照。

検証環境作成

設定ファイル

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">
<!-- 省略 -->
	<!-- Spring設定 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/application.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- ▼DWR設定 -->
	<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>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dwr</servlet-name>
		<url-pattern>/dwr/*</url-pattern>
	</servlet-mapping>
	<!-- ▲DWR設定 -->
<!-- 省略 -->
</web-app>
Bean定義ファイル(application.xml)
  • Springアノテーションの使用のweb.xmlに★の行を追加する。
  • <dwr:annotation-scan base-package="************"/>で指定したパッケージ以下でDWRのアノテーションが有効になる。
<?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:context="http://www.springframework.org/schema/context"
★	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.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd
★	http://www.directwebremoting.org/schema/spring-dwr
★	http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd
	">
	<!-- Springアノテーションを有効にする -->
	<context:component-scan base-package="jp.holenews.w2u.test2.service"/>
	<!-- プロパティファイルを認識させる -->
	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
		<list>
			<value>classpath:config.properties</value>
		</list>
		</property>
	</bean>
★	<!-- DWRアノテーションを有効にする -->
★	<dwr:annotation-scan base-package="jp.holenews.w2u.test2"/>

</beans>
プロパティファイル(config.properties)
### テスト ###
cat.name=ミミ
cat.message=にゃーん
cat.age=5

プログラムソース

TestDwrController.java
  • JavaScript側から呼べるようにするクラス
  • Bean定義ファイルの「<dwr:annotation-scan base-package="***">」で指定したパッケージ以下に置く。
  • @RemoteProxy(creator = SpringCreator.class)をクラス名につけることで、インスタンスをSpringが生成してくれる。
  • @Autowiredをつけたフィールドに、同じ型名のクラスをSpringがインジェクションしてくれる。→Springアノテーションの使用
  • @RemoteMethodをつけたメソッドをJavaScriptが呼ぶことができる。引数・返り値がプリミティブ型以外のときは、その型もDWRに登録する必要がある。(後述)
package jp.holenews.w2u.test2.controller;
import org.directwebremoting.annotations.*;
import org.directwebremoting.spring.SpringCreator;
import org.springframework.beans.factory.annotation.Autowired;
import jp.holenews.w2u.test2.bean.CatDto;
import jp.holenews.w2u.test2.service.*;
/**
 * DWRがこのコントローラを呼び出す
 */
@RemoteProxy(creator = SpringCreator.class)
public class TestDwrController {
	
	/**
	 * Service層の処理(Springによりインジェクションされる)
	 */
	@Autowired
	private TestSpringService testSpringService;
	
	/**
	 * Service層の処理から猫情報を取得する
	 * @param count 鳴き声の繰り返し回数
	 * @return 猫情報
	 */
	@RemoteMethod
	public CatDto callCat(int count){
		// 鳴き声の繰り返し回数を指定して、猫情報をJavaScriptに返す
		return testSpringService.getCatDto(count);
	}

        // (略)testSpringServiceのgetter, setter
}
TestSpringService.java
  • TestDwrControllerから呼び出される処理。getCatDtoメソッドは、引数の数だけ猫の鳴き声が増える。
  • ※DWRのアノテーションは使っていない。
  • @Value("${プロパティのキー}")でプロパティファイルの値を取得できる。
package jp.holenews.w2u.test2.service;
import jp.holenews.w2u.test2.bean.CatDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * Springによって管理される
 */
@Component
public class TestSpringService {
	
	@Value("${cat.name}")
	private String catName;		// プロパティファイルから猫の名前を取得
	
	@Value("${cat.message}")
	private String catMessage;	// プロパティファイルから猫の鳴き声を取得
	
	@Value("${cat.age}")
	private int catAge;			// プロパティファイルから猫の年齢を取得
	
	/**
	 * 猫情報を作成して返す
	 * @param count 鳴き声の繰り返し回数
	 * @return 猫情報
	 */
	public CatDto getCatDto(int count){
		CatDto catDto = new CatDto();
		catDto.setName(this.catName); // 名前設定
		catDto.setAge(this.catAge);   // 年齢設定
		// 繰り返し回数分鳴き声を追加
		String message = "";
		for(int i = 0; i < count; i++){
			message += catMessage;
		}
		catDto.setMessage(message);   // 鳴き声設定
		
		return catDto;
	}
	
	// (略) catName, catMessage, catAgeのsetter
}
CatDto.java
  • JavaScript側とやり取りするためのデータ保持クラス。(DTO→DataTransferObject)
  • クラス名の前に@DataTransferObjectを、記述することでDWRに登録される。
  • JavaScript側で参照できるフィールドに@RemotePropertyをつける。
package jp.holenews.w2u.test2.bean;
import org.directwebremoting.annotations.*;
/**
 * 猫情報を持つDTO
 */
@DataTransferObject
public class CatDto {
	// 名前
	@RemoteProperty
	private String name;
	// 鳴き声
	@RemoteProperty
	private String message;
	// 年
	@RemoteProperty
	private int age;

	//(略) name, message, ageのsetter, getter
}
test.html
  • 鳴く回数をドロップダウンリストで選択し、「猫を呼ぶ」ボタンを押すとサーバーと通信する。
  • /dwr/engine.jsは必須。「/dwr/interface/・・・」に呼び出したいクラスの名前を書く。
  • 上記のjsファイルはhttp://サーバ名/アプリ名/dwr/の位置にあるので、<script>タグでのパスは環境に合わせて変更する。
<!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">
<script src="../dwr/engine.js"></script>
<script src="../dwr/interface/TestDwrController.js"></script>
<script type="text/javascript">
// 猫を呼ぶボタンクリック時
function onClick(){
	// 鳴き声繰り返し回数
	var count = parseInt(document.getElementById("callCount").value);
	// TestDwrControlerクラスのcallCatメソッドを呼ぶ
	TestDwrController.callCat(
		count,{
	        callback: _callBackCat, // コールバック処理
	        errorHandler: onError   // エラー時の処理
	    }
	);
}
// 通信後のコールバック処理
function _callBackCat(catData){
	// 猫の名前・年齢・鳴き声を表示する
	alert(catData.name + "(" + catData.age + "才)" + "「" + catData.message + "」");
}
// エラー時の処理
function onError(){
	alert("ERROR!");
}
</script>
<title>Insert title here</title>
</head>
<body onload="onload()">
鳴く回数
<select id="callCount">
	<option>1</option>
	<option>2</option>
	<option>3</option>
</select>
<input type="button" value="猫を呼ぶ" onClick="onClick()"/>
</body>
</html>

結果確認

  • サーバー側のプロパティファイルの値が取れている。
  • 鳴き声がクライアント側で指定した回数分繰り返されている。

その他・備考

  • web.xmlのdebugパラメータをtrueにした状態でhttp://サーバ名/アプリ名/dwr/を開くと、DWRに登録されているクラス一覧と、メソッドの公開状態が確認できる。
    • 非公開のメソッドはメソッド名の下に赤文字でメッセージが入る。
  • Springにまかせるのでdwr.xmlは不要。