DWR 入门与应用(一)

 

DWR 入门与应用(一)

Java 开发人员与网页设计人员的桥梁 DWR…呃!我懒得写简介了…直接来看看可以做什么吧!…

请先到 http://getahead.ltd.uk/dwr/ 下载 dwr.jar,放到WEB-INF/lib下…

负责处理客户端请求,并呼叫Java对象的是DWRServlet,DWR其实也有些Model 2的味道,只是View的这一层比较弱,因为放到客户端的JavaScript应用程序中…

在web.xml中加入DWRServlet…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>
  ajaxDWR</display-name>
  <servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
    <init-param>
      <description>
      </description>
      <param-name>debug</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-app>



接下来写个简单的Hello吧!

1
2
3
4
5
6
7

package onlyfun.caterpillar;
 
public class Hello {
  public String hello(String name) {
      return "哈啰!" + name + "!您的第一个DWR!";
    }
}



客户端要呼叫这个Java对象,传给它参数,而后传回一个字符串,客户端再显示这个字符串,神奇?其实是要告诉DWRServlet这件事,这需要一个dwr.xml:

1
2
3
4
5
6
7
8
9
10
11

<?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 creator="new" javascript="Hello">
      <param name="class" value="onlyfun.caterpillar.Hello" />
    </create>
  </allow>
</dwr>



creator设定为new,表示使用Hello的无参数建构子来生成对象,javascript设定为Hello,表示客户端JavaScript程序可以使用Hello来呼叫对应的onlyfun.caterpillar.Hello物件。

来写个客户端的网页,当中有一个输入字段…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
  <title>第一个DWR程序</title>
  <script type='text/javascript' src='dwr/interface/Hello.js'></script>
  <script type='text/javascript' src='dwr/engine.js'></script>
  <script type='text/javascript' src='dwr/util.js'></script>
  <script type='text/javascript' src='hello.js'></script>
</head>
<body>
 
<input id="user" type="text" />
<input type='button' value='哈啰' οnclick='hello();' />
 
<div id="result"></div>
 
</body>
</html>



dwr/interface/Hello.js是由DWRServlet根据dwr.xml中的设定生成的,engine.js负责客户端伺服端沟通,util.js是一些好用的JavaScript程序,可以让您少写很多JavaScript。

hello.js是我们自订的函式,按下按钮后,会呼叫当中的hello()函式:

1
2
3
4
5
6
7
8

function hello() {
    var user = $('user').value;
    Hello.hello(user, callback);
}
 
function callback(msg) {
   DWRUtil.setValue('result', msg);
}



${'user'}取得输入字段的DOM对象,value取得当中的字段值,而后呼叫Hello.hello(),并将value当作参数传送… 结果是呼叫Server端的Hello Java对象,当结果传回后,会呼叫JavaScript的callback函式,DWRUtil的setValue()方法会将传回的msg设定给指定 id的DOM,结果就是…啥!AJAX的功能在哪…就这个而言就是发出异步请求,而响应不用Refresh页面啦! 


好啦!这个无聊的Hello DWR可以做啥!…XD

已经可以让您做个简单的文字提示功能了…像这个…
http://caterpillar.onlyfun.net/Gossip/index.html

把鼠标指到书的照片上,会显示提示文字,这些提示文字本身不是存在网页上的,而是在Server端,当鼠标指到书上时,会用Request object去抓,然后显示在框框中…

当然!我的网站只支持PHP,所以那不是DWR完成的功能,而且我是直接用Request object跟DOM去慢慢刻的…对初学者来说已经有些麻烦了…XD

不过!用DWR就可以很简单完成这个功能…

先写个Java类别吧!会抓properties档案中的文字讯息,例如…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

package onlyfun.caterpillar;
 
import java.util.ResourceBundle;
 
public class Book {
  private ResourceBundle resource;
 
  public Book() {
    resource = ResourceBundle.getBundle("book");
  }
       
  public String getDescription(String key) {
    return resource.getString(key);
  }
}



从程序中就知道,它会去抓book_zh_TW.properties的数据,这不是重点啦!只是Java的一个功能,我们要看的是DWR,不过先把book_zh_TW.properties准备好…

1
2
3

java=Java 学习笔记的介绍 … BlaBla...
spring=Spring 技术手册的介绍…BlaBla...
ajax=Ajax in action 中文版的介绍…



唔!里头是中文字,自己用native2ascii转换吧…这也不是重点…我们是要看DWR怎么做到文字提示功能…

一样的…要开放这个Book对象,在dwr.xml中…

1
2
3
4
5
6
7
8
9
10
11

<?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 creator="new" javascript="Book" scope="application">
            <param name="class" value="onlyfun.caterpillar.Book"/>
        </create> 
  </allow>
</dwr>



scope设定为application,表示这个Book对象在整个应用程序阶段都活着。

然后,客户端写个网页…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
  <script type='text/javascript' src='dwr/interface/Book.js'></script>
  <script type='text/javascript' src='dwr/engine.js'></script>
  <script type='text/javascript' src='dwr/util.js'></script>
  <script type='text/javascript' src='book.js'></script>
<title>个人着/译作</title>
</head>
<body>
 
      <div id="ajax" οnmοuseοver="getBookData(this);"
 οnmοuseοut="clearData();"><a
 href="http://www.gotop.com.tw/waweb2004/home/home.aspx?pg=HM010X&bn=AXP011800"><small><img
 style="border: 0px solid ; width: 80px; height: 110px; float: left;"
 alt="Ajax in action 中文版" title="Ajax in action 中文版"
 src="images/ajax_in_action_c.jpg" hspace="10" vspace="2"></small></a></div>
 
      <div id="spring" οnmοuseοver="getBookData(this);"
 οnmοuseοut="clearData();"><a
 href="http://www.gotop.com.tw/waweb2004/home/home.aspx?pg=HM010X&bn=ACL021000"><small><img
 style="border: 0px solid ; width: 80px; height: 110px; float: left;"
 alt="Spring 技术手册" title="Spring 技术手册"
 src="images/SpringTech_S.jpg" hspace="10" vspace="2"></small></a></div>
 
      <div id="java" οnmοuseοver="getBookData(this);"
 οnmοuseοut="clearData();"><a
 href="http://www.gotop.com.tw/waweb2004/home/home.aspx?pg=HM010X&bn=ACL020931"><small><img
 style="border: 0px solid ; width: 80px; height: 110px; float: left;"
 alt="Java 学习笔记" title="Java 学习笔记"
 src="images/JavaGossip_Cover_Small.jpg" hspace="10"
 vspace="2"></small></a></div>
 
    <br/><br/><br/><br/><br/><br/>
 
    <div id="info"></div>
 
</body>
</html>



重点在于onmouseover跟onmouseout,鼠标移入与移出时会呼叫的函式,还有最下面的info,抓回来的书籍介绍会放到当中…

book.js如下,简单的很…

1
2
3
4
5
6
7
8
9
10
11

function getBookData(ele) {
  Book.getDescription(ele.id, setBookData);
}
 
function setBookData(description) {
  DWRUtil.setValue('info', description);
}
 
function clearData() {
  DWRUtil.setValue('info', '');
}



程序很简单,我懒得解释了…XD

看一下画面好了…这是鼠标移到 Ajax in action中文版 上的介绍画面…



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1186566

 

 

假设您要从数据库中查询出一些字符串,然后填写到窗体的下拉选单中。

例如一个示意的Java程序如下:

1
2
3
4
5
6
7
8

package onlyfun.caterpillar;
 
public class Option {
  public String[] getOptions() {
                // 实际上这些字符串是从数据库中查到的啦…
    return new String[] {"良葛格", "毛美眉", "米小狗"};
  }
}



传回的字符串数组,您要填写到下拉选单中,当然,首先我们要在dwr.xml中开发这个对象…

1
2
3
4
5
6
7
8
9
10

<?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 creator="new" javascript="OPT">
        <param name="class" value="onlyfun.caterpillar.Option"/>
    </create> 
  </allow>
</dwr>



这是我们的网页…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<script src="option.js" type="text/javascript"></script>
<script src="dwr/interface/OPT.js" type="text/javascript"></script>
<script src="dwr/engine.js" type="text/javascript"></script>
<script src="dwr/util.js" type="text/javascript"></script>
 
</head>
 
<body>
    选项: <select id="opts"></select>
</body>
</html>



传回的字符串数组会填入opts这个select中,我们的option.js如下…

1
2
3
4
5
6
7
8

window.onload = function() {
    OPT.getOptions(populate); 
};
 
function populate(list){
    DWRUtil.removeAllOptions("opts");
    DWRUtil.addOptions("opts", list);
}



够简单了…不需要解释了…

看一下结果… 


好啦!我知道有人在说了,这个程序有够无聊…

改一下!就是个不错的范例了,例如连动方块,唔!在Ajax in action中叫啥?Dynamic double combo?…

假设一个会去从数据库中查询数据的Java程序示意如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

package onlyfun.caterpillar;
 
import java.util.Map;
import java.util.TreeMap;
 
public class Bike {
  private Map<String, String[]> bikes;
  
