利用Servlet创建一个XML文档

在我们深入研究代码之前,我们需要做出一些决定。我们将使用XML返回数据,但是应该如何设计XML结构?我们的XML响应应该是什么样子的呢?我们不希望任何复杂,所以我们的目标是创建一个XML文档,如下所示:

<converted-values>
    <decimal>97</decimal>
    <hexadecimal>0x61</hexadecimal>
    <octal>0141</octal>
    <hyper>&0x61;</hyper>
    <binary>1100001B</binary>
</converted-values>

使用这种格式,浏览器可以使用它的文档对象模型(DOM)解析器索引和检索数据。

有很多方法可以创建这个XML文档。为了简单起见,我们首先使用StringBuffer来包装数据和XML标记。

让我们看下在servlet代码中封装的XML数据。

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class AjaxResponseServlet extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        // key is the parameter passed in from the JavaScript
        // variable named url (see index.html)
        String key = req.getParameter("key");
        StringBuffer returnXML = null;
        if (key != null) {
            // extract the first character from key
            // as an int, then convert that int to a String
            int keyInt = key.charAt(0);
            returnXML = new StringBuffer("\r\n<converted-values>");
            returnXML.append("\r\n<decimal>"+
                             Integer.toString(keyInt)+"</decimal>");
            returnXML.append("\r\n<hexadecimal>0x"+
                             Integer.toString(keyInt,16)+"</hexadecimal>");
            returnXML.append("\r\n<octal>0"+
                             Integer.toString(keyInt,8)+"</octal>");
            returnXML.append("\r\n<hyper>&0x"+
                             Integer.toString(keyInt,16)+";</hyper>");
            returnXML.append("\r\n<binary>"+
                             Integer.toString(keyInt,2)+"B</binary>");
            returnXML.append("\r\n</converted-values>");

            // set up the response
            res.setContentType("text/xml");
            res.setHeader("Cache-Control", "no-cache");
            // write out the XML string
            res.getWriter().write(returnXML.toString( ));
        }
        else {
            // if key comes back as a null, return a question mark
            res.setContentType("text/xml");
            res.setHeader("Cache-Control", "no-cache");
            res.getWriter( ).write("?");
        }
    }
}

这段代码仅仅设置了一个名为returnXML的StringBuffer。然后我们将传入值转换为十进制、十六进制、等等,将它与一个适当的XML标记,并将它添加到缓冲当中。当我们完成了所有五种转化和添加结束标记(< /converted-values>),我们使用res.getWriter().write( )将响应发送回Ajax客户端。如果我们收到的key为null,我们返回一个问号(表示没有任何XML封装)。
下面,我们来设计客户端HTML页面,如图:


客户端代码显示了如何获取从服务器端发送的XML文档中的数据字段。

