傅老师课堂:Ajax高级应用之DWR原理解析(二)

开篇一笑:周杰伦在沙漠中迷路了,这时他捡到一个神灯,他摸摸神灯,出来一个神仙,神仙说,我能满足你三个愿望。周杰伦一看,高兴的脱口而出:“哇塞,屌爆了!”结果,他痛苦的在地上呻吟。神仙说:“第二个愿望呢?”周杰伦痛苦的说:“把我弟弟治好。”果然,他不疼了,站起来一看,完好无损。遂惊呼:“哇塞,屌爆了!”

注:此篇文章适合于有一定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, HttpServletResponse response)
            throws ServletException, 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="测试" οnclick="fireClick()"><br>
  </body>
</html>
访问上面的index.jsp页面,点击按钮“测试”,可以看到弹出alert对话框“OK”。你和你的小伙伴是不是又都惊呆了?!
现在第二个问题也已经解决完了,那么,结课。

注意:本文主要是通过最简单的方式去解释DWR的原理,所以在代码实现上跟DWR有很大的不同,请大家不要误解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值