使用 ajax 和 json 来做菜单联动
一、数据库表的建立
数据库的 sql 文件以存放到工程文件当中,下载源码文件即可获得。
1、dao
(1)、接口定义
package cn.wyx.dao;
import java.util.List;
import cn.wyx.model.Area;
public interface AreaDao
{
public List<Area> getAreasByPid(Integer pid);
}
(2)、实现接口当中的抽象方法
package cn.wyx.dao.impl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import cn.wyx.dao.AreaDao;
import cn.wyx.model.Area;
public class AreaDaoImpl implements AreaDao
{
@Override
public List<Area> getAreasByPid(Integer pid)
{
String sql = "select * from wyx_area t where t.area_pid = ?";
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/wyx_demo";
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<Area> aList = new ArrayList<Area>();
try
{
Class.forName(driver);
connection = DriverManager.getConnection(url, "root", "kmust538");
pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, pid);
rs = pstmt.executeQuery();
while (rs.next())
{
Area a = new Area();
int areaId = rs.getInt("area_id");
int pId = rs.getInt("area_pid");
int level = rs.getInt("area_level");
String aName = rs.getString("area_name");
a.setAreaId(areaId);
a.setAreaName(aName);
a.setLevel(level);
a.setPid(pId);
aList.add(a);
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
try
{
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (connection != null)
connection.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
return aList;
}
}
2、模型建立(model)
package cn.wyx.model;
public class Area
{
private Integer areaId;
private String areaName;
private Integer pid;
private Integer level;
public Integer getAreaId()
{
return areaId;
}
public void setAreaId(Integer areaId)
{
this.areaId = areaId;
}
public String getAreaName()
{
return areaName;
}
public void setAreaName(String areaName)
{
this.areaName = areaName;
}
public Integer getPid()
{
return pid;
}
public void setPid(Integer pid)
{
this.pid = pid;
}
public Integer getLevel()
{
return level;
}
public void setLevel(Integer level)
{
this.level = level;
}
}
3、service
(1)、接口定义
package cn.wyx.service;
import java.util.List;
import cn.wyx.model.Area;
public interface AreaService
{
public List<Area> getAreasByPid(Integer pid);
}
(2)、实现接口当中的抽象方法
package cn.wyx.service.impl;
import java.util.List;
import cn.wyx.dao.AreaDao;
import cn.wyx.dao.impl.AreaDaoImpl;
import cn.wyx.model.Area;
import cn.wyx.service.AreaService;
public class AreaServiceImpl implements AreaService
{
private AreaDao ad = new AreaDaoImpl();
@Override
public List<Area> getAreasByPid(Integer pid)
{
return ad.getAreasByPid(pid);
}
}
4、servlet
(1)、LoadProvServlet
package cn.wyx.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.wyx.model.Area;
import cn.wyx.service.AreaService;
import cn.wyx.service.impl.AreaServiceImpl;
public class LoadProvServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
AreaService as = new AreaServiceImpl();
List<Area> provList = as.getAreasByPid(-1);
req.setAttribute("pList", provList);
req.getRequestDispatcher("/area.jsp").forward(req, resp);
}
}
(2)、LoadOptServlet
package cn.wyx.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import cn.wyx.model.Area;
import cn.wyx.service.AreaService;
import cn.wyx.service.impl.AreaServiceImpl;
public class LoadOptServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String pid = req.getParameter("area_pid");
AreaService as = new AreaServiceImpl();
// 根据父节点查询子地区
List<Area> provList = as.getAreasByPid(new Integer(pid));
// 把集合转换成json对象
JSONArray ja = JSONArray.fromObject(provList);
// 把json对象转换成字符串
String result = ja.toString();
resp.setContentType("text/html;charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().write(result);
}
}
5、配置文件 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<servlet>
<servlet-name>areaServlet</servlet-name>
<servlet-class>cn.wyx.servlet.LoadProvServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>areaServlet</servlet-name>
<url-pattern>/loadProv</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>optServlet</servlet-name>
<servlet-class>cn.wyx.servlet.LoadOptServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>optServlet</servlet-name>
<url-pattern>/loadOpt</url-pattern>
</servlet-mapping>
</web-app>
6、前端页面(jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
//定义xmlhttprequest
var xmlHttp;
function ajaxFunction()
{
try
{
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("您的浏览器不支持AJAX!");
return false;
}
}
}
}
function loadOpt(obj, areaType)
{
//创建XMLHttpRequest
ajaxFunction();
var url = "/area_demo/loadOpt";
//打开连接,第一个参数是请求方式,第二个参数是请求地址,第三个参数是同步还是异步,true异步,false是同步
xmlHttp.open('post', url, true);
//如果是post请求必须设置,setRequestHeader必须放在open下面
xmlHttp.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded");
xmlHttp.onreadystatechange = function()
{
//readyState==4请求完成
if(xmlHttp.readyState == 4)
{
//服务器响应正确
if(xmlHttp.status == 200)
{
//接收服务器的响应数据
var result = xmlHttp.responseText;
//alert(result);
var jsonResult = window.eval("("+result+")");
//alert(jsonResult);
if(areaType == 'city')
{
var cityObj1=document.getElementById('city');;
var cityObj2=document.getElementById('district');
if(jsonResult=="")
{
cityObj1.innerHTML = null;
cityObj2.innerHTML = null;
}
else
{
var cityObj = document.getElementById('city');
var optStr = "<option value=\"-2\">--请选择市--</option>";
//alert(jsonResult);
for(var i = 0; i < jsonResult.length; i++)
{
var areaId = jsonResult[i].areaId;
var areaName = jsonResult[i].areaName;
optStr = optStr + "<option value=\""+areaId+"\">"+areaName+"</option>";
}
cityObj2.innerHTML = null;
cityObj.innerHTML = optStr;
}
}
else if(areaType == 'district')
{
var cityObj = document.getElementById('district');
var optStr = "<option value=\"-2\">--请选择区--</option>";
if(jsonResult=="")
{
var cityObj = document.getElementById('district');
cityObj.innerHTML = null;
}
else
{
for(var i = 0; i < jsonResult.length; i++)
{
var areaId = jsonResult[i].areaId;
var areaName = jsonResult[i].areaName;
optStr = optStr + "<option value=\""+areaId+"\">"+areaName+"</option>";
}
cityObj.innerHTML = optStr;
}
}
}
}
}
var data = "area_pid="+obj.value;
//发送数据,如果是get请求数据是在url上传递,不需要发送数据,send必须在最后调用。
xmlHttp.send(data);
}
</script>
</head>
<body>
<table>
<tr>
<td>省
<select id="province" onchange="loadOpt(this,'city')">
<option value="-2">--请选择省--</option>
<c:forEach items="${pList}" var="area">
<option value="${area.areaId}">${area.areaName}</option>
</c:forEach>
</select>
</td>
<td>市
<select id="city" onchange="loadOpt(this,'district')"></select>
</td>
<td>区
<select id="district"></select>
</td>
</tr>
</table>
</body>
</html>
三、效果展示
四、源码文件及数据库表下载
注意:需要 JSTL 标签的相关 jar 包,mysql 数据库驱动包,json 相关的 jar 包。源码文件当中已包含所有需要的 jar 包,同时提供数据库 sql 文件。
如有错误,欢迎指正!