实验报告四:基于AJAX的级联下拉菜单
需求分析:
- 掌握AJAX的原理
- 掌握Jquery框架的AJAX使用
- 基于AJAX实现级联下拉菜单(至少3级)
个人网站(分享学习内容)https://www.yushi.chat/
页面实例展示点我!
https://www.yushi.chat/web/web.html
实验步骤:
-
通过eclipse以及Tomcat架构本地web服务器以展示页面
-
首先设计三级级联下拉菜单的前端样式,即是三个下拉选择框
-
在javascript中使用函数以及AJAX,在用户对前端进行对应操作时,传回数据到后端
-
使用servlet接收前端传回的数据,连接数据库分析省会编号取出市级信息数组传回前端
-
接收后端传回的数组并通过循环操作,动态得将市级信息加入下一级下拉菜单
-
县级下拉菜单制作步骤与市级下拉菜单相同
-
最终通过tomcat发布,并验证整体功能实现,查看是否能实现三级级联下拉菜单
问题及解决办法:
-
在后端接收json数据时尝试在Getpost函数中使用req.getParameter提取数据,但取值为null
经过查询发现,post传递数据在使用req.getParameter方法时需要使用固定编码格式,若格式不对则会接收null,最终使用getReader方法接收数据。
-
在后端传回数据到前端时,需要拼出JSON格式,但省市县的数量并不固定,需要动态创建
经过多次尝试,最终采用JSON数组的方式,并同时将count数量传给前端,以便前端操作。
-
在对网页功能进行测试时发现,更改了省会后市级地区内容只增不减,这不符合需求
在js函数中加入了触发操作后重置市级以及县级下拉菜单中的内容,读到后端数据后再加入其中即可。
html+CSS代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
#line1{
width:230px;
height:50px;
font-size: 20px;
border-radius:20px;
background-color:#99FFFF;
color:#0000CC;
}
#line2{
width:230px;
height:50px;
font-size: 20px;
border-radius:20px;
background-color:#99FFFF;
color:#0000CC;
}
#line3{
width:230px;
height:50px;
font-size: 20px;
border-radius:20px;
background-color:#99FFFF;
color:#0000CC;
}
.slct{
position:absolute;
height:300px;
top:100px;
left:250px;
z-index:4;
}
#image{
background-image:url("1.jpg");
background-size:1152px 1647px;
width:1152px;
height:1647px;
z-index:3;
position:absolute;
}
</style>
</head>
<body>
<div id="image"></div>
<div class="slct">
<select onchange="change1()" id="line1">
<option>省</option>
<option>辽宁省</option>
<option>新疆维吾尔自治区</option>
</select>
<select onchange="change2()" id="line2">
<option>市</option>
</select>
<select id="line3">
<option>县</option>
</select>
</div>
</body>
</html>
<script>
function change1(){
let line2=document.getElementById("line2");
let line3=document.getElementById("line3");
while(line2.firstChild){
line2.removeChild(line2.firstChild);
}
var a=new Option("市");
line2.options.add(a);
while(line3.firstChild){
line3.removeChild(line3.firstChild);
}
var a=new Option("县");
line3.options.add(a);
let xhr = new XMLHttpRequest();
xhr.open('POST',"test1",true);
let data=document.getElementById("line1").value;
xhr.send(data);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// let data = xhr.responseText;
let resp = JSON.parse(xhr.responseText);
for(i=0;i<resp.count;i++){
var x=new Option(resp.sites[i]);
line2.options.add(x);
}
}
};
}
function change2(){
let line2=document.getElementById("line2");
let line3=document.getElementById("line3");
while(line3.firstChild){
line3.removeChild(line3.firstChild);
}
var a=new Option("县");
line3.options.add(a);
let xhr = new XMLHttpRequest();
xhr.open('POST',"test2",true);
let data=document.getElementById("line2").value;
xhr.send(data);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// let data = xhr.responseText;
let resp = JSON.parse(xhr.responseText);
for(i=0;i<resp.count;i++){
var x=new Option(resp.sites[i]);
line3.options.add(x);
}
}
};
}
</script>
servlet代码,分别为test1.java和test2.java
test1.java
package web;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class test1
*/
public class test1 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public test1() {
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
String URL1="jdbc:mysql://你的数据库地址/webform";
String USER="数据库账号";
String PASSWORD="数据库密码";
String provinces = req.getReader().readLine();
resp.setContentType("application/json;charset=utf-8");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
Connection con=DriverManager.getConnection(URL1,USER,PASSWORD);
PreparedStatement psd;
String sql="SELECT num FROM provinces WHERE value='"+provinces+"'";
psd=con.prepareStatement(sql);
ResultSet rs=psd.executeQuery();
rs.next();
int rs2=rs.getInt("num")/1000;
psd=con.prepareStatement("SELECT count(*) from cities where num LIKE '"+rs2+"%'");
rs=psd.executeQuery();
rs.next();
int allcount=rs.getInt(1);
psd=con.prepareStatement("SELECT value from cities where num LIKE '"+rs2+"%'");
rs=psd.executeQuery();
int count=0;
String result="{"+"\"sites\"" +":"+"[";
while(rs.next()) {
count++;
if(count==allcount) {
result+="\""+rs.getString("value")+"\""+"]"+",";
}
else {
result+="\""+rs.getString("value")+"\""+",";
}
}
result += "\"count\":"+count+"}";
resp.getWriter().write(result);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
test2.java
package web;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class test2
*/
@WebServlet("/test2")
public class test2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public test2() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
String URL1="jdbc:mysql://你的数据库地址/webform";
String USER="数据库账号";
String PASSWORD="数据库密码";
String cities = req.getReader().readLine();
resp.setContentType("application/json;charset=utf-8");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
Connection con=DriverManager.getConnection(URL1,USER,PASSWORD);
PreparedStatement psd;
String sql="SELECT num FROM cities WHERE value='"+cities+"'";
psd=con.prepareStatement(sql);
ResultSet rs=psd.executeQuery();
rs.next();
int rs2=rs.getInt("num")/10;
psd=con.prepareStatement("SELECT count(*) from counties where num LIKE '"+rs2+"%'");
rs=psd.executeQuery();
rs.next();
int allcount=rs.getInt(1);
psd=con.prepareStatement("SELECT value from counties where num LIKE '"+rs2+"%'");
rs=psd.executeQuery();
int count=0;
String result="{"+"\"sites\"" +":"+"[";
while(rs.next()) {
count++;
if(count==allcount) {
result+="\""+rs.getString("value")+"\""+"]"+",";
}
else {
result+="\""+rs.getString("value")+"\""+",";
}
}
result += "\"count\":"+count+"}";
resp.getWriter().write(result);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}