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连接相关的代码拷贝下来以备后用。
<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" onclick="sayHi();" value="问好"/> <input type="button" onclick="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,"name"); dwr.util.addOptions('setScreenOneSec'+indexs,data5,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="{'','分级','数量','媒体传播'}" onchange="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>