DWR(Direct Web Remoting)
DWR采取了一个类似AJAX的新方法来动态生成基于JAVA类的JavaScript代码。
这样WEB开发人员就可以在JavaScript里使用Java代码,就像它们是浏览器的本地代码(客户端代码)一样;
package com.qingyuan.huake;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DwrDill {
public static String getTime(){
Date date = new Date();
Format frm = new SimpleDateFormat("yyyyMMddHHmmss");
String nowTime = frm.format(date);
String year = nowTime.substring(0,4) + "年";
String month = nowTime.substring(4,6) + "月";
String day = nowTime.substring(6,8) + "日";
String hour = nowTime.substring(8,10) + ":";
String minue = nowTime.substring(10,12) + ":";
String second = nowTime.substring(12,14);
return year + month + day + hour + minue + second;
}
public static String sayHi(){
return "Bonjour, monsieur, comment allez-vous? ";
}
public static String sayBye(String name){
return "Au revoir. monsieur" + name;
}
}
web.xml文件
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<!-- 类名在jar包相关类拷贝过来 -->
<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>
<init-param>
<param-name>allowScriptTagRemoting</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
WEB-INF目录下新建一个dwr.xml文件,并对其进行如下配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<create javascript="france" creator="none">
<param name="class" value="com.qingyuan.huake.DwrDill" />
</create>
</allow>
</dwr>
dwr配置属性参考:
creator属性 是必须的 - 它用来指定使用那种创造器。
默认情况下DWR1.1有8种创造器。它们是:
•new: 用Java的new关键字创造对象
•none: 它不创建对象
•scripted: 通过BSF使用脚本语言创建对象
•spring: 通过Spring框架访问Bean
•jsf: 使用JSF的Bean
•struts: 使用Struts的FormBean
•pageflow: 访问Beehive或Weblogic的PageFlow
javascript属性 用于指定浏览器中这个被创造出来的对象的名字。注意不能使用Javascript的关键字
param元素 被用来指定创造器的其他参数
param元素中value属性的值是所要调用的类的url,即类所在的路径
先将项目部署好,然后在浏览器中访问以下地址:http://localhost:8080/dwr/dwr
注:我的Tomcat端口是8080,项目名是dwr
这时候会进入到http://localhost:8080/dwr/dwr/index.html这个地址,接下来是将这个页面上的超链接点开,下面是该页面顶部的部分信息,你需将页面上与js连接相关的代码拷贝下来以备后用。
jsp文件:<注意要对js的回调函数有比较深刻的认识>
<span style="font-size:18px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
</span>
<span style="font-size:18px;"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</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">
<script type='text/javascript' src='/dwr/dwr/interface/france.js'></script>
<script type='text/javascript' src='/dwr/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr/dwr/util.js'></script>
<script type="text/javascript">
function sayHi(){
france.sayHi(function(data){
document.getElementById("msg").innerHTML = "<HR><font color='red'>" + data + "</font><BR>";
});
}
function sayBye(){
var uname = document.getElementById("username").value;
france.getTime(function(time){
france.sayBye(uname,{callback:function(hiName){
document.getElementById("msg").innerHTML = "<HR><BR>" + hiName + "<BR>" + time;
}
});
});
}
</script>
</head>
<body>
name:
<input type="text" id="username">
<input type="button" οnclick="sayHi();" value="问好"/>
<input type="button" οnclick="sayBye();" value="道别"/>
<br>
<div id="msg"></div>
</body>
</html></span>
后话
需要补充说明一下的是,需要连接的js脚本除了像上面那种通过访问拷贝得到之外,你也可以自己来写,注意,是只需要写js的链接代码就行了,源码是由dwr框架提供的,不需要你自己来写的。其中有两个js脚本是不能少的:
<script type='text/javascript' src='/DWR/dwr/engine.js'></script>
<script type='text/javascript' src='/DWR/dwr/util.js'></script>
另外的js脚本,是根据dwr.xml配置文件中的javascript属性的值来确认的,比如我在我的dwr.xml文件中配置的是javascript="france",因此,我需要连接的js就是:
<script type='text/javascript' src='/dwr/dwr/interface/france.js'></script>
同时dwr.xml文件中配置的javascript属性的值(我这里配置的是javascript="france")france其实就是一个java类生成的对象,通过该对象,我们可以在js中直接访问运行在服务器端
的java类中的方法
设置dwr的回调函数是异步还是同步 dwr的回调函数的执行默认是异步的,即在调用dwr函数以后,
如果后面还有js语句,会立刻执行其后的js语句,不会等待dwr函数的回调函数执行完后才去执行
其后的js语句。
现在,我们可以通过设置dwr让其同步执行,即做完回调函数以后,再继续执行其后的js。
同步执行设置语句:
dwr.engine.setAsync(false);
用完某个调用以后,最好还是返回原来的异步执行:
dwr.engine.setAsync(false);
例子:
function check(id,index){
.....................
if(masterConfId == ""){
var confID = document.getElementById("confID").value;
dwr.engine.setAsync(false);
McuHelpDwrMethod.getCasList(idipArray[0],confID,callback);
dwr.engine.setAsync(true);
//执行完dwr回调函数以后,才开始执行这句话.
dwr.util.addOptions('setScreenOneSec'+indexs, data4, "id", "name");
..............
}
function callback(lst){
dwr.util.addOptions('setScreenOneSec'+indexs, data3, "id", "name");
dwr.util.addOptions('setScreenOneSec'+indexs, data5, "id", "name");
dwr.util.addOptions('setScreenOneSec'+indexs, lst, 'mcu_participant_id', 'mcu_participant_name');
}
[可参考DWR.util.js工具包的使用]
<script type='text/javascript' src='/dwr/dwr/engine.js'></script>
<script type='text/javascript' src='/dwr/dwr/util.js'></script>
getText()作用于select lists。
getValue[s]()、setValue[s]()作用于除tables、lists和images以外的大多数html元素
addRows()和removeAllRows()用于编辑tables
addOptions()和removeAllOptions()用于编辑lists(如:select lists、ul、ol)
function setDisabled(i)
{
dwr.engine.setAsync(false);
var complainValue = document.getElementById("complain"+i).value;
m_businessTypeService.queryBusinessTypeByFullName(cValue, function(businessType)
{
var result = businessType.split(":");
if(result.length != 5)
{
return;
}
var relationchannelflag = result[0];
var relationrequestflag = result[1];
var relationorgflag = result[2];
var relationDutyFlag = result[3];
var relationSupportsysFlag = result[4];
objDisabled("serviceSrType", '0');
objBtnDisabled("productType", "productTypeButton", '0');
objDisabled("channel", relationchannelflag);
objDisabled("request", relationrequestflag);
objDisabled("org", relationorgflag);
});
// <[设置为异步执行 ]>
dwr.engine.setAsync(true);
}
<span style="font-size:18px;"> <script language="JavaScript">
// 删除
function deleteConfig()
{
var allId = document.getElementsByName("otherCheckbox");
var ids = "";
<!--中间代码省略-->
if (confirm("确认要删除选中的数据?"))
{
// <[关键代码,回调函数]>
complaintscoreconfService.deleteComplaintScoresConf(ids, function(data)
{
if (data>0)
{
alert("删除成功!");
var form = parent.document.getElementById("queryFrm");
form.submit();
}
});
}
}
</script>
<!--x.XXX.dwr.xml-->
<!-- 工单分级分数配置 -->
<create creator="spring"
javascript="complaintscoreconfService">
<param name="beanName"
value="complaintscoreconfService" />
<include method="deleteComplaintScoresConf" />
<include method="checkConfIsExist" />
</create>
<!--x.XXX.service.xml-->
<bme:service id="complaintscoreconfService"
class="XXX.complaintscoreconf.service.impl.ComplaintscoreconfServiceImpl">
<property name="complaintscoreconfDao" ref="complaintscoreconfDao"/>
<property name="commonDasDAO" ref="commonDasDAO"/>
</bme:service></span>
<span style="font-size:18px;"><!--xxx.java>
public class ComplaintscoreconfServiceImpl implements ComplaintscoreconfService {
public int deleteComplaintScoresConf(String ids)
{
return complaintscoreconfDao.deleteComplaintScoresConf(ids);
}
}</span>
<span style="font-size:18px;"> -- 简单的二级级联示例:
<isap:layout id="inputLayout" cols="6" labelwidth="10%"
layoutstyle="width:99%" layoutclass="table_listoutline">
<isap:label value="'分类因素'"/>
<isap:gridecell colspan="1" align="left">
<isap:select name="elementoftaxonomy" id="elementoftaxonomy" list="{'','分级','数量','媒体传播'}"
οnchange="getDivideFactor()"/>
</isap:gridcell>
<isap:label value="'分类要素'"/>
<isap:gridcell colspan="1" align="left">
<isap:select name="languagelocaldisplay" id="languagelocaldisplay" emptyoption="true" label="''"/>
</isap:gridcell>
-- 语法参考JavaScript数值赋值:var a = [1,2,3,4,5];
var factors=['','普通','重要','重大'];
var complainNum=['','1级','2级','3级'];
var weibo=['','普通微博','10万粉丝微博','主流互联网站']
function getDivideFactor() {
var elementoftaxonomy = document.getElementById("elementoftaxonomy");
var languagelocaldis = document.getElementById("languagelocaldisplay");
//先删除上次下拉列表的值:
languagelocaldis.options.length=0;
//分级赋值:
if (elementoftaxonomy.value == '分级') {
addoption(languagelocaldis,factors);
return;
}
if (elementoftaxonomy.value == '数量') {
addoption(languagelocaldis,complainNum);
return;
}
if (elementoftaxonomy.value == '媒体传播') {
addoption(languagelocaldis,weibo);
return;
}
}
-- 参考html下拉列表系统方法:add(),一个select对象:
function change() {
var select = document.getElementById("Select1");
select.options.length = 0;
select.options.add(new Option("请选择", ""));
select.options.add(new Option("工作3", "3"));
select.options.add(new Option("工作4", "4"));
}
-- 往二级菜单中添加值[浏览器解释执行]
function addoption(selectObj,array) {
for (var i = 0; i < array.length; i++ ) {
//new方法或createElement方法
var option = document.createElement("OPTION");
option.text = array[i];
option.value = array[i];
select.add(option);
}
}</span>