1 ---------------------------------ajaxUtil----------------------------------------------------------------------------------- 2 3 // ajaxUtil.js 4 5 var debug = true; 6 7 function sendHttpRequest(method, url, params, callback) { 8 var request; 9 if (window.XMLHttpRequest) 10 request = new XMLHttpRequest(); 11 else if (window.ActiveXObject) 12 request = new ActiveXObject("Microsoft.XMLHTTP"); 13 else 14 return null; 15 16 if (method) 17 method = method.toUpperCase(); 18 else 19 method = "GET"; 20 var fullURL = url; 21 if (params && method == "GET") 22 fullURL += "?" + buildQueryString(params); 23 var async = false; 24 if (callback) 25 async = true; 26 request.open(method, fullURL, async); 27 28 function calbackWrapper() { 29 if (async && request.readyState == 4) { 30 if (request.status == 200) 31 callback(request); 32 else 33 reportError(request, url, params); 34 } 35 } 36 if (async) 37 request.onreadystatechange = calbackWrapper; 38 39 var body = null; 40 if (method == "POST") { 41 request.setRequestHeader("Content-Type", 42 "application/x-www-form-urlencoded"); 43 if (params) 44 body = buildQueryString(params); 45 } 46 request.send(body); 47 if (!async && (request.readyState != 4 48 || request.status != 200)) { 49 reportError(request, url, params); 50 return null; 51 } 52 return request; 53 } 54 55 function buildQueryString(params) { 56 var query = ""; 57 for (var i = 0; i < params.length; i++) { 58 query += (i > 0 ? "&" : "") 59 + escape(params[i].name) + "=" 60 + escape(params[i].value); 61 } 62 return query; 63 } 64 65 function reportError(request, url, params) { 66 if (debug) { 67 if (request.status != 200) { 68 if (request.statusText) 69 alert(request.statusText); 70 else 71 alert("HTTP Status: " + request.status); 72 } else 73 alert("Response Error"); 74 if (params) 75 url += "?" + buildQueryString(params); 76 document.location = url; 77 } 78 } 79 80 function abortRequest(request) { 81 function doNothing() { 82 } 83 request.onreadystatechange = doNothing; 84 request.abort(); 85 delete feedRequest; 86 } 87 88 function escapeXML(content) { 89 if (content == undefined) 90 return ""; 91 if (!content.length || !content.charAt) 92 content = new String(content); 93 var result = ""; 94 var length = content.length; 95 for (var i = 0; i < length; i++) { 96 var ch = content.charAt(i); 97 switch (ch) { 98 case ‘&‘: 99 result += "&"; 100 break; 101 case ‘<‘: 102 result += "<"; 103 break; 104 case ‘>‘: 105 result += ">"; 106 break; 107 case ‘"‘: 108 result += """; 109 break; 110 case ‘\‘‘: 111 result += "'"; 112 break; 113 default: 114 result += ch; 115 } 116 } 117 return result; 118 } 119 120 function parse(xml) { 121 var dom; 122 try { 123 dom = new ActiveXObject("Microsoft.XMLDOM"); 124 dom.async = false; 125 dom.loadXML(xml); 126 } catch (error) { 127 try { 128 var parser = new DOMParser(); 129 dom = parser.parseFromString(xml, "text/xml"); 130 delete parser; 131 } catch (error2) { 132 if (debug) 133 alert("XML parsing is not supported."); 134 } 135 } 136 return dom; 137 } 138 139 function serialize(dom) { 140 var xml = dom.xml; 141 if (xml == undefined) { 142 try { 143 var serializer = new XMLSerializer(); 144 xml = serializer.serializeToString(dom); 145 delete serializer; 146 } catch (error) { 147 if (debug) 148 alert("DOM serialization is not supported."); 149 } 150 } 151 return xml; 152 } 153 154 -----------------------ajaxLogic--------------------------------------------------------------------------- 155 156 // ajaxLogic.js 157 158 var ctrlURL = "ajaxCtrl.jsp"; 159 var feedRequest = null; 160 161 function sendInfoRequest(symbols, callback) { 162 if (feedRequest) 163 abortRequest(feedRequest); 164 var params = new Array(); 165 for (var i = 0; i < symbols.length; i++) 166 params[i] = { 167 name: "symbol", 168 value: symbols[i] 169 }; 170 feedRequest = sendHttpRequest( 171 "GET", ctrlURL, params, callback); 172 } 173 174 function sendSaveRequest(xml) { 175 var params = [ { name: "xml", value: xml } ]; 176 var saveRequest = sendHttpRequest("POST", ctrlURL, params); 177 if (saveRequest) 178 delete saveRequest; 179 } 180 181 function sendLoadRequest() { 182 var model = null; 183 var loadRequest = sendHttpRequest("GET", ctrlURL); 184 if (loadRequest) { 185 model = eval(loadRequest.responseText); 186 delete loadRequest; 187 } 188 return model; 189 } 190 191 192 ------------------------------ajaxCtrl----------------------------------------------------------------------------------- 193 194 <%-- ajaxCtrl.jsp --%> 195 196 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 197 <%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %> 198 <%@ taglib prefix="feed" uri="/WEB-INF/feed.tld" %> 199 200 <tags:setHeader name="Cache-Control" value="no-cache"/> 201 202 <jsp:useBean id="dataFeed" scope="application" 203 class="ajaxapp.feed.DataFeed" /> 204 <jsp:useBean id="dataModel" scope="session" 205 class="ajaxapp.model.DataModel" /> 206 207 <c:choose> 208 <c:when test="${!empty param.symbol}"> 209 ${feed:getData(dataFeed, paramValues.symbol)} 210 </c:when> 211 <c:when test="${!empty param.xml}"> 212 <c:set target="${dataModel}" 213 property="data" 214 value="${param.xml}" /> 215 </c:when> 216 <c:otherwise> 217 ${dataModel.data} 218 </c:otherwise> 219 </c:choose> 220 -----------------------------------domTest.jsp-------------------------------------------------- 221 222 <html> 223 <head> 224 225 <script src="ajaxUtil.js"> 226 </script> 227 228 </head> 229 <body> 230 231 <script language="javascript"> 232 var xml = "<element>da<!--comment-->ta&" 233 + "<![CDATA[cdata]]></element>"; 234 235 var dom = parse(xml); 236 var element = dom.documentElement; 237 238 var childNodes = element.childNodes; 239 var text = ""; 240 for (var i = 0; i < childNodes.length; i++) 241 if (childNodes[i].nodeValue) { 242 var type = childNodes[i].nodeType; 243 if (type == 3 || type == 4) 244 text += childNodes[i].nodeValue; 245 } 246 247 document.writeln("<p>Original:<br>"); 248 document.writeln(escapeXML(xml)); 249 document.writeln("<p>Serialized:<br>"); 250 document.writeln(escapeXML(serialize(dom))); 251 document.writeln("<p>Text:<br>"); 252 document.writeln(text); 253 </script> 254 255 </body> 256 </html> 257 -----------------------------feedTest--------------------------------------------------------------------------- 258 259 <html> 260 <head> 261 262 <style> 263 TD { text-align: right; } 264 </style> 265 266 <script src="ajaxUtil.js"> 267 </script> 268 269 <script src="ajaxLogic.js"> 270 </script> 271 272 <script language="javascript"> 273 274 var symbols = [ "AAAA", "BBBB", "CCCC" ]; 275 276 function onLoad() { 277 sendInfoRequest(symbols, updateInfo); 278 setInterval("sendInfoRequest(symbols, updateInfo)", 5000); 279 } 280 281 function updateInfo(request) { 282 var shares = eval(request.responseText); 283 var table = "<table border=1 cellpadding=5>"; 284 table += "<tr>"; 285 table += "<th>Symbol</th>"; 286 table += "<th>Trend</th>"; 287 table += "<th>Last Price</th>"; 288 table += "</tr>"; 289 for (var i = 0; i < shares.length; i++) { 290 var share = shares[i]; 291 var symbol = escapeXML(share.symbol) 292 var trend = share.trend > 0 ? "+" : "-"; 293 var lastPrice = new Number(share.lastPrice).toFixed(2); 294 table += "<tr>"; 295 table += "<td>" + symbol + "</td>"; 296 table += "<td>" + trend + "</td>"; 297 table += "<td>" + lastPrice + "</td>"; 298 table += "</tr>"; 299 } 300 table += "</table>"; 301 document.getElementById("table").innerHTML = table; 302 } 303 304 </script> 305 306 </head> 307 308 <body onLoad="onLoad()"> 309 310 <div id="table"> 311 </div> 312 313 </body> 314 </html> 315 --------------------------------------------ModelTest-------------------------------------------------------------------------------------- 316 317 <html> 318 <head> 319 320 <script src="ajaxUtil.js"> 321 </script> 322 323 <script src="ajaxLogic.js"> 324 </script> 325 326 <script language="javascript"> 327 328 function attribute(name, value) { 329 return " " + name + "=\"" + escapeXML(value) + "\""; 330 } 331 332 function buildPortfolioDoc(stocks) { 333 var xml = "<portfolio>"; 334 for (var i = 0; i < stocks.length; i++) { 335 var stock = stocks[i]; 336 xml += "<stock "; 337 xml += attribute("symbol", stock.symbol); 338 xml += attribute("shares", stock.shares); 339 xml += attribute("paidPrice", stock.paidPrice); 340 xml += "/>"; 341 } 342 xml += "</portfolio>"; 343 return xml; 344 } 345 346 </script> 347 348 </head> 349 <body> 350 351 <p>Saved portfolio: <br> 352 <script language="javascript"> 353 var savedStocks = [ 354 { symbol: "AAAA", shares: 1, paidPrice: 10 }, 355 { symbol: "BBBB", shares: 2, paidPrice: 20 }, 356 { symbol: "CCCC", shares: 3, paidPrice: 30 } 357 ]; 358 var xml = buildPortfolioDoc(savedStocks); 359 sendSaveRequest(xml); 360 document.writeln(escapeXML(xml)); 361 </script> 362 363 <p>Loaded portfolio: <br> 364 <script language="javascript"> 365 var loadedStocks = sendLoadRequest(); 366 document.writeln(escapeXML(buildPortfolioDoc(loadedStocks))); 367 </script> 368 369 </body> 370 </html> 371 ------------------------------------queryTest---------------------------------------------------------------------- 372 373 <html> 374 <head> 375 376 <script src="ajaxUtil.js"> 377 </script> 378 379 </head> 380 <body> 381 382 <script language="javascript"> 383 384 var someParams = [ 385 { name: "name", value: "John Smith" }, 386 { name: "email", value: "john@company.com" }, 387 { name: "phone", value: "(123) 456 7890" } 388 ]; 389 390 someQuery = buildQueryString(someParams); 391 392 document.writeln(someQuery); 393 394 </script> 395 396 </body> 397 </html> 398 -------------------------------------------------------------------- 399 400 java:src 401 402 package ajaxapp.feed; 403 404 import ajaxapp.util.JSONEncoder; 405 406 import java.util.*; 407 408 public class DataFeed implements java.io.Serializable { 409 private HashMap<String, ShareBean> shareMap; 410 411 public DataFeed() { 412 shareMap = new HashMap<String, ShareBean>(); 413 } 414 415 public synchronized String getData(String symbols[]) { 416 JSONEncoder json = new JSONEncoder(); 417 json.startArray(); 418 for (int i = 0; i < symbols.length; i++) { 419 String symbol = symbols[i]; 420 ShareBean share = shareMap.get(symbol); 421 if (share == null) { 422 share = new ShareBean(symbol); 423 shareMap.put(symbol, share); 424 } 425 json.startObject(); 426 json.property("symbol", share.getSymbol()); 427 json.property("trend", share.getTrend()); 428 json.property("lastPrice", share.getLastPrice()); 429 json.endObject(); 430 } 431 json.endArray(); 432 return json.toString(); 433 } 434 435 public static String getData( 436 DataFeed feed, String symbols[]) { 437 return feed.getData(symbols); 438 } 439 440 } 441 package ajaxapp.feed; 442 443 public class ShareBean implements java.io.Serializable { 444 private String symbol; 445 private int trend; 446 private double lastPrice; 447 448 public ShareBean(String symbol) { 449 this.symbol = symbol; 450 trend = 1; 451 lastPrice = Math.random() * 100; 452 } 453 454 public String getSymbol() { 455 return symbol; 456 } 457 458 public int getTrend() { 459 return trend; 460 } 461 462 public double getLastPrice() { 463 lastPrice += trend * Math.random() * 0.1; 464 if (Math.random() < 0.2) 465 trend = -trend; 466 return lastPrice; 467 } 468 469 } 470 package ajaxapp.model; 471 472 import ajaxapp.util.JSONEncoder; 473 import ajaxapp.util.XMLUtil; 474 475 import org.w3c.dom.*; 476 import org.xml.sax.*; 477 478 import javax.xml.parsers.*; 479 import javax.xml.xpath.*; 480 481 import java.io.*; 482 import java.util.*; 483 import java.util.logging.*; 484 485 public class DataModel implements java.io.Serializable { 486 private static final String SCHEMA_NAME 487 = "/ajaxapp/model/portfolio.xsd"; 488 private static DocumentBuilderFactory parserFactory; 489 490 private ArrayList<StockBean> stockList; 491 492 public DataModel() { 493 stockList = new ArrayList<StockBean>(); 494 } 495 496 private static Document parsePortfolioDoc(String xml) 497 throws IOException, SAXException, 498 ParserConfigurationException { 499 synchronized (DataModel.class) { 500 if (parserFactory == null) 501 parserFactory = XMLUtil.newParserFactory(SCHEMA_NAME); 502 } 503 DocumentBuilder parser = XMLUtil.newParser(parserFactory); 504 InputSource in = new InputSource(new StringReader(xml)); 505 return parser.parse(in); 506 } 507 508 public synchronized void setData(String xml) 509 throws IOException, SAXException, 510 ParserConfigurationException, 511 XPathExpressionException { 512 try { 513 ArrayList<StockBean> stockList 514 = new ArrayList<StockBean>(); 515 Document doc = parsePortfolioDoc(xml); 516 NodeList nodeList = XMLUtil.evalToNodeList( 517 "/portfolio/stock", doc); 518 for (int i = 0; i < nodeList.getLength(); i++) { 519 Node node = nodeList.item(i); 520 StockBean stock = new StockBean(); 521 stock.setSymbol( 522 XMLUtil.evalToString("@symbol", node)); 523 stock.setShares( 524 (int) XMLUtil.evalToNumber("@shares", node)); 525 stock.setPaidPrice( 526 XMLUtil.evalToNumber("@paidPrice", node)); 527 stockList.add(stock); 528 } 529 this.stockList = stockList; 530 } catch (Exception e) { 531 Logger.global.logp(Level.SEVERE, "DataModel", "setData", 532 e.getMessage(), e); 533 } 534 } 535 536 public synchronized String getData() { 537 JSONEncoder json = new JSONEncoder(); 538 json.startArray(); 539 for (int i = 0; i < stockList.size(); i++) { 540 StockBean stock = stockList.get(i); 541 json.startObject(); 542 json.property("symbol", stock.getSymbol()); 543 json.property("shares", stock.getShares()); 544 json.property("paidPrice", stock.getPaidPrice()); 545 json.endObject(); 546 } 547 json.endArray(); 548 return json.toString(); 549 } 550 551 } 552 package ajaxapp.model; 553 554 public class StockBean implements java.io.Serializable { 555 private String symbol; 556 private int shares; 557 private double paidPrice; 558 559 public String getSymbol() { 560 return symbol; 561 } 562 563 public void setSymbol(String symbol) { 564 this.symbol = symbol; 565 } 566 567 public int getShares() { 568 return shares; 569 } 570 571 public void setShares(int shares) { 572 this.shares = shares; 573 } 574 575 public double getPaidPrice() { 576 return paidPrice; 577 } 578 579 public void setPaidPrice(double paidPrice) { 580 this.paidPrice = paidPrice; 581 } 582 583 } 584 ---------------proloi.xsd----------------------------------------- 585 586 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 587 588 <xsd:element name="portfolio" type="portfolioType"/> 589 590 <xsd:complexType name="portfolioType"> 591 <xsd:sequence> 592 <xsd:element name="stock" 593 minOccurs="0" maxOccurs="unbounded"> 594 <xsd:complexType> 595 <xsd:attribute name="symbol" 596 type="xsd:string" use="required"/> 597 <xsd:attribute name="shares" 598 type="xsd:positiveInteger" use="required"/> 599 <xsd:attribute name="paidPrice" 600 type="xsd:decimal" use="required"/> 601 </xsd:complexType> 602 </xsd:element> 603 </xsd:sequence> 604 </xsd:complexType> 605 606 </xsd:schema> 607 --------------------JSON------------------------------------------------------------------------------ 608 609 package ajaxapp.util; 610 611 public class JSONEncoder { 612 private StringBuilder buf; 613 614 public JSONEncoder() { 615 buf = new StringBuilder(); 616 } 617 618 public void character(char ch) { 619 switch (ch) { 620 case ‘\‘‘: 621 case ‘\"‘: 622 case ‘\\‘: 623 buf.append(‘\\‘); 624 buf.append(ch); 625 break; 626 case ‘\t‘: 627 buf.append(‘\\‘); 628 buf.append(‘t‘); 629 break; 630 case ‘\r‘: 631 buf.append(‘\\‘); 632 buf.append(‘r‘); 633 break; 634 case ‘\n‘: 635 buf.append(‘\\‘); 636 buf.append(‘n‘); 637 break; 638 default: 639 if (ch >= 32 && ch < 128) 640 buf.append(ch); 641 else { 642 buf.append(‘\\‘); 643 buf.append(‘u‘); 644 for (int j = 12; j >= 0; j-=4) { 645 int k = (((int) ch) >> j) & 0x0f; 646 int c = k < 10 ? ‘0‘ + k : ‘a‘ + k - 10; 647 buf.append((char) c); 648 } 649 } 650 } 651 } 652 653 public void string(String str) { 654 int length = str.length(); 655 for (int i = 0; i < length; i++) 656 character(str.charAt(i)); 657 } 658 659 public void literal(Object value) { 660 if (value instanceof String) { 661 buf.append(‘"‘); 662 string((String) value); 663 buf.append(‘"‘); 664 } else if (value instanceof Character) { 665 buf.append(‘\‘‘); 666 character(((Character) value).charValue()); 667 buf.append(‘\‘‘); 668 } else 669 buf.append(value.toString()); 670 } 671 672 private void comma() { 673 buf.append(‘,‘); 674 } 675 676 private void deleteLastComma() { 677 if (buf.length() > 0) 678 if (buf.charAt(buf.length()-1) == ‘,‘) 679 buf.deleteCharAt(buf.length()-1); 680 } 681 682 public void startObject() { 683 buf.append(‘{‘); 684 } 685 686 public void property(String name, Object value) { 687 buf.append(name); 688 buf.append(‘:‘); 689 literal(value); 690 comma(); 691 } 692 693 public void endObject() { 694 deleteLastComma(); 695 buf.append(‘}‘); 696 comma(); 697 } 698 699 public void startArray() { 700 buf.append(‘[‘); 701 } 702 703 public void element(Object value) { 704 literal(value); 705 comma(); 706 } 707 708 public void endArray() { 709 deleteLastComma(); 710 buf.append(‘]‘); 711 comma(); 712 } 713 714 public String toString() { 715 deleteLastComma(); 716 return buf.toString(); 717 } 718 719 public void clear() { 720 buf.setLength(0); 721 } 722 723 } 724 package ajaxapp.util; 725 726 import oracle.xml.jaxp.JXDocumentBuilderFactory; 727 import oracle.xml.parser.schema.XMLSchema; 728 import oracle.xml.parser.schema.XSDBuilder; 729 730 import org.w3c.dom.*; 731 import org.xml.sax.*; 732 733 import javax.xml.*; 734 import javax.xml.parsers.*; 735 import javax.xml.transform.*; 736 import javax.xml.transform.dom.*; 737 import javax.xml.transform.stream.*; 738 import javax.xml.validation.*; 739 import javax.xml.xpath.*; 740 741 import java.io.*; 742 import java.util.*; 743 import java.util.logging.*; 744 745 public class XMLUtil { 746 747 public static ErrorHandler newErrorHandler() { 748 return new ErrorHandler() { 749 public void warning(SAXParseException e) 750 throws SAXException { 751 Logger.global.warning(e.getMessage()); 752 } 753 754 public void error(SAXParseException e) 755 throws SAXException { 756 throw e; 757 } 758 759 public void fatalError(SAXParseException e) 760 throws SAXException { 761 throw e; 762 } 763 }; 764 } 765 766 public static InputStream getResourceAsStream(String name) 767 throws IOException { 768 InputStream in = XMLUtil.class.getResourceAsStream(name); 769 if (in == null) 770 throw new FileNotFoundException(name); 771 return in; 772 } 773 774 protected static SchemaFactory schemaFactory; 775 static { 776 schemaFactory = SchemaFactory.newInstance( 777 XMLConstants.W3C_XML_SCHEMA_NS_URI); 778 schemaFactory.setErrorHandler(newErrorHandler()); 779 } 780 781 public static Schema newSchema(String name) 782 throws IOException, SAXException { 783 Schema schema; 784 InputStream in = getResourceAsStream(name); 785 try { 786 schema = schemaFactory.newSchema(new StreamSource(in)); 787 } finally { 788 in.close(); 789 } 790 return schema; 791 } 792 793 public static XMLSchema newOracleSchema(String name) 794 throws IOException, SAXException { 795 XMLSchema schema; 796 InputStream in = getResourceAsStream(name); 797 try { 798 XSDBuilder builder = new XSDBuilder(); 799 schema = builder.build(new InputSource(in)); 800 } catch (Exception e) { 801 throw new SAXException(e); 802 } finally { 803 in.close(); 804 } 805 return schema; 806 } 807 808 public static DocumentBuilderFactory newParserFactory( 809 String schemaName) throws IOException, SAXException { 810 DocumentBuilderFactory parserFactory 811 = DocumentBuilderFactory.newInstance(); 812 try { 813 parserFactory.setSchema(newSchema(schemaName)); 814 } catch (UnsupportedOperationException e) { 815 if (parserFactory instanceof JXDocumentBuilderFactory) { 816 parserFactory.setAttribute( 817 JXDocumentBuilderFactory.SCHEMA_OBJECT, 818 newOracleSchema(schemaName)); 819 } 820 } 821 return parserFactory; 822 } 823 824 public static DocumentBuilder newParser( 825 DocumentBuilderFactory parserFactory) 826 throws ParserConfigurationException { 827 DocumentBuilder parser = parserFactory.newDocumentBuilder(); 828 parser.setErrorHandler(newErrorHandler()); 829 return parser; 830 }; 831 832 protected static XPathFactory xpathFactory; 833 static { 834 xpathFactory = XPathFactory.newInstance(); 835 } 836 837 public static XPath newXPath() { 838 return xpathFactory.newXPath(); 839 } 840 841 public static String evalToString(String expression, 842 Object context) throws XPathExpressionException { 843 return (String) newXPath().evaluate(expression, context, 844 XPathConstants.STRING); 845 } 846 847 public static boolean evalToBoolean(String expression, 848 Object context) throws XPathExpressionException { 849 return ((Boolean) newXPath().evaluate(expression, context, 850 XPathConstants.BOOLEAN)).booleanValue(); 851 } 852 853 public static double evalToNumber(String expression, 854 Object context) throws XPathExpressionException { 855 return ((Double) newXPath().evaluate(expression, context, 856 XPathConstants.NUMBER)).doubleValue(); 857 } 858 859 public static Node evalToNode(String expression, 860 Object context) throws XPathExpressionException { 861 return (Node) newXPath().evaluate(expression, context, 862 XPathConstants.NODE); 863 } 864 865 public static NodeList evalToNodeList(String expression, 866 Object context) throws XPathExpressionException { 867 return (NodeList) newXPath().evaluate(expression, context, 868 XPathConstants.NODESET); 869 } 870 871 public static TransformerFactory serializerFctory; 872 static { 873 serializerFctory = TransformerFactory.newInstance(); 874 } 875 876 public static void serialize(Node node, OutputStream out) 877 throws TransformerException { 878 Transformer serializer = serializerFctory.newTransformer(); 879 Properties serializerProps = new Properties(); 880 serializerProps.put(OutputKeys.METHOD, "xml"); 881 serializer.setOutputProperties(serializerProps); 882 Source source = new DOMSource(node); 883 Result result = new StreamResult(out); 884 serializer.transform(source, result); 885 } 886 887 }
解如何利用 XML 和 JavaScript Object Notation 在 Ajax 客户端和 Java 服务器之间传输数据(代码)(Oracle)。,布布扣,bubuko.com
解如何利用 XML 和 JavaScript Object Notation 在 Ajax 客户端和 Java 服务器之间传输数据(代码)(Oracle)。