  public Bike() {
    bikes = new TreeMap<String, String[]>();
    bikes.put("2000", new String[] {"2000 T1", "2000 T2", "2000 T3"});
    bikes.put("2001", new String[] {"2001 A1", "2001 A2"});
    bikes.put("2002", new String[] {"2002 BW1", "2002 BW2", "2002 BW"});
    bikes.put("2003", new String[] {"2003 S320"});
    bikes.put("2004", new String[] {"2004 TA1", "2004 TA2", "2004 TA3"});
  }
  
  public String[] getYears() {
    String[] keys = new String[bikes.size()];
    int i = 0;
    for(String key : bikes.keySet()) {
      keys[i++] = key;
    }
    return keys;
  }
  
  public String[] getBikes(String year) {
    return bikes.get(year);
  }
}



getYears()跟getBkies()分别表示产品的年份跟型号,这边用Map仿真,实际上数据是来自数据库的查询。

一样的,在dwr.xml中设定:

1
2
3
4
5
6
7
8
9
10

<?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 creator="new" javascript="Bike" scope="application">
        <param name="class" value="onlyfun.caterpillar.Bike"/>
    </create>
  </allow>
</dwr>



我们会有个脚踏车年份与型号查询页面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Insert title here</title>
  <script type='text/javascript' src='dwr/interface/Bike.js'></script>
  <script type='text/javascript' src='dwr/engine.js'></script>
  <script type='text/javascript' src='dwr/util.js'></script>
  <script type='text/javascript' src='bike.js'></script>
</head>
<body οnlοad="refreshYearList();">
  年份:<select id="years" οnchange="refreshBikeList();"></select><br/><br/>
  型号:<select id="bikes"></select><br/>
</body>
</html>



注意,在选完第一个年份后,会触发onchange事件,接着第二个下拉选单会自动填上对应年份的型号,而不是按钮按下,再去取得第二个下拉选单,然后refresh...blah...blah...

bike.js如下…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

function refreshYearList() {
    Bike.getYears(populateYearList);
}
 
function populateYearList(list){
    DWRUtil.removeAllOptions("years");
    DWRUtil.addOptions("years", list);
    refreshBikeList();
}
 
function refreshBikeList() {
    var year = $("years").value;
    Bike.getBikes(year, populateBikeList);
}
 
function populateBikeList(list){
    DWRUtil.removeAllOptions("bikes");
    DWRUtil.addOptions("bikes", list);
}



一样很简单…

看个无聊的画面…XD

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

package onlyfun.caterpillar;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.List;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
 public class ChatRoomServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
     private static LinkedList<Message> messages = new LinkedList<Message>();
    
     public ChatRoomServlet() {
    super();
  }
   
    private List<Message> addMessage(String text) {
        if (text != null && text.trim().length() > 0) {
            messages.addFirst(new Message(text));
            while (messages.size() > 10) {
                messages.removeLast();
            }
        }
 
        return messages;
    }
 
    private List<Message> getMessages() {
        return messages;
    }
   
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Message> list = null;
       
        if("send".equals(request.getParameter("task"))) {
             list = addMessage(request.getParameter("msg"));
        }
        else if("query".equals(request.getParameter("task"))){
             list = getMessages();
        }
 
        PrintWriter out = response.getWriter();
        response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");
 
        out.println("<response>");
        for(int i = 0; i < list.size(); i++) {
            String msg = list.get(i).getText();
            out.println("<message>" + msg + "</message>");
        }
        out.println("</response>");
  }            
}



Message物件如下…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

package onlyfun.caterpillar;
 
public class Message {
    private long id = System.currentTimeMillis();
    private String text;
   
    public Message(String newtext) {
        text = newtext;
        if (text.length() > 256) {
            text = text.substring(0, 256);
        }
        text = text.replace('<', '[');
        text = text.replace('&', '_');
    }
 
    public long getId() {
        return id;
    }
 
    public String getText() {
        return text;
    }
}



Servlet接受讯息新增与查询,判断的方式是检查请求参数task是send或query。

Servlet会以XML传回目前List当中的讯息,客户端可以查询或插入新讯息时,取得目前List中的讯息,接着在web.xml中设定一下…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <description>
    </description>
    <display-name>
    ChatRoomServlet</display-name>
    <servlet-name>ChatRoomServlet</servlet-name>
    <servlet-class>
    onlyfun.caterpillar.ChatRoomServlet</servlet-class>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>ChatRoomServlet</servlet-name>
    <url-pattern>/ChatRoomServlet</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>
            30
        </session-timeout>
  </session-config> 
</web-app>



在网页中,使用者可以在输入讯息后按下按钮送出信息,并在XML响应取得时,将讯息以一列一列的表格方式显示出来,另外还设定了周期性的轮询,即使不输入新讯息,也可以周期性的取得新的聊天讯息…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Chat Room</title>
 
<script type="text/javascript">
var xmlHttp;
 