<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
    <STYLE type="text/css">
        .borderless {  color:black; text-align:center; background:powderblue;
                border-width:0;border-color:green;  }
    </STYLE>

    <title>function</title>
    <SCRIPT language="JavaScript" type="text/javascript">
        var req;

        function convertToXML( ) {
            var key = document.getElementById("key");
            var keypressed = document.getElementById("keypressed");
            keypressed.value = key.value;
            var url = "/ajaxcodeconverter-lab2/response?key=" + escape(key.value);
            if (window.XMLHttpRequest) {
                req = new XMLHttpRequest( );
            }
            else if (window.ActiveXObject) {
                req = new ActiveXObject("Microsoft.XMLHTTP");
            }
            req.open("Get",url,true);
            req.onreadystatechange = callback;
            req.send(null);
        }
        function nonMSPopulate( ) {
            xmlDoc = document.implementation.createDocument("","", null);
            var resp = req.responseText;
            var parser = new DOMParser( );
            var dom = parser.parseFromString(resp,"text/xml");

            decVal = dom.getElementsByTagName("decimal");
            var decimal = document.getElementById('decimal');
            decimal.value=decVal[0].childNodes[0].nodeValue;

            hexVal = dom.getElementsByTagName("hexadecimal");
            var hexadecimal = document.getElementById('hexadecimal');
            hexadecimal.value=hexVal[0].childNodes[0].nodeValue;

            octVal = dom.getElementsByTagName("octal");
            var octal = document.getElementById('octal');
            octal.value=octVal[0].childNodes[0].nodeValue;

            hyperVal = dom.getElementsByTagName("hyper");
            var hyper = document.getElementById('hyper');
            hyper.value=hyperVal[0].childNodes[0].nodeValue;

            binaryVal = dom.getElementsByTagName("binary");
            var bin = document.getElementById('bin');
            bin.value=binaryVal[0].childNodes[0].nodeValue;
        }

        function msPopulate( ) {
            var resp = req.responseText;

            var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async="false";
            xmlDoc.loadXML(resp);

            nodes=xmlDoc.documentElement.childNodes;

            dec = xmlDoc.getElementsByTagName('decimal');
            var decimal = document.getElementById('decimal');
            decimal.value=dec[0].firstChild.data;

            hexi = xmlDoc.getElementsByTagName('hexadecimal');
            var hexadecimal = document.getElementById('hexadecimal');
            hexadecimal.value=hexi[0].firstChild.data;

            oct = xmlDoc.getElementsByTagName('octal');
            var octal = document.getElementById('octal');
            octal.value=oct[0].firstChild.data;

            bin = xmlDoc.getElementsByTagName('binary');
            var binary = document.getElementById('bin');
            binary.value=bin[0].firstChild.data;
            hypertextml = xmlDoc.getElementsByTagName('hyper');
            var hyper = document.getElementById('hyper');
            hyper.value=hypertextml[0].firstChild.data;
        }

        function callback( ) {
            if (req.readyState==4) {
                if (req.status == 200) {

                    if (window.XMLHttpRequest) {
                        nonMSPopulate( );
                    }
                    else if (window.ActiveXObject) {
                        msPopulate( );
                    }
                }
            }
            clear( );
        }

        function clear( ) {
            var key = document.getElementById("key");
            key.value="";
        }

    </SCRIPT>
</head>

<body>
    <H1>
        <CENTER>AJAX CHARACTER DECODER</CENTER>
    </H1>
    <H2>
        <CENTER>Press a key to find its value.</CENTER>
    </H2>
    <form name="form1" action="/ajaxcodeconverter-lab2" method="get">

    <table border="2" bordercolor="black" bgcolor="lightblue" valign="center"
           align="center">
        <tr>
            <td align="center">
                Enter Key Here ->
                <input type="text" id="key" name="key" maxlength="1" size="1"
                       οnkeyup="convertToXML( );">
            </td>
        </tr>
    </table>
    <br>
    <table class="borderless" border="1" valign="center" align="center">
        <tr>
            <td align="center" colspan="5">
                Key Pressed: 
                <input class="borderless" type="text" readonly id="keypressed"
                       maxlength="1" size="1">
            </td>
        </tr>
        <tr>
            <td align="center">  Decimal  </td>
            <td align="center">Hexadecimal</td>
            <td align="center">   Octal   </td>
            <td align="center">
                    Binary    
            </td>
            <td align="center">
                    HTML    
            </td>
        </tr>
        <tr>
            <td align="center"><input class="borderless" type="text" readonly
                id="decimal" maxlength="6" size="6"></td>
            <td align="center"><input class="borderless" type="text" readonly
                id="hexadecimal" maxlength="6" size="6"></td>
            <td align="center"><input class="borderless" type="text" readonly
                id="octal" maxlength="6" size="6"></td>
            <td align="center"><input class="borderless" type="text" readonly
                id="bin" maxlength="8" size="8"></td>
            <td align="center"><input class="borderless" type="text" readonly
                id="hyper" maxlength="6" size="6"></td>
        </tr>
    </table>

    </form>
</body>
</html>

记住,这一切都始于我们使用JavaScript写的callback()函数

记得convertToXML()是如何确定浏览器是Internet Explorer或者其他浏览器了吗?我们这里又有同样的问题。当callback()被调用时,它必须检查我们是否正在运行ActiveXObject(Internet Explorer)或XMLHttpRequest(其他所有主流浏览器)。

