Ajax读取xml

一、向服务端读取xml 

页面jsp的Ajax读取xml和上一篇的Ajax读取方法一样,只不过responseText变成了responseXML。

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/9/16
  Time: 11:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>Ajax读取xml</title>
    <script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.js"></script>
    <%
        String path=request.getSession().getServletContext().getContextPath();
    %>
    <script>
        $(function () {
            var xmlHttpRequest=createXmlHttpRequest();
            xmlHttpRequest.open("post","<%=path%>/XMLServlet");
            xmlHttpRequest.send(null)
            xmlHttpRequest.onreadystatechange=function () {
                if(xmlHttpRequest.status==200&&xmlHttpRequest.readyState==4){
                    var xmlObject=xmlHttpRequest.responseXML;
                    var emp=xmlObject.getElementsByTagName("emp")[0];
                    var empno=xmlObject.getElementsByTagName("empno")[0];
                    var empname=xmlObject.getElementsByTagName("empname")[0];
                    console.log(empno);
                    console.log(empname.firstChild.nodeValue)
                }

            }
        })

        function createXmlHttpRequest() {
            if(window.XMLHttpRequest){
                xmlHttpRequest=new XMLHttpRequest();
            }else {
                xmlHttpRequest=new ActiveXObject("Microsoft.XMLHttp");
            }
            return xmlHttpRequest;
        }
    </script>
</head>
<body>

</body>
</html>

后台Servlet用DOM方法创建xml,再返回给客户端:

package test;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.text.Format;

@WebServlet(urlPatterns = "/XMLServlet")
public class XMLServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/xml");
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder=factory.newDocumentBuilder();
            Document document=builder.newDocument();
            document.setXmlStandalone(true);
            Element allEmps=document.createElement("allEmps");
            Element emp=document.createElement("emp");
            Element empno=document.createElement("empno");
            Element empname=document.createElement("empname");

            empno.setTextContent("1");
            empname.setTextContent("小明");
            document.appendChild(allEmps);
            allEmps.appendChild(emp);
            emp.appendChild(empno);
            emp.appendChild(empname);

            TransformerFactory tff=TransformerFactory.newInstance();
            Transformer tf=tff.newTransformer();
            //换行
            tf.setOutputProperty(OutputKeys.INDENT, "yes");

            Writer out=response.getWriter();
            tf.transform(new DOMSource(document),new StreamResult(out));


        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行结果:

 

二、Ajax实现二级联动菜单

很多用户提交表单都会出现像下图这样的联动菜单,在没有学过Ajax之前,我们通常需要让服务端把所有的省份封装到List中放到request里,再把所有省份对应的城市封装到Map中再放到request里。这样做也可以实现联动,但是它需要把所有城市一次性查询出来。数据量小的话问题不大,但是如果数据量很大的话呢?所以更好的实现方式是利用Ajax,每次选择一个省份后,都发起一次Ajax请求,服务端只返回该省份的所有城市,大大减少了数据量。

代码

页面jsp:

<%@ page import="java.util.Set" %>
<%@ page import="java.util.Iterator" %><%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/9/16
  Time: 16:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>二级菜单</title>
    <%
        String path=request.getSession().getServletContext().getContextPath();
    %>
    <script>
        window.onload=function () {
            var select=document.getElementById("province");
            select.onchange=function () {
                var value=select.value;
                if(window.XMLHttpRequest){
                    var xmlHttpRequest=new XMLHttpRequest();
                }else {
                    var xmlHttpRequest=new ActiveXObject("Microsoft.XMLHttp");
                }
                xmlHttpRequest.open("post","<%=path%>/cascadeServlet?province="+value);
                xmlHttpRequest.send(null)
                xmlHttpRequest.onreadystatechange=function () {
                    if(xmlHttpRequest.status==200&&xmlHttpRequest.readyState==4) {
                        var xmlObject = xmlHttpRequest.responseXML;
                        var cities = xmlObject.getElementsByTagName("name");

                        var citySelect = document.getElementById("city");
                        //清空下拉列表
                        citySelect.length=1;
                        for (var i = 0; i < cities.length; i++) {
                            var option = document.createElement("option");
                            var text = document.createTextNode(cities[i].firstChild.nodeValue);
                            option.appendChild(text);
                            citySelect.appendChild(option);
                        }
                    }

                }
            }
        }
    </script>
</head>
<%
    Set<String> ps=(Set)request.getAttribute("ps");
    Iterator i=ps.iterator();
%>
<body>
    <select id="province" name="province">
        <option >请选择省份</option>
        <%
            while (i.hasNext()){
                String pName=(String) i.next();
        %>
        <option value="<%=pName%>"><%=pName%></option>
        <%
            }
        %>

    </select>
    <select id="city" name="city">
        <option >请选择城市</option>

    </select>
</body>
</html>

后台返回省份及城市:因为重点是Ajax是如何实现的,所以我用了Map存储省份和城市代替数据库。省份反正都是一次性显示所有省,所以不用Ajax,直接用List封装并放到request中。

package test;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.Writer;
import java.util.*;

@WebServlet(urlPatterns = "/cascadeServlet")
public class CascadeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/xml");

        //创建省份与城市的Map
        Map<String,List<String>> map=new HashMap();
        List<String> zhejiang=new ArrayList<>();
        zhejiang.add("宁波");
        zhejiang.add("杭州");
        zhejiang.add("温州");
        List<String> fujian=new ArrayList<>();
        fujian.add("厦门");
        fujian.add("福州");
        fujian.add("泉州");
        map.put("福建",fujian);
        map.put("浙江",zhejiang);

        Set ps=map.keySet();
        String province=request.getParameter("province");
        //province参数为null说明没有选中省份
        if (province==null){
            request.setAttribute("ps",ps);
            request.getRequestDispatcher("test/cascadeMenu.jsp" ).forward(request,response);
            return;
        }

        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder=factory.newDocumentBuilder();
            Document document=builder.newDocument();
            document.setXmlStandalone(true);
            Element root=document.createElement("city");
            List<String> cities=map.get(province);
            for (String city:cities){
                Element c=document.createElement("name");
                c.setTextContent(city);
                root.appendChild(c);
            }
            document.appendChild(root);

            //向页面输出xml操作
            TransformerFactory tff=TransformerFactory.newInstance();
            Transformer tf=tff.newTransformer();
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            Writer out=response.getWriter();
            tf.transform(new DOMSource(document),new StreamResult(out));

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值