注:此篇文章适合于有一定DWR基础的开发人员
老师,都已经上课了,女生为什么都没来?
女同学都已经懂了,不用来听课了,你们男同学有没有不懂的?嗯...都懂了哈,看来同学们没有辜负老师的一片苦心,为了鼓励你们,老师绝对下课后请你们每人吃一棍小布丁。既然大家都这么聪明,那么老师就再接再厉,把第二问题给同学讲明白。js直接调用Java方法,是不是很神奇!?哇塞,简直屌爆了!
这位同学,老师不是神灯,小心出事。其实神奇的不是能不能调,而是DWR的这种构思,这种想法,这种创新实在是让人不得不佩服。
安静,安静,同学们不要鸡冻,冷静一下,我能理解你们现在的心情,在进入正题之前,谁能回答老师一个问题:在js中到底能不能调用Java方法?
好像不能吧?!js是运行在客户端,Java是运行在服务器端,应该是不能的?!
这位同学不用担心,你说的一点都没错,js当然不能直接调用Java方法,所有客户端与服务器的交互都必须要遵循http协议,即请求——反馈。DWR也不例外,js想要调用Java方法,也必须要从客户端发送请求,然后得到服务器的反馈。实际上在js中调用“Java方法”时即是给服务器发送请求,没错,而这个请求的工作都是通过Ajax去完成的,所以在调用“Java方法”的时候需要指定回调函数,因为Ajax是异步的,而服务器处理请求是同步的。因此在表面上看来,js好像真的直接调用了Java方法,只是中间的过程被Ajax偷偷的做了。那么接下来,我们对上节课的例子稍微改造一下。
新建处理类DemoDWRFacade.java
package com.dwr; public class DemoDWRFacade { public String test(){ System.out.println("OK"); return "OK"; } }修改DwrServlet(注:本例中的doPost方法是DWR中DwrServlet的简化版,实例化和输出js文件流在DWR中使用的是XML+反射实现)
package com.dwr; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DwrServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { doPost(request,response); } @Override public void doPost(HttpServletRequest request,IOException { ServletOutputStream out = null; try { out = response.getOutputStream(); if (request.getRequestURI().endsWith(".js")) { // 如果请求的是js文件则输出文件流 byte[] b = "demoDWRFacade = {}; demoDWRFacade.test = function(callback){send(callback)};".getBytes(); out.write(b); } else { // 如果请求的是处理则实例化类且执行对应的方法 DemoDWRFacade demoDWRFacade = new DemoDWRFacade(); out.print(demoDWRFacade.test()); } out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } }修改index.jsp(注:本例中的send方法是简化版的engine.js,但处理的过程也不外乎如此,感兴趣的同学可以查阅engine.js的源代码)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My DWR</title> <Meta http-equiv="pragma" content="no-cache"> <Meta http-equiv="cache-control" content="no-cache"> <script type="text/javascript" src="dwr/interface/demo.js"></script> <script type="text/javascript"> function send(callback){ var xmlHttp; if(window.document.all){ try{ xmlHttp = new ActiveXObject('Msxml2.XMLHTTP'); }catch(e1){ try{ xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); }catch(e2){ alert("Your IE dosn't support XMLHTTP,please update to IE6 or later."); } } }else if(typeof XMLHttpRequest != 'undefined'){ xmlHttp = new XMLHttpRequest(); } xmlHttp.open("POST",encodeURI("dwr/interface/demo"),true); xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4){ var responseText = xmlHttp.responseText; if(xmlHttp.status == 200){ if(callback) callback.call(this,responseText); } } }; xmlHttp.setrequestheader('cache-control','no-cache'); xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xmlHttp.send(); } // 回调函数 function response(responseText){ alert(responseText); } function fireClick(){ demoDWRFacade.test(response); } </script> </head> <body> <input type="button" value="测试" onclick="fireClick()"><br> </body> </html>访问上面的index.jsp页面,点击按钮“测试”,可以看到弹出alert对话框“OK”。你和你的小伙伴是不是又都惊呆了?!
现在第二个问题也已经解决完了,那么,结课。
注意:本文主要是通过最简单的方式去解释DWR的原理,所以在代码实现上跟DWR有很大的不同,请大家不要误解。 原文链接:https://www.f2er.com/ajax/166050.html