如果浏览器是Internet Explorer,我们运行msPopulate()来删除XML中的数据。否则,我们运行nonMSPopulate()。有什么区别吗?这与我们如何得到一个XML解析器和解析器提供的API。Mozilla Firefox和Safari都使用新的DOMParser()来获得一个内置解析器解析XML,而且据说Opera很快就会支持这个。Internet Explorer,另一方面,使用新的ActiveXObject(“Microsoft.XMLDOM”)得到微软的XML解析器。

   function msPopulate( ) {
      var resp = req.responseText;

      var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
      xmlDoc.async="false";
      xmlDoc.loadXML(resp);
 
      dec = xmlDoc.getElementsByTagName('decimal');
      var decimal = document.getElementById('decimal');
      decimal.value=dec[0].firstChild.data;

      hexi = xmlDoc.getElementsByTagName('hexadecimal');
      var hexadecimal = document.getElementById('hexadecimal');
      hexadecimal.value=hexi[0].firstChild.data;

      oct = xmlDoc.getElementsByTagName('octal');
      var octal = document.getElementById('octal');
      octal.value=oct[0].firstChild.data;

      bin = xmlDoc.getElementsByTagName('binary');
      var binary = document.getElementById('bin');
      binary.value=bin[0].firstChild.data;

      hypertextml = xmlDoc.getElementsByTagName('hyper');
      var hyper = document.getElementById('hyper');
      hyper.value=hypertextml[0].firstChild.data;
  }

在msPopulate( )这里,我们使用内置的浏览器功能,我已经被吹捧为一个程序员玩。我们开始通过ActiveXObject称微软。XMLDOM(第4行)。接下来,我们来自servlet的响应加载到XML文档(第6行)。

现在我们可以获取文档数据。首先我们获得数据之间的 <decimal></decimal>标记。要做到这一点,我们首先检索XML数据字段信息,通过调用getElementsByTagName(elementName)(第8行),这个函数返回的子节点数组的元素(父节点)与给定的标记。我们得到的子节点数组后,我们可以引用第一个元素的子节点通过调用firstChild。然后我们通过引用数据字段获得子节点的值。所以,总之,我们从dec[0].firstChild.data获取十进制值。

获取XML的十进制值后,第10行的代码更新十进制表单元素。我们现在从XML检索一个值并显示在页面上。我们以这种方式继续,直到我们所有的更新数据字段的值从servlet发送到的XML DOM检索完毕。

  function nonMSPopulate( ) {
      var resp = req.responseText;
      var parser = new DOMParser( );
      var dom = parser.parseFromString(resp,"text/xml");

      decVal = dom.getElementsByTagName("decimal");
      var decimal = document.getElementById('decimal');
      decimal.value=decVal[0].childNodes[0].nodeValue;

      hexVal = dom.getElementsByTagName("hexadecimal");
      var hexadecimal = document.getElementById('hexadecimal');
      hexadecimal.value=hexVal[0].childNodes[0].nodeValue;

      octVal = dom.getElementsByTagName("octal");
      var octal = document.getElementById('octal');
      octal.value=octVal[0].childNodes[0].nodeValue;

      hyperVal = dom.getElementsByTagName("hyper");
      var hyper = document.getElementById('hyper');
      hyper.value=hyperVal[0].childNodes[0].nodeValue;

      binaryVal = dom.getElementsByTagName("binary");
      var bin = document.getElementById('bin');
      bin.value=binaryVal[0].childNodes[0].nodeValue;
  }



我们创建一个新的DOMParser(第3行),然后在第4行创建一个DOM从servlet获取到的XML字符串。接下来,我们通过调用dom.getElementByTagName("decimal")获取<decimal></decimal>标记(第6行)之间的数据。之后从我们的HTML文档检索十进制表单元素,我们将检索的值以XML的形式发送给我们并且用它来设置适当的字段

decimal.value=decVal[0].childNodes[0].nodeValue;

使用decVal[0]获取<decimal></decimal>标记之间的数据。如果我们有两个<decimal></decimal>标签,我们会参考第二个标签设置decVal[1]。

这些数据就是从servlet发送的响应:

<converted-values>
    <decimal>97</decimal>
    <hexadecimal>0x61</hexadecimal>
    <octal>0141</octal>
    <hyper>&0x61;</hyper>
    <binary>1100001B</binary>
</converted-values>





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值