• Ajax框架---dwr的用法


    通常使用Ajax时用的都是jQuery框架,现在公司的框架里用的都是dwr。我觉得dwr和jQuery中的ajax用法差不多,看起来也很像。

    一、简介

      百度百科上对dwr的描述:

    DWR采取了一个类似AJAX的新方法来动态生成基于JAVA类的JavaScript代码。这样WEB开发人员就可以在JavaScript里使用Java代码,就像它们是浏览器的本地代码(客户端代码)一样;但是Java代码运行在WEB服务器端而且可以自由访问WEB 服务器的资源。出于安全的理由,WEB开发者必须适当地配置哪些Java类可以安全的被外部使用。

    二、用法

      (1)引入dwr

        1.下载dwr.jar,放大项目WEB-INF的lib下

        2.在web.xml中配置。把以下代码粘贴到web.xml的后边:
        

     1 <servlet>
     2     <servlet-name>dwr-invoker</servlet-name>
     3     <display-name>DWR Servlet</display-name>
     4     <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
     5     <init-param>
     6         <param-name>debug</param-name>
     7         <param-value>true</param-value>
     8     </init-param>
     9 </servlet>
    10 <servlet-mapping>
    11     <servlet-name>dwr-invoker</servlet-name>
    12     <url-pattern>/dwr/*</url-pattern>
    13 </servlet-mapping>

     (2)写dwr.xml

      dwr.xml和web.xml放到同一目录下。

      dwr.xml的写法如下:

    <dwr>
        <allow>
            <convert converter="bean" match="com.dwr.TestBean">
            <create creator="new" javascript="testClass" >
                <include method="testMethod1"/>
            </create>
        </allow>
    </dwr>

    <allow>标签内是允许页面访问的内容。

    <create>表示允许访问的类。

    ——creator属性表示该类的实例的创建方式,值可以是new或spring。new表示通过类的默认构造函数来创建。spring表示通过与IOC容器Spring进行集成来获得实例。

    ——javascript属性表示在js中访问的类名。(类名首字母小写)

    <include>表示类中允许访问的方法名。

    <converter>是告诉dwr如何在js中的参数和后台Java中的参数之间进行类型转化。js中调用后台方法时,传递的参数是js中的类型;但后台该方法的该参数是Java类型的。后台方法返回值时,值是Java类型的;但前台js中回调函数接受的该参数是js中的类型。<converter>的作用就是在这其中转换。当这个参数是Java的基本类型时,不需要些<converter>;当是自定义类的时候,就必须要写<converter>了,否则无法正常转换。match参数写实体类的完全限定名。

    (3)写后台方法

    后台Action中,该方法时public的:

    public class TestClass{
        public void testMethod1(){
            ......
        }
    }

    (4)页面js调用

    1.在页面上引入dwr的js文件

    1 <script src='/WEB-INF/dwr/interface/testClass.js'></script>
    2 <script src='/WEB-INF/dwr/engine.js'></script>
    3 <script src='/WEB-INF/dwr/util.js'></script>

    其中第一行是这个页面上请求的 类名.js(<create>标签中javascript属性的值.js),是dwr根据dwr.xml中的配置自动生成的。使用dwr的时候不要忘记引用这个js文件。

    第二行和第三行是dwr带的js

    2.调用方法

    如下:

    1 testClass.testMethod1();

     ①如果testMethod1有参数:

    public class TestClass{
        public void testMethod1(String name){
            ......
        }
    }

    调用:

    1 testClass.testMethod1("tom");

    ②如果testMethod1参数是自定义类型的:

    1 public class TestClass{
    2     public void testMethod1(TestBean testBean){
    3         ......
    4     }
    5 }
    1 public class TestBean{
    2     private String name;
    3     private String age;
    4     
    5     //get,set
    6     ......
    7 }

    则在dwr.xml中写<converter>,调用的时候:

    1 var param={ name:"tom", age:10 }
    2 testClass.testMethod1(param);

    ③如果testMethod1有返回值,返回值通常有这几种类型:String、对象、JSON,用回调函数接收并处理返回值。

    1 testClass.testMethod1(name,function(data){
    2     alert("返回的值:"+data);
    3 });

    返回值是对象时:

    1 testClass.testMethod1(name,function(data){
    2     for(var property in data){//不知道对象属性名时的处理方法
    3         alert("property:"+property);//对象的属性名
    4         alert(property+":"+data[property]);//属性对应的值
    5     }
    6 });

    或者:

    1 testClass.testMethod1(name,function(data){
    2     for(var property in data){//知道对象属性名时的处理方法
    3         alert(data.name);
    4         alert(data.age);
    5     }
    6 }

     返回的是JSON时,在后台返回JSON的字符串,页面的js上:

    1 testClass.testMethod1(name,function(data){
    2     var jsonData=JSON.parse(data);//把JSON的字符串转换成JSON,如果不处理的话,是无法直接解析JSON的字符串的
    3     //处理JSON数据
    4    ......
    5 }

     ④如果调用Java方法的参数是List、Set或Map类型的

    例子1:参数是List<TestBean>,js:

     1 var param1=[
     2      {
     3          name:tom,
     4          age:10
     5      },
     6      {
     7          name:jack,
     8          age:12
     9      }
    10  ];
    11 testClass.testMethod(param1,function(data){
    12 
    13 })

    在dwr.xml中的配置,在<allow>后加上:

    <signatures>
        <![CDATA[
            import java.util.List;
            import com.dwr.TestClass;
            import com.dwr.TestBean;
            TestClass.testMethod(List<TestBean>);
        ]]>
    </signatures>

    <signatures>标签是用来说明List中是什么类型的数据。 

    例子2:参数是Map类型

    1 var param1=[
    2     "key1":{name:tom,age:10},
    3     "key2":{name:jack,age:12}
    4 ];
    5 testClass.testMethod(param1,function(data){
    6     ......
    7 }

    在dwr.xml中的配置类似上边的,改为:TestClass.testMethod(Map<String,TestBean>);即可

    ⑤如果调用的Java方法返回的是List、Set、Map类型的值

     除了上述的方法外,没有特殊的写法。处理回调函数时,类似③的处理方式:

    例子1:返回类型是List<TestBean>

     1 testClass.testMethod6(callBackFunction(data){
     2     //对于JavaBean返回值,有两种方式处理
     3    //不知道属性名称时,使用如下方法
     4    for(var i=0;i<data.length;i++){
     5         for(var property in data[i]){
     6             alert("property:"+property);
     7             alert(property+":"+data[i][property]);
     8         }
     9     }
    10 
    11     //知道属性名称时,使用如下方法
    12    for(var i=0;i<data.length;i++){
    13         alert(data[i].username);
    14         alert(data[i].password);
    15     }
    16 });
    View Code

     例子2:返回类型是Map<String,TestBean>

    1 for(var property in data){
    2     var bean = data[property];
    3     alert(bean.username);
    4     alert(bean.password);
    5 }
    View Code

     三、注意事项

    (1)最近工作中,做Ajax的文件下载。以前都习惯的用jQuery写Ajax,这次,尝试了用dwr。但是,很快就发现不对劲的地方了。程序开始报空指针异常,我很不解。后来发现居然是这里面的resp(也就是response)是null。

    刚开始百思不得其解,后来上网查,才明白。原因请看我细细道来。

    在ssh中,获得Response的方法有两种:

    1 //第一种,通过ServletActionContext获取
    2 HttpServletResponse response=ServletActionContext.getResponse();
    3 //第二种,通过Aware接口获取
    4 public class TestAction implements ServletResponseAware{
    5     public void setServletResponse(HttpServletResponse resp){
    6          this.response=resp;  
    7     }      
    8 }
    View Code

    但以上两种获取的方法,但这两种获取Response的方法,请求必须通过struts2的XML配置文件进入action才能获取到。否则第一种方法中ServletActionContext为null,第二种方法中获取不到Response。

    但dwr发出的请求并不走strtus2的XML文件,它的请求是在dwr.xml中配置的。所以这个Response是获取不到的。所以马上又换回jQuery写Ajax。

    后来跟同事学了一个方法,dwr发送请求,后台可以获取request。但还没有试这种方法能不能获取Response。

    ------------------------------------------------------------------------------------------------------------------

    占地留空,呆验证了dwr可以获取Response之后,在这里补充。

    ------------------------------------------------------------------------------------------------------------------

     (2)最近在工作中又有另一种情况。

    用jQuery写Ajax,获取查询列表的list。在本地eclipse+tomcat运行正常。但放到weblogic的服务上之后,这个功能却怎么都不生效。调试了很久,调试console中并没有报错。打断点,只要走到

    1 var path=ctx+"/exambank/listQuestionManagerByAty.do?msg='"+timer+"'";
    2 $.getJSON(path,{id:id},function(json){
    3     ...
    4 }
    View Code

    这段代码的$.getJSON这一句,断点就没有了,查询列表仍然没有出来。然后,我开始试着调试,在调试框中,把js发送的path值粘出来,放到浏览器中请求,结果,chrome返回正确的json。这说明这个请求的后台程序没有问题。但我仍然不知道为什么程序走到$.getJson就不行了。

    百思不得其解的我,终于决定不再继续钻牛角尖,开始换成dwr实现这个效果。

    用dwr发送请求很顺利,但后台,需要取session中的一个值。语句如下:

    1 String orgCode=(String) request.getSession().getAttribute("OrgCode");
    View Code

    从session中取值,这是一定要用到request的。请教过同事之后,学到了下面的方法。以上的js写法不变,后台写法:

    1 public String listQuestionManagerByAty(HttpServletRequest request,String msg,BigDecimal id){
    2     String sql=getQuestionListSql(request,questionManagerVo);
    3 }
    View Code
    1 private String getQuestionListSql(HttpServletRequest request,QuestionManagerVo questionManagerVoParam){
    2     String orgCode="";
    3     if(!PubMethod.isEmpty(request)){
    4         orgCode=(String) request.getSession().getAttribute("OrgCode");
    5     }else{
    6         orgCode=(String) getSession().getAttribute("OrgCode");
    7     }
    8 }
    View Code

    在dwr请求的方法中,第一个参数的位置,写上HttpServletRequest request,这样,dwr请求进入到这个方法中的时候,request会自动被附上值。使用request获取session的时候,直接用就行了。

    request这个参数只能放到方法中的第一位。

      

  • 相关阅读:
    阿里播放器踩坑记录 进度条重构 video loadByUrl失效解决方案
    liunx 安装nc/netcat centos安装netcat
    jquery实现显示textarea输入字符数
    SQL 时间戳转换为日期
    .Net WebRequest异步请求与WebClient异步请求
    SQL删除多列语句
    jQuery为元素设置css的问题
    关于调试WCF时引发的异常XmlException: Name cannot begin with the '<' character, hexadecimal value 0x3C” on Client Side
    SQL删除指定条件的重复数据,只保留一条
    net.exe use命令的使用
  • 原文地址:https://www.cnblogs.com/mySummer/p/4604946.html
Copyright © 2020-2023  润新知