什么是DWR
DWR是一个实现服务端的java代码与浏览器端的javascript交互的java类库,并且能很简单的实现方法的相互调用。
DWR是对ajax的封装,使数据对象类型的传递更丰富。
DWR搭建流程及注意事项
1. 创建web项目DwrMyDemo,导入dwr需要的jar包
dwr.jar,common-logging.jar
2. 在web.xml中配置dwr
<?xml version="1.0"encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<!-- <init-param>-->
<!-- <param-name>crossDomainSessionSecurity</param-name>-->
<!-- <param-value>false</param-value> -->
<!-- </init-param> -->
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</web-app>
3. 在web.xml同级目录下面新增一个dwr.xml配置文件dwr.xml中配置dwr
<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting2.0//EN"
"http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="SelectorDemo">
<param name="class" value="com.project.web.dwr.SelectorDwr"/>
</create>
<convert match="com.project.demo.UserType" converter="bean" javascript="SelectorDemo"/>
<convert match="com.project.demo.User" converter="bean" javascript="SelectorDemo"/>
<create creator="new" javascript="StringUtils">
<param name="class" value="org.apache.commons.lang.StringUtils"/>
</create>
<create creator="new" javascript="DWRUtil">
<param name="class" value="org.directwebremoting.proxy.dwr.Util"/>
</create>
</allow>
</dwr>
注意:
刚开始我从dwr官网上拷贝的shema是
<!DOCTYPE dwr PUBLIC
"-//GetAheadLimited//DTD Direct Web Remoting 3.0//EN"
"http://getahead.org/dwr/dwr30.dtd">
放在这里不能用,要改成:
<!DOCTYPE dwr PUBLIC
"-//GetAheadLimited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.org/dwr/dwr20.dtd">
才能用。因为此shema与我的jar包版本不匹配,我用的是DWR2。
4. 新建一个任意类,新建一些方法。(根据我上面的配置,我建的类是SelectorDwr)
package com.project.web.dwr;
import java.util.ArrayList;
import java.util.List;
importorg.apache.commons.lang.StringUtils;
import com.project.demo.User;
import com.project.demo.UserType;
public class SelectorDwr {
publicList<User> getUserListByType(UserType userType){
List<User>uList = new ArrayList<User>();
Stringtype = userType.getUserType();
if(StringUtils.isNotBlank(type)&& "1".equals(type)){
uList.add(newUser("李明",18,"男"));
uList.add(newUser("韩梅梅",17,"女"));
}
if(StringUtils.isNotBlank(type)&& "2".equals(type)){
uList.add(newUser("闰土",20,"男"));
uList.add(newUser("祥林嫂",48,"女"));
}
System.out.println("userType= "+userType);
returnuList;
}
}
5. 如果还需要新建DWR类,将新建Java类如步骤3一般,配置在dwr.xml文件中。
6. 将项目加载在容器中(如tomcat),启动容器,访问URL:
http://localhost:8080/DwrMyDemo/dwr。
可以看见在dwr中配置的java类出现在浏览器中,点击进入类,可以看到类中可以从浏览器端调用的方法,并可以测试。
7. jsp页面中新增两句几句话,指定dwr的在容器中的名称映射:
<script src="<%=basePath%>dwr/interface/SelectorDemo.js"></script>
<scriptsrc="<%=basePath%>dwr/interface/StringUtils.js"></script>
<scriptsrc="<%=basePath%>dwr/engine.js"></script>
整个index.jsp代码如下:
<%@ pagelanguage="java" import="java.util.*"pageEncoding="UTF-8"%>
<%
Stringpath = request.getContextPath();
StringbasePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">
<title>DWR示例</title>
<meta http-equiv="pragma"content="no-cache">
<meta http-equiv="cache-control"content="no-cache">
<meta http-equiv="expires"content="0">
<meta http-equiv="keywords"content="keyword1,keyword2,keyword3">
<meta http-equiv="description"content="This is my page">
<!--
<link rel="stylesheet"type="text/css" href="styles.css">
-->
<script src="<%=basePath%>dwr/interface/DWRUtil.js"></script>
<scriptsrc="<%=basePath%>dwr/interface/StringUtils.js"></script>
<scriptsrc="<%=basePath%>dwr/interface/SelectorDemo.js"></script>
<scriptsrc="<%=basePath%>dwr/engine.js"></script>
<script type="text/javascript">
functiondwrTest1(){
var utype =document.getElementsByName("u1Type")[0].value;
StringUtils.isBlank(utype,function(date){alert(date);});
}
function dwrText2(){
var uType =document.getElementsByName("u2Type")[0].value;
var typeName = (uType =="2")?"语文书人物":"英文书人物";
var typeObject ={userType:uType,typeName:typeName};
SelectorDemo.getUserListByType(typeObject,dwr2_callback);
}
function dwr2_callback(data){
var selectObj =document.getElementsByName("u2Link")[0];
if(selectObj.options.length>0){
for(vari=0;i<selectObj.options.length;i++){
selectObj.remove(i);
i--;
}
}
var len = data.length;
if(len>0){
for(vari=0;i<len;i++){
var user= data[i];
varsubOption = document.createElement("option");
subOption.value=i;
subOption.text=user.userName
selectObj.appendChild(subOption);
}
}else{
alert("数据为空");
}
}
function linkChange(_self){
alert(_self.value);
}
</script>
</head>
<body>
This is my JSP page. <br>
<input type="text"name="u1Type" /><br><br>
<input type="button"value="测试" onClick="dwrTest1()"/><br><br>
<select name="u2Type"onChange="dwrText2()">
<optionvalue="">请选择</option>
<optionvalue="1">英文书人物</option>
<option value="2">语文书人物</option>
</select>
<br>
<select name="u2Link"onChange="linkChange(this)"></select>
</body>
</html>
8. 如果有需要转换的类,要标明转换类,参数、返回值如果是我们自己建的java类,需要建转换类,在dwr.xml添加语句:
<convert match="com.project.demo.UserType"converter="bean"
javascript="SelectorDemo"/>
<convertmatch="com.project.demo.User" converter="bean"
javascript="SelectorDemo"/>
说明:第一个convert是调用函数的参数类型;第二个convert是调用函数的返回值类型。如果参数或返回值的类型是自定义的,不指定convert类型,DWR不生效。
问题及总结
1. 本测试时基于IE10,IE8下测试有问题。主要是javascript的问题。
2. DWR除了可以在浏览器端调用自定义的java类,还可以调用lib中的类库。如步骤3中定义的dwr.xml文件中就定义了StringUtils.js(来自common-lang.jar)和DWRUtil.js(来自dwr.jar)。本来<select>元素添加删除<option>可以用org.directwebremoting.proxy.dwr.Util类的
dwr.util.addOptions(selectid, data, valueprop, textprop);
dwr.util.removeAllOptions(id);
方法,就不用自动动态创建<option>节点。但是测试结果是“不支持的方法”,可能是浏览器的问题,我没深究。
3. 如果是与spring集成的话,dwr.xml中的配置可写成:
<create creator="spring" javascript="FunctionDao">
<param name="beanName" value="functionDao"/>
</create>
注意属性:creator和name。
4. 实验代码包: