实现效果
完整代码
链接:https://pan.baidu.com/s/1nvkSNVV 密码:qsyb
1 创建项目及准备工作
DAY11-01-AJAX-DropDownMenu Maven的war项目
导入springmvc和jackson的jar包
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
</dependencies>
web.xml
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
applicationContext.xml
<context:component-scan base-package="cn.tedu.spring" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
<value>application/json;charset=utf-8</value>
<value>*/*;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
2 设计数据
----- 请选择 -----
1.广东省 1.广州,2.深圳,3.珠海
2.河北省 4.石家庄,5.保定,6.秦皇岛
3 设计服务端的功能:
URL : getCities.do
请求类型:GET
参数:provinceId
返回:ResponseResult,其中的数据部分是List<City>,City中至少封装id,name
a) 创建cn.tedu.spring.bean.ResponseResult,属性包括:int state,String message,Object data;
package cn.tedu.spring.bean;
public class ResponseResult {
private int state;
private String message;
private Object data;
public ResponseResult() {
super();
}
public ResponseResult(int state) {
super();
this.state = state;
}
public ResponseResult(int state, String message) {
super();
this.state = state;
this.message = message;
}
public ResponseResult(int state, Object data) {
super();
this.state = state;
this.data = data;
}
public ResponseResult(int state, String message, Object data) {
super();
this.state = state;
this.message = message;
this.data = data;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
- b) 创建cn.tedu.spring.bean.City,属性包括:int id,String name;
package cn.tedu.spring.bean;
public class City {
private int id;
private String name;
public City() {
super();
}
public City(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- c) 创建cn.tedu.spring.controller.CityController,添加public String getCities(int provinceId)方法,映射到getCites.do路径,在方法内部,根据参数provinceId进行判断,然后得到List<City>,封装到ResponseResult中,最后转换为JSON字符串,作为方法的返回值
@Controller
public class CityController {
@RequestMapping("getCities.do")
@ResponseBody
public String getCities(int provinceId){
List<City> cityes = new ArrayList<City>();
switch (provinceId){
case 1:
cityes.add(new City(1,"广州"));
cityes.add(new City(2,"深圳"));
cityes.add(new City(3,"珠海"));
case 2:
cityes.add(new City(4,"石家庄"));
cityes.add(new City(5."保定"));
cityes.add(new City(6,"秦皇岛"));
break;
default:
break;
}
}
}
- d) 通过浏览器测试
4 创建前端页面index.html,并添加2个下拉菜单,其中第1个下拉菜单中添加1广东省、2河北省这2个有效选项。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax -- 二级联动菜单</title>
</head>
<body>
<select style="width: 120px;" onchange="getCities(this.value)">
<option value="0">----- 请选择 -----</option>
<option value="1">广东省</option>
<option value="2">河北省</option>
</select>
<select style="width: 120px;" id="cities">
</select>
</body>
</html>
5 设计AJAX请求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax -- 二级联动菜单</title>
<script type="text/javascript">
function $(id) {
return document.getElementById(id);
}
function getXMLHttpRequest() {
var xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveObject("Microsoft.XMLHttp");
}
return xmlhttp;
}
function getCities(provinceId) {
// 无论选中哪个选项,先清空“城市”列表
while ($("cities").firstChild) {
$("cities").removeChild($("cities").firstChild);
}
// 判断provinceId是否有效
if (provinceId == 0) {
return;
}
// 获取XMLHttpRequest
var xmlhttp = getXMLHttpRequest();
// 设计响应函数
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// 获取响应的正文文本
var text = xmlhttp.responseText;
// 将响应的正文文本转换为JSON对象
var jsonObject = JSON.parse(text);
// 判断JSON对象中state是否正确
if (jsonObject.state == 1) {
// 遍历JSON对象中的data对应的数组
for (var i = 0; i < jsonObject.data.length; i++) {
// 将数组中的每个数据设计为一个个<option>
var opt = document.createElement("option");
// <option value="3">珠海</option>
// "data":[
// {"id":1,"name":"广州"},
// {"id":2,"name":"深圳"},
// {"id":3,"name":"珠海"}
// ]
opt.value = jsonObject.data[i].id;
opt.innerHTML = jsonObject.data[i].name;
// 将<option>添加到“城市”列表中
$("cities").appendChild(opt);
}
}
}
};
// 发出请求
var url = "getCities.do?provinceId=" + provinceId;
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
</script>
</head>
<body>
<select style="width: 120px;" onchange="getCities(this.value)">
<option value="0">----- 请选择 -----</option>
<option value="1">广东省</option>
<option value="2">河北省</option>
</select>
<select style="width: 120px;" id="cities">
</select>
</body>
</html>
测试效果
AJAX的数据缓存问题
如果反复向同一个URL发出请求,并且请求参数没有发生变化的话,可能会获取到缓存的数据,即获取到的不是最新数据!
针对这个问题的解决方案:使得每次请求参数都不同!例如为每次的请求多添加1个参数,参数名可以自定义,参数值使用随机数即可!
jQuery AJAX 实现二级联动
JQuery AJAX - load()
在使用了JQuery后,关于AJAX的应用也得到了极大的简化,通过load()函数可以快速的提交AJAX的异步请求,并且将响应的结果填充到某个标签中。
注意:这种做法适用于(但不局限于)将结果直接填充到标签中!
这种做法的语法格式是:
$(选择器).load(URL,参数);
在以上语法中,$(选择器)表示需要将结果填充到哪个标签中,URL表示请求路径,参数表示发出请求时向服务器提交的参数,参数值的格式可以是字符串格式,例如:
username=tomcat&password=123456
参数值的格式还可以是JSON对象格式:
{"username":"tomcat","password":"123456"}
其实,load()函数的完整格式是:
$(选择器).load(URL,参数,处理响应结果的函数);
也就是说,load()函数还可以有第3个参数,第3个参数是一个函数,专门用于处理结果,类似于传统方式中的xmlhttp.onreadystatechange属性的值。
另外,其实在jQuery中,还有另一个也叫做load()的函数,也是被某个标签对象所调用的,但是,其参数是某个函数,用于表示标签加载完成时的自定义处理,这2个load()函数,至于执行的是哪个,取决于参数的设计。
- 1 引入jQuery
- 2 添加load.html页面,使用load()函数提交AJAX请求
load.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JQuery AJAX -- load</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
function loadContent(){
$("#content").load("getCities.do","provinceId=1");
}
</script>
</head>
<body>
<div id="content" style="border:1px solid #999; width:300px;height:200px;"></div>
<p>
<input type="button" value="使用JQuery提交AJAX请求" onclick="loadContent()" />
</p>
</body>
</html>
- 3 测试效果
jQuery AJAX - ajax()
在使用jQuery时,通过ajax()函数可以设置AJAX请求过程中所有的可设置项!
使用ajax()的基本语法是:
$.ajax({配置});
以上语法中,“配置”及左右两侧的{}整体表现为一个JSON对象格式。
在“配置”中,通常会设置的属性有:
url:请求的路径
例如:
$.ajax({
"url":"getCities.do",
"success":function(obj){
}
});
还会设置的属性有:
type:请求的类型(请求方式),取值为"GET"或"POST"
data:请求的参数,参数值可以是字符串格式的,也可以是JSON对象格式的
dataType:响应结果的数据的类型,常用的取值有"text"、"json",当取值为"text"时,后续success属性对应的处理函数中的参数将是字符串类型的,当取值为"json"时,后续success属性对应的处理函数中参数将是JSON对象
success:成功得到响应结果时的处理函数,即该属性的值是某个函数,该函数仅会在成功得到响应结果后被调用,所以,在函数内部,无须再判断状态码为4或响应码为200,并且,在编写处理函数时,请为该函数添加参数,参数名称可自行定义,参数将是成功得到响应结果时的响应结果,类似于xmlhttp.responseTest
在配置以上属性时,不区分先后顺序,即先配置哪个,并没有要求!
除此以外,ajax()函数还可以配置许多属性,如有需要,请参考相关文档。
- 1 使用$.ajax({配置});提交AJAX请求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JQuery Ajax -- 二级联动菜单</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
// 为了便于可能存在的事件绑定,
// 凡是与事件相关的函数,
// 能不定义参数就不要定义参数
// 对于那些动态的、可能变化的值,
// 推荐在函数内部去动态获取
function getCities(){
// 清空“城市”的下拉列表
$("#cities").empty(); // 相当于 innerHTML=""
// 获取当前选中的“省份”的value
var pid = $("#provinces").val();
// 如果获取到的是0,则不处理
if(pid == 0){
return;
}
// 发出请求并处理响应结果
$.ajax({
"url":"getCities.do", // 请求地址
"type":"GET", // 请求方式
"data":"provinceId="+pid, // 请求参数
"dataType":"json", // 服务器返回的数据类型
"success":function(obj){ // 服务器处理正常对应的回调函数
// 判断JSON对象中的state
if(obj.state == 1){
//"data":[
// {"id":1,"name":"广州"},
// {"id":2,"name":"深圳"},
// {"id":3,"name":"珠海"}
//]
// 遍历JSON对象中的data(数组)
for(var i = 0;i<obj.data.length;i++){
// 创建<option>的HTML代码(字符串)
var op = "<option value="+obj.data[i].id+">"+obj.data[i].name+"</option>"
// 将<option>的HTML代码添加到"城市"下拉菜单
$("#cities").append(op);
}
}
}
});
}
</script>
</head>
<body>
<h3>jQuery Ajax -- 二级联动菜单</h3>
<select id="provinces" style="width: 120px" onchange="getCities()">
<option value="0">----- 请选择 -----</option>
<option value="1">广东省</option>
<option value="2">河北省</option>
</select>
<select style="width: 120px;" id="cities">
</select>
</body>
- 2 测试效果
- 3 动态效果
回顾
[*****] HTML
用于规划网页内容,需要掌握有哪些标签,什么时候用什么标签,什么样的标签默认有什么样式
[***] CSS
[***] Javascript
处理界面与用户的交互
[***] jQuery
[*****] jQuery AJAX
[***] Servlet
用于接收用户的请求,并向客户返回响应结果。
需要掌握:定位、注册、注册时配置参数
[**] Filter
用于对请求进行过滤,运行在Servlet之前
需要掌握:字符编码过滤器
[*****] JSP
向客户端提供响应的视图
需要掌握:EL、JSTL
a + b
a > b
EL是表达式,JSTL进行逻辑处理
[*****] SQL
需要掌握:创建库、创建表、增删改查、关联表查询、事务
需要了解:聚合函数、Having、Group By、存取过程、触发器
[*****] Spring
Spring解决了创建对象的问题,使得开发者可以不通过new语法获取对象。
DI(依赖注入)是实现的手段,IOC(控制反转)是最终的实现效果。
*****] Spring MVC
Spring MVC提供完整的接收请求、分发请求、响应请求的机制,最终表现为开发者可以自定义Controller类,并在Controller自定义方法去处理请求。