function createXMLHttpRequest() {
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}
 
function sendMessage() {
  var msg = document.getElementById("text").value;
 
  if(msg == "") {
    refreshMessage();
    return;
  }
 
  var param = "task=send&msg=" + msg;
  ajaxRequest(param);
  document.getElementById("text").value = "";
}
 
function queryMessage() {
  var param = "task=query";
  ajaxRequest(param);
}
 
function ajaxRequest(param) {
  var url = "ChatRoomServlet?timestamp" + new Date().getTime();
    createXMLHttpRequest();
  xmlHttp.onreadystatechange = refreshMessage;
    xmlHttp.open("POST", url, true);
  xmlHttp.setRequestHeader("Content-Type",
           "application/x-www-form-urlencoded;");
    xmlHttp.send(param);
}
 
function refreshMessage() {
  if(xmlHttp.readyState == 4) {
        if(xmlHttp.status == 200) {
          var messages = xmlHttp.responseXML.getElementsByTagName("message");
 
          var table_body = document.getElementById("dynamicUpdateArea");
      var length = table_body.childNodes.length;
      for (var i = 0; i < length; i++) {
        table_body.removeChild(table_body.childNodes[0]);
      }
     
      var length = messages.length;
          for(var i = length - 1; i >= 0 ; i--) {
              var message = messages[i].firstChild.data;
              var row = createRow(message);
       
              table_body.appendChild(row);                       
          }
      setTimeout("queryMessage()", 2000);
        }
  }
}
 
function createRow(message) {
    var row = document.createElement("tr");
    var cell = document.createElement("td");
    var cell_data = document.createTextNode(message);
    cell.appendChild(cell_data);
    row.appendChild(cell);
    return row;
}
 
</script>
 
</head>
<body>
 
<p>
  Your Message:
  <input id="text"/>
  <input type="button" value="Send"
      οnclick="sendMessage()"/>
</p>
 
<p>Messages:</p>
    <table align="left">
        <tbody id="dynamicUpdateArea"></tbody>
    </table>
 
</body>
</html>



简单抓个画面… 


直接用AJAX,后端用JSP/Servlet,您要对请求参数做些判断,看看是新增讯息或查询,并要自行输出XML,有的没的…

改成DWR的话,就很简单了,写个简单的Java对象…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

package onlyfun.caterpillar;
 
import java.util.LinkedList;
import java.util.List;
 
public class Chat {
  private static LinkedList<Message> messages = new LinkedList<Message>();
 
  public List addMessage(String text) {
    if (text != null && text.trim().length() > 0) {
      messages.addFirst(new Message(text));
      while (messages.size() > 10) {
        messages.removeLast();
      }
    }
 
    return messages;
  }
 
  public List getMessages() {
    return messages;
  }
}



接着…在dwr.xml中开放一下…

1
2
3
4
5
6
7
8
9
10
11
12
13

<?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 creator="new" javascript="Chat">
      <param name="class" value="onlyfun.caterpillar.Chat"/>
    </create>
   
    <convert converter="bean" match="onlyfun.caterpillar.Message"/>     
  </allow>
</dwr>



使用者取得讯息时,是直接传回List对象,而List中装的是Message对象,Message对象是自订对象,conterver设定为 bean,表示DWR会自动将Message的getter名称转换为传回客户端的JavaScript对象中的属性,例如Message中有 getText(),则在客户端可以用message.text这样的方式来存取。

接着是简单的客户端网页…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Insert title here</title>
 
<script src="dwr/interface/Chat.js" type="text/javascript"></script>
<script src="dwr/engine.js" type="text/javascript"></script>
<script src="dwr/util.js" type="text/javascript"></script>
 
<script type="text/javascript">
function sendMessage() {
    var text = DWRUtil.getValue("text");
    DWRUtil.setValue("text", "");
    Chat.addMessage(text, gotMessages);
}
 
function gotMessages(messages) {
    var chatlog = "";
    for (var data in messages) {
        chatlog = "<div>" + messages[data].text +
            "</div>" + chatlog;
    }
    DWRUtil.setValue("chatlog", chatlog);
  setTimeout("queryMessage()", 2000);
}
 
function queryMessage() {
  Chat.getMessages(gotMessages);
}
</script>
 
</head>
<body>
 
<p>
  Your Message:
  <input id="text"/>
  <input type="button" value="Send"
      οnclick="sendMessage()"/>
</p>
 
<p>Messages:</p>
<div id="chatlog"></div>
 
</body>
</html>



当List对象传回时,它成为gotMessages(messages)中的messages对象,而messages对象中包括 Message对象转换后对应的JavaScript对象,由于我们已经设定了Converter,所以可以用messages[data].text来 取得传回的讯息…

简单抓个画面…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值