文章目录
一.事件驱动编程
-
事件驱动编程
- 所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数).当然事件不仅限于用户的操作. 当对象处于某种状态时,可以发出一个消息通知,然后对这个消息感兴趣的程序就可以执行。
-
事件驱动编程中的几个核心对象
- 事件源:谁发出事件通知,发出消息;也就是事件主体(通常指元素和标签);
- 事件名称:发出什么样的通知的名称,比如鼠标到我头上了,我被别人点了一下;
- 事件响应函数:谁对这个这个事件感兴趣,当这个事件发生时要执行什么样的操作;
- 事件对象:一般来说,当事件发生时,会产生一个描述该事件的具体对象,包括具体的参数等一起发给响应函数,好让他们通过事件对象来了解事件更加详细的信息。
二.事件绑定
事件监听,也就是指对指定对象的指定事件指定响应处理处理函数;
-
第一种:
在标签上使用onclick属性配置事件源: 点我呀这个button, 可以在调用响应函数中传入this获取 事件名称:onclick 响应函数:clickMe 事件对象:可以在响应函数中传入event获取
注意: 此方式无法重复绑定响应函数
-
第二种:
在js代码中,使用 "元素.οnclick=响应函数"进行事件监听 -
第三种:
使用方法来完成对元素的监听IE [Object].attachEvent(“name_of_event_handler”, fnHandler); name_of_event_handler : 事件名称: 注意:事件操作前,必须加"on"!!! fnHandler: 响应函数 多次添加监听后,触发顺序: 先添加,后执行 [Object].detachEvent(“name_of_event_handler”, fnHandler); fnHandler : 移除时,传入的"事件响应函数",必须和添加时,传入的是同一个(通过相同标识符引用的那一个函数) 匿名函数,每次创建的都不同 W3C [Object].addEventListener(“name_of_event”, fnHandler); name_of_event: 事件名称: 直接使用事件(操作)名称 (没有 on) 多次添加监听后,触发顺序: 先添加,先执行 fnHandler: 响应函数 [Object].removeEventListener(“name_of_event”, fnHandler); fnHandler : 移除时,传入的"事件响应函数",必须和添加时,传入的是同一个(通过相同标识符引用的那一个函数) 匿名函数,每次创建的都不同
-
定义一个通用的添加事件的函数
function addListener(element,eventName,eventFn){
if(element.attachEvent){
element.attachEvent("on"+eventName,eventFn);
}else{
element.addEventListener(eventName,eventFn);
}
}
事件对象中包括了事件源及事件的具体描述信息,一般包括事件源,鼠标事件或键盘事件的相关信息;在监听函数中有时候需要通过事件对象来获取更详细的事件信息,然后再进行处理
oDiv.onclick = function (oEvent) {
//参数oEvent即为事件对象
}
实例.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="indext.js"></script>
<title>Insert title here</title>
</head>
<body>
<!-- 用户触发按钮之后,js引擎自动创建event对象 -->
<button onclick="onclickMe(this,event)" id="btn">方式1:点我呀</button><br>
<button id="btn2">方式二.点我呀</button><br>
<button id="btn3">方式三.点我呀</button><br>
</body>
</html>
index.js
//方式二:
window.onload=function (){
//方式二,通过js代码方式指定事件
var btn2 = document.getElementById("btn2");
//事件源:btn2,在匿名的function中,打印的this就是事件源,没有srcEl这个参数
//事件名称:onclick
//相应函数:匿名funcion
btn2.onclick=function(event){
console.log(event);
//console.log(srcEl);//不存在
console.log(this);
alert("我又被点了~~");
};
//方式2,事件无法重复绑定,如果重复绑定,后面的会覆盖前面的
btn2.onclick=function(event){
console.log(event);
//console.log(srcEl);//不存在
console.log(this);
alert("我又又被点了~~");
};
//方式三:
/*//IE:
var btn3= document.getElementById("btn3");
//事件源:btn3
//事件名称:attachEvent方法的第一个参数
//响应函数:匿名函数function
//事件对象:匿名function的第一个参数
//参数1:事件名称
//参数2:响应函数
btn3.attachEvent("onclick",function(eventObject){
alert("我怎又又被点击");
console.log(eventObject);//event
console.log(this);//window
});
//可以重复绑定,倒序执行
btn3.attachEvent("onclick",function(eventObject){
alert("我怎又又被点击");
console.log(eventObject);//event
console.log(this);//window
});*/
/*//W3C
var btn3= document.getElementById("btn3");
//方式三:
//事件源:btn3,匿名function 内部this
//事件名称:addEventListener方法的第一个参数
//响应函数:function
//事件对象:匿名function第一个参数
//参数1:事件名称 点击事件(onclick)
btn3.addEventListener("click",function(eventObject){
alert("我怎又又被点击");
console.log(this);//window
console.log(eventObject);//
});
//可以重复绑定,顺序执行
btn3.addEventListener("click",function(eventObject){
alert("我怎又又被点击");
console.log(this);//
console.log(eventObject);//
});*/
//通用事件绑定
addEvent(btn3,"click",function(){
alert("我怎又又又被点击");
});
};
//设计一个方法:统一事件的绑定,既可以绑定IE,又可以实现W3C绑定
/**
*
* @param srcEl: 事件源
* @param eventType: 事件名称,IE拼接on
* @param fnHandler: 统一处理函数
* @returns
*/
function addEvent(srcEl,eventType,fnHandler){
//attachEvent 方法是IE方法,如果有值就是IE浏览器,反之就是W3C
if(srcEl.attachEvent){//IE
srcEl.attachEvent("on"+eventType,fnHandler);
}else{//W3C
srcEl.addEventListener(eventType,fnHandler);
}
}
//方式1:在onclick属性设置事件
//事件源: 点我呀这个button,可以在相应函数中传入this获取
//时间名称:onclick 点击事件
//事件处理函数: onclickMe
//事件对象:可以在相应函数中传入event获取
function onclickMe(srcEl,event){
//根据id获取事件源
console.log(document.getElementById("btn"));
//根据this获取事件源
console.log(srcEl);
console.log(this);
console.log(event);
//函数中自带的参数对象,用来包装调用者传入的参数
console.log(arguments);
alert("你真点啊!");
}
三.事件相关
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="indext.js"></script>
<title>Insert title here</title>
</head>
<body>
<img alt="" src="01.gif" id="myImg">
</body>
</html>
index.js
window.onload=function(){
var imgEl = document.getElementById("myImg");
addEvent(imgEl,"mouseout",function(){
imgEl.src="01.gif";
});
addEvent(imgEl,"mouseover",function(){
imgEl.src="02.gif";
});
addEvent(imgEl,"click",function(){
imgEl.src="03.gif";
});
};
//设计一个方法:统一事件的绑定,既可以绑定IE,又可以实现W3C绑定
/**
*
* @param srcEl: 事件源
* @param eventType: 事件名称,IE拼接on
* @param fnHandler: 统一处理函数
* @returns
*/
function addEvent(srcEl,eventType,fnHandler){
//attachEvent 方法是IE方法,如果有值就是IE浏览器,反之就是W3C
if(srcEl.attachEvent){//IE
srcEl.attachEvent("on"+eventType,fnHandler);
}else{//W3C
srcEl.addEventListener(eventType,fnHandler);
}
}
四.综合练习
多选框的选择
checkbox.html
<!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>checkbox</title>
<script type="text/javascript" src="checkbox.js" ></script>
</head>
<body>
请选择你的爱好:<br/>
<input type="checkbox" onchange="checkChange(this)" id="checkAll"/>全选/全不选<br/>
<div>
<input type="checkbox" name="hobby"/>JAVA
<input type="checkbox" name="hobby"/>打篮球
<input type="checkbox" name="hobby"/>上网
<input type="checkbox" name="hobby"/>撩妹
</div>
<div>
<input type="button" id="btn_checkAll" onclick="checkAll(true)" value="全选"/>
<input type="button" onclick="checkAll(false)" value="全不选"/>
<input type="button" onclick="checkUnAll()" value="反选"/>
</div>
</body>
</html>
checkbox.js
//全选/全不选
function checkAll(value){
//1.获取全部hobby
var hobbys = document.getElementsByName("hobby");
//2.遍历所有
for(var i = 0;i < hobbys.length; i++ ){
hobbys[i].checked=value;
}
};
//反选
function checkUnAll(){
//1.获取全部hobby
var hobbys = document.getElementsByName("hobby");
for(var i = 0;i < hobbys.length; i++){
hobbys[i].checked=!hobbys[i].checked;
}
};
//全选/全不选
//srcEl 页面传进来的事件源
function checkChange(srcEl){
//1: 获取上面id为checkAll多选框 状态
//2:获取所有要勾选多选框
//3:遍历这些多选框,改变他们的值
//为true是表示全选,为false时为全不选
checkAll(srcEl.checked);
};
select移动
select.html
<!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>选择列表</title>
<script type="text/javascript" src="select.js" ></script>
</head>
<body>
<table border="1">
<tr>
<td>
<select id="select1" style="width:100px;height:200px" size="10" multiple="multiple">
<option value="选项1">选项1</option>
<option value="选项2">选项2</option>
<option value="选项3">选项3</option>
<option value="选项4">选项4</option>
<option value="选项5">选项5</option>
<option value="选项6">选项6</option>
<option value="选项7">选项7</option>
<option value="选项8">选项8</option>
<option value="选项9">选项9</option>
</select>
</td>
<td align="center">
<input type="button" onclick="moveSelected('select1','select2')" value="-->"/><br/>
<input type="button" onclick="moveAll('select1','select2')" value="==>"/><br/>
<input type="button" onclick="moveSelected('select2','select1')" value="<--"/><br/>
<input type="button" onclick="moveAll('select2','select1')" value="<=="/>
</td>
<td>
<select id="select2" style="width:100px;height:200px" size="10" multiple="multiple"></select>
</td>
</tr>
</table>
</body>
</html>
select.js
//全部移动
function moveAll(srcId,targetId){
//1:获取源select的所有option
var srcId=document.getElementById(srcId);
var ops = srcId.children;
//2:所有option添加到目标
var targetId = document.getElementById(targetId);
//一个一个往里面塞,不能一次性移动
/*for(var i = 0;i < ops.length;i++){
targetId.appendChild(ops[i]);
}*/
//当options有值的时候一直移动索引为0这个值
while(ops.length>0){
targetId.appendChild(ops[0]);
}
}
//选中移动
function moveSelected(srcEl,targetEl){
var srcEl = document.getElementById(srcEl);
//选中的options
var ops = srcEl.selectedOptions;
var targetEl = document.getElementById(targetEl);
//当options有值的时候一直移动索引为0这个值
while(ops.length>0){
targetEl.appendChild(ops[0]);
}
}
user添加与删除
user.html
<!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>用户新增</title>
<script type="text/javascript" src="user.js" ></script>
</head>
<body>
<form name="userForm">
<center>
用户录入<br/>
用户名:<input id="username" name="username" type="text" size=15/>
E-mail:<input id="email" name="email" type="text" size=15/>
电话:<input id="tel" name="tel" type="text" size=15/>
<input type="button" value="添加" id="btn_submit"/>
<input type="button" value="删除所有" id="btn_removeAll"/>
</center>
</form>
<hr/>
<table border="1" align="center" cellpadding=0 cellspacing=0 width=400>
<thead>
<tr>
<th>用户名</th>
<th>E-mail</th>
<th>电话</th>
<th>操作</th>
</tr>
</thead>
<tbody id="userTbody">
<tr id="0001">
<td>张无忌</td>
<td>wujizhang@163.com</td>
<td>18212345678</td>
<td><a href="javascript:delRow('0001')">删除</a></td>
</tr>
</tbody>
</table>
</body>
</html>
user.js
window.onload=function (){
//1:获取添加按钮
var addBtn= document.getElementById("btn_submit");
//2:绑定一个点击事件
addBtn.onclick=function(){
//1.获取name,email,tel值
var nameV=document.getElementById("username").value;
var emailV=document.getElementById("email").value;
var telV=document.getElementById("tel").value;
//2.创建出相关的元素 tr/td
var trEl = document.createElement("tr");
//使用当前时间的毫秒数做id
var idV = new Date().getTime();
trEl.id=idV;
var nameEl = document.createElement("td");
var eamilEl = document.createElement("td");
var telEl = document.createElement("td");
var opEl = document.createElement("td");
//设置td的内容
nameEl.innerHTML = nameV;
eamilEl.innerHTML = nameV;
opEl.innerHTML = nameV;
opEl.innerHTML="<a href='javascript:delRow(\""+idV+"\")'>删除</a>";
//3.设置tr td tbody的关系
trEl.appendChild(nameEl);
trEl.appendChild(eamilEl);
trEl.appendChild(telEl);
trEl.appendChild(opEl);
var tbody= document.getElementById("userTbody");
tbody.appendChild(trEl);
};
//删除所有的按钮
var removeAllBtn= document.getElementById("btn_removeAll");
removeAllBtn.onclick=function(){
var tbody=document.getElementById("userTbody");
//把tbody的内容为空字符串
tbody.innerHTML="";
};
};
//定义删除行的方法
function delRow(trId){
var trEl = document.getElementById(trId);
//找到父类删除自己
trEl.parentNode.removeChild(trEl);
}
五.AJAX
概述
- Ajax不是一项具体的技术,而是几门技术的综合应用。
Javascript、XHTML和CSS、DOM、XML和XMLHttpRequest。 - Ajax核心只不过是要在javascript中调用一个叫XMLHttpRequest类,这个类可以与Web服务器使用HTTP协议进行交互,程序不通过浏览器发出请求,而是用这个特殊的JavaScript对象发送请求和接收响应。
- XMLHttpRequest对象在网络上的俗称为Ajax对象。
- 一种不用刷新整个页面便可与服务器通讯的办法(更新网页部分数据).
AJAX缺陷:
- AJAX大量使用了Javascript和AJAX引擎,而这个取决于浏览器的支持。IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla虽然也支持AJAX,但是提供XMLHttpRequest的方式不一样。所以,使用AJAX的程序必须测试针对各个浏览器的兼容性。
- AJAX更新页面内容的时候并没有刷新整个页面,因此,网页的后退功能是失效的;有的用户还经常搞不清楚现在的数据是旧的还是已经更新过的。这个就需要在明显位置提醒用户“数据已更新”。
- 对流媒体的支持没有FLASH、Java Applet好。 HTML5
- Ajax不支持跨域访问
六.获取服务端的时间-后台
先搭建java web项目结构
需要jar包
后台
mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- IoC注解解析器-->
<context:component-scan base-package="cn.dusk"/>
<!-- DI注解驱动器 -->
<context:annotation-config/>
<!-- 注解驱动器 -->
<mvc:annotation-driven/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--过滤器-->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置SpringMVC的前端控制器-->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
GetTimeController类
@Controller
public class GetTimeController {
@RequestMapping("getTime")
public void getTime(HttpServletResponse response) throws Exception {
response.setContentType("text/html;charaset=utf-8");
Date date = new Date();
response.getWriter().write(date.toLocaleString());
}
}
前端
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
北京时间:<span id="sp">暂时没有时间</span><br>
<button id="getTime">获取系统时间</button>
</body>
</html>
index.js
window.onload=function(){
var btn = document.getElementById("getTime");
btn.onclick=function(){
//使用ajax的请求获取系统当前时间
//1.创建一个ajax对象
var ajax = createAjax();
//2.创建一个http请求对象
/**
* 参数1:http请求方式 get post
* 参数2:http请求url
* 参数3:是否为异步请求 默认true
*/
//解决浏览器缓存的问题
ajax.open("get","/getTime.do?time"+ new Date().getTime(),true);
//3. 绑定htttp状态改变的监听器,处理请求结果
ajax.onreadystatechange=function(){
//当readState等于4的时候,表示数据请求已经回来了,
//通知浏览器处理数据,进而改变页面元素的值
//此时ajax提供一种状态改变机制,当readState状态为4时,表示ajax返回完毕
//并且能正常返回数据的时候,才进行操作
var sp = document.getElementById("sp");
if(ajax.readyState == 4 && ajax.status == 200){
sp.innerHTML=ajax.responseText;
}else{
sp.innerHTML="亲,网络繁忙,请稍后访问~~";
}
}
//4:发送http请求 参数表示传递post 才使用的
ajax.send();
};
};
//通用的ajax对象创建
function createAjax(){
var jaax = null;
try{
ajax = new XMLHttpRequest();
}catch(e){
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
return ajax;
}
七.检查账号是否存在
CheckNameController类
@Controller
public class CheckNameController {
@RequestMapping("checkName")
public void checkName(String username,HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
if ("admin".equals(username)) {
response.getWriter().write("该用户已经被注册了");
}else {
response.getWriter().write("恭喜你,该用户可以注册");
}
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
账号:<input type="text" name="usernmae" id="nameId"/>
<span id="sp"></span>
</body>
</html>
index.js
//页面加载完毕绑定时间
window.onload=function(){
var inpEl = document.getElementById("nameId");
//失去焦点时间
inpEl.onblur=function(){
//发送请求,检查用户是否存在
var ajax = new XMLHttpRequest();
//创建http请求对象
ajax.open("get","/checkName.do?username="+inpEl.value,true);
//设置http请求状态监听,并处理结果
ajax.onreadystatechange=function(){
//请求结果接收完毕,并且请求状态200时候再处理
var sp = document.getElementById("sp");
if(ajax.readyState == 4 && ajax.status==200){
sp.innerHTML = ajax.responseText;
}else{
sp.innerHTML="亲网络范萌,请稍后再试~~";
}
}
//发送请求
ajax.send();
}
}
八.用户登录操作
LoginController类
@Controller
public class LoginController {
@RequestMapping("login")
public void login(String username,String password,HttpServletResponse response) throws IOException {
if ("admain".equals(username) && "12".equals(password)) {
response.getWriter().write("登录成功");
}else {
response.getWriter().write("账号密码不正确");
}
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
账号:<input type="text" name="username" id="nameId"/><br>
密码:<input type="text" name="password" id="passwordId"/><br>
<input type="button" value="登录" id="btn"/><br>
<span id="sp"></span><br>
</body>
</html>
inex.js
//页面加载完毕绑定时间
window.onload=function(){
var inpEl = document.getElementById("nameId");
var pwdId = document.getElementById("passwordId");
var btn = document.getElementById("btn");
//失去焦点时间
btn.onclick=function(){
//发送请求,检查用户是否存在
var ajax = new XMLHttpRequest();
//创建http请求对象
ajax.open("post","/login.do",true);
//设置http请求状态监听,并处理结果
ajax.onreadystatechange=function(){
//请求结果接收完毕,并且请求状态200时候再处理
var sp = document.getElementById("sp");
if(ajax.readyState == 4 && ajax.status==200){
sp.innerHTML = ajax.responseText;
}else{
sp.innerHTML="亲网络范萌,请稍后再试~~";
}
}
//在post请求提交之前,需要设置参数,编码格式
//设置请求头
ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
//post请求参数拼接个get一样
var params = "username="+inpEl.value+"&password="+pwdId.value;
console.log(params);
//post请求参数可以设置在send方法中
//发送请求
ajax.send(params);
}
}
九.二级联动HTML格式
省份数据Province
/**
* 省份对象
*/
public class Province {
private Long id;//id
private String name;//省份名字
public Province() {
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public Province(Long id, String name) {
this.id = id;
this.name = name;
}
//获取所有的的省份信息
public static List<Province> getAllProvince() {
List<Province> provinces = new ArrayList<Province>();
provinces.add(new Province(1L, "湖南"));
provinces.add(new Province(2L, "广东"));
provinces.add(new Province(3L, "湖北"));
return provinces;
}
public String toString() {
return "Province [id=" + id + ", name=" + name + "]";
}
}
City数据
/**
* 城市对象
*/
public class City {
private Long id;
private String name;
public City() {
}
public City(Long id, String name) {
this.id = id;
this.name = name;
}
/**
* 根据省份id查询省份中的城市!
* @return
*/
public static List<City> getCityByProvinceId(Long pid) {
List<City> citys = new ArrayList<City>();
if (pid == 1) {
citys = Arrays.asList(
new City(11L,"长沙市"),
new City(12L,"株洲市"),
new City(13L,"湘潭市"),
new City(14L,"衡阳市"),
new City(15L,"邵阳市"),
new City(16L,"岳阳市"),
new City(17L,"常德市"),
new City(18L,"张家界市")
);
} else if (pid == 2) {
citys = Arrays.asList(
new City(21L,"广州市"),
new City(22L,"深圳市"),
new City(23L,"佛山市"),
new City(24L,"中山市"),
new City(25L,"珠海市"),
new City(26L,"汕头市"),
new City(27L,"潮州市"),
new City(28L,"东莞市")
);
} else if (pid == 3) {
citys = Arrays.asList(
new City(31L,"孝感市"),
new City(32L,"黄冈市"),
new City(33L,"咸宁市"),
new City(34L,"恩施州"),
new City(35L,"鄂州市"),
new City(36L,"武汉市"),
new City(37L,"荆门市"),
new City(38L,"襄阳市")
);
}
return citys;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String toString() {
return "City [id=" + id + ", name=" + name + "]";
}
}
拼接HTML格式数据
LinkageHTMLController
@Controller
@RequestMapping("myhtml")
public class LinkageHTMLController {
/*格式
* <option>--请选择--</option>
<option>广东</option>
<option>上海</option>
*/
@RequestMapping("getProvinces")
public void getProvinces(HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf-8");
List<Province> list = Province.getAllProvince();
StringBuilder sb = new StringBuilder(100);
for (Province vo : list) {
sb.append("<option value='"+vo.getId()+"'>").append(vo.getName()).append("</option>");
}
response.getWriter().write(sb.toString());
}
/**
*
* @param pid
* @param response
* @throws Exception
*/
@RequestMapping("getCities")
public void getCities(Long pid,HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf-8");
List<City> list = City.getCityByProvinceId(pid);
StringBuilder sb = new StringBuilder(100);
for (City vo : list) {
sb.append("<option value='"+vo.getId()+"'>").append(vo.getName()).append("</option>");
}
response.getWriter().write(sb.toString());
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- json -->
<script type="text/javascript" src="linkage_json.js"></script>
<!-- xml -->
<!-- <script type="text/javascript" src="linkage_xml.js"></script> -->
<!-- html方式 -->
<!-- <script type="text/javascript" src="linkage_html.js"></script> -->
</head>
<body>
<select id="provinces">
<option value="-1">--请选择--</option>
</select>
<select id="cities">
<option value="-1">--请选择--</option>
</select>
</body>
</html>
inkage_html.js
window.onload=function(){
//省份
var pEl = document.getElementById("provinces");
var cEl = document.getElementById("cities");
//页面加载完毕之后,通过ajax 获取所有的省份
var ajax = new XMLHttpRequest();
ajax.open("get","/myhtml/getProvinces.do",true);
ajax.onreadystatechange=function(){
if(ajax.readyState == 4&& ajax.status ==200){
//已经是html格式,直接拼接即可
pEl.innerHTML+=ajax.responseText;
}
}
ajax.send();
//城市:通过省份id获取
pEl.onchange=function(){
var pid = pEl.value;
//清空原来的值
cEl.innerHTML="<option value='-1'>--请选择--</option>";
//当用户选中的省份是 请选择的时候没有必要发ajax请求
if(pid==-1){
return ;
}
//页面加载完毕之后,通过ajax 获取所有的省份
var ajax = new XMLHttpRequest();
ajax.open("get","/myhtml/getCities.do?pid="+pid,true);
ajax.onreadystatechange=function(){
if(ajax.readyState == 4&& ajax.status ==200){
//已经是html格式,直接拼接即可
cEl.innerHTML+=ajax.responseText;
}
}
ajax.send();
}
}
十.二级联动 XML格式
LinkageXMLController类
@Controller
@RequestMapping("xml")
public class LinkageXMLController {
/*格式
* <datas>
* <data id='1'>湖南</data>
* <data id='2'>广东</data>
* <data id='3'>湖北</data>
* </datas>
*/
@RequestMapping("getProvinces")
public void getProvinces(HttpServletResponse response) throws Exception {
response.setContentType("text/xml;charset=utf-8");
List<Province> list = Province.getAllProvince();
//使用DOM操作
//创建document
org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = doc.createElement("datas");
doc.appendChild(root);
for (Province vo : list) {
Element dataEl = doc.createElement("data");
dataEl.setAttribute("id", vo.getId()+"");
dataEl.setTextContent(vo.getName());
root.appendChild(dataEl);
}
//同步更新(拼接好的xml格式文件输出到浏览器中)
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(response.getOutputStream()));
}
/**
*
* @param pid
* @param response
* @throws Exception
*/
@RequestMapping("getCities")
public void getCities(Long pid,HttpServletResponse response) throws Exception {
response.setContentType("text/xml;charset=utf-8");
List<City> list = City.getCityByProvinceId(pid);
//使用DOM操作
//创建document
org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = doc.createElement("datas");
doc.appendChild(root);
for (City vo : list) {
Element dataEl = doc.createElement("data");
dataEl.setAttribute("id", vo.getId()+"");
dataEl.setTextContent(vo.getName());
root.appendChild(dataEl);
}
//同步更新(拼接好的xml格式文件输出到浏览器中)
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(response.getOutputStream()));
}
}
linkage_json.js
window.onload=function(){
//省份
var pEl = document.getElementById("provinces");
var cEl = document.getElementById("cities");
//页面加载完毕之后,通过ajax 获取所有的省份
var ajax = new XMLHttpRequest();
ajax.open("get","/xml/getProvinces.do",true);
ajax.onreadystatechange=function(){
if(ajax.readyState == 4&& ajax.status ==200){
//已经返回结果xml格式,所以拼接即可
var doc = ajax.responseXML;
console.log("xml");
console.log(doc);
var datas = doc.getElementsByTagName("data");
//拼接option
var opHTML="";
for(var i=0;i<datas.length;i++){
opHTML+="<option value='"+datas[i].id+"'>"
+datas[i].innerHTML+"</option>";
}
pEl.innerHTML+=opHTML;
}
}
ajax.send();
//城市:通过省份id获取
pEl.onchange=function(){
var pid = pEl.value;
//清空原来的值
cEl.innerHTML="<option value='-1'>--请选择--</option>";
//当用户选中的省份是 请选择的时候没有必要发ajax请求
if(pid==-1){
return ;
}
//页面加载完毕之后,通过ajax 获取所有的省份
var ajax = new XMLHttpRequest();
ajax.open("get","/xml/getCities.do?pid="+pid,true);
ajax.onreadystatechange=function(){
if(ajax.readyState == 4&& ajax.status ==200){
//已经返回结果xml格式,所以拼接即可
var doc = ajax.responseXML;
console.log("xml");
console.log(doc);
var datas = doc.getElementsByTagName("data");
//拼接option
var opHTML="";
for(var i=0;i<datas.length;i++){
opHTML+="<option value='"+datas[i].id+"'>"
+datas[i].innerHTML+"</option>";
}
cEl.innerHTML+=opHTML;
}
}
ajax.send();
}
}
十一.JSON数据格式
-
JSON(JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。易于人阅读和编写,同时也易于机器解析和生成(网络传输速度快)
-
JSON是JavaScript原生格式,这意味着在JavaScript中处理JSON数据不需要任何特殊的API或工具包。
-
描述一个对象: {属性名1 : 属性值1 , 属性名2 : 属性值2}
JSON的规则很简单:
- 对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’对”之间使用“,”(逗号)分隔。
- 映射用冒号(“:”)表示。名称:值
- 并列的数据之间用逗号(“,”)分隔。名称1:值1,名称2:值2
- 映射的集合(对象)用大括号(“{}”)表示。{名称1:值1,名称2:值2}
- 并列数据的集合(数组)用方括号(“[]”)表示。
[ {名称1:值,名称2:值2}, {名称1:值,名称2:值2} ]
- 元素值可具有的类型:string, number, object, array, true, false, null
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
</body>
</html>
index.js
//页面加载完毕绑定时间
window.onload=function(){
var employee={
id:1,
name:"dusk",
salary:1000,
birthDate:new Date(),
dept:{
id:1,
name:"开发部"
}
}
console.log(employee);
//获取属性
console.log(employee.name);
console.log(employee.dept.name);
//json格式数组表示多个员工
var es = [
{id:1,name:"dusk",age:18},
{id:1,name:"DUSK",age:19}
];
console.log(es);
//使用json字符串转换json对象
var json="{id:1,name:'dusk'}"
console.log(json);
//将js格式的字符串转换成js表达式
console.log(eval("("+json+")"));
}
十二.操作JSON的库
-
因为手动拼接JSON数据格式效率比较低,而且不是特别的可靠,所以我们一般都会使用第三方的一些json操作的库来对JAVA对象转换为JSON字符串,也可以json字符串转换为java对象
-
在Java中,转换JSon的库有很多,两种常用的
- jackson:在SpringMVC中内置的一个转换json的插件,速度也挺快,稳定性比较好
- fastjson:阿里出品,号称是Java领域中转换Json最快的一个插件,中文文档比较齐全,用户量比较多
jackson:
1:添加jar
User类
@Data
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String password;
private Date birthday = new Date();
public Object toJson() {
HashMap<String, Object> map = new HashMap<String,Object>();
map.put("id",this.id);
map.put("username",this.username);
map.put("birthday", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(birthday));
return map;
}
}
@Test
public void testFastSon() throws Exception {
//1.单个Object转换成字符串
String jsonS = JSON.toJSONString(new User(2L,"Dusk","333",null));
System.out.println(jsonS);
//2.成字符串 -->单个Object
User u = JSON.parseObject(jsonS,User.class);
System.out.println(u);
//3.多个个Object转换成字符串
List<User> list = new ArrayList<>();
list.add(new User(2L,"Dusk","333",null));
list.add(new User(2L,"Dusk","333",null));
list.add(new User(2L,"Dusk","333",null));
list.add(new User(2L,"Dusk","333",null));
String jsonL = JSON.toJSONString(list);
System.out.println(jsonL);
//4.json字符转换成多个User对象
List<User> list2 = JSON.parseArray(jsonL, User.class);
for (User user : list2) {
System.out.println(user);
}
}
fasjson
fastjson-1.2.41.jar
@Test
public void testJackSon() throws Exception {
ObjectMapper mapper = new ObjectMapper();
//1.单个Object转换成字符串
String jsonS = mapper.writeValueAsString(new User(2L,"Dusk","333",null));
System.err.println(jsonS);
//2.成字符串 -->单个Object
User u = mapper.readValue(jsonS, User.class);
System.out.println(u);
//3.多个个Object转换成字符串
List<User> list = new ArrayList<>();
list.add(new User(2L,"Dusk","333",null));
list.add(new User(2L,"Dusk","333",null));
list.add(new User(2L,"Dusk","333",null));
list.add(new User(2L,"Dusk","333",null));
String jsonL = mapper.writeValueAsString(list);
System.out.println(jsonL);
//4.json字符转换成多个User对象
JavaType javaType = mapper.getTypeFactory()
//参数一:返回值类型,参数2:返回泛型
.constructParametricType(ArrayList.class, User.class);
List<User> list2 = mapper.readValue(jsonL, javaType);
for (User user : list2) {
System.err.println(user);
}
十三.二级联动-JSON数据格式实现
LinkageJSONController类
//@Controller 表示该controller中所有方式返回都转换成json格式
@RestController
@RequestMapping("json")
public class LinkageJSONController {
/*格式
[
{id:1,name:"湖南"},
{id:2,name:"广东"},
{id:3,name:"湖北"}
]
*/
@RequestMapping("getProvinces")
//@ResponseBody 返回数据的数据(对象)转换成json字符格式
public List<Province> getProvinces(HttpServletResponse response) throws Exception {
response.setContentType("text/json;charset=utf-8");
return Province.getAllProvince();
/*StringBuilder sb = new StringBuilder(100);
sb.append("[");
for (Province vo : list) {
sb.append("{id:"+vo.getId()+",name:'").append(vo.getName()+"'},");
}
//删除最后的逗号
sb.deleteCharAt(sb.length()-1);
sb.append("]");
response.getWriter().write(sb.toString());
*/
//改进
/*response.getWriter().write(JSON.toJSONString(list));*/
}
/**
*
* @param pid
* @param response
* @throws Exception
*/
@RequestMapping("getCities")
/*@ResponseBody*/
public List<City> getCities(Long pid,HttpServletResponse response) throws Exception {
response.setContentType("text/json;charset=utf-8");
return City.getCityByProvinceId(pid);
/*StringBuilder sb = new StringBuilder(100);
sb.append("[");
for (City vo : list) {
sb.append("{id:"+vo.getId()+",name:'").append(vo.getName()+"'},");
}
//删除最后的逗号
sb.deleteCharAt(sb.length()-1);
sb.append("]");
response.getWriter().write(sb.toString());*/
//改进
/*response.getWriter().write(JSON.toJSONString(list));*/
}
}
linkage_json.js
window.onload=function(){
//省份
var pEl = document.getElementById("provinces");
var cEl = document.getElementById("cities");
//页面加载完毕之后,通过ajax 获取所有的省份
var ajax = new XMLHttpRequest();
ajax.open("get","/json/getProvinces.do",true);
ajax.onreadystatechange=function(){
if(ajax.readyState == 4&& ajax.status ==200){
//已经返回结果json格式,所以拼接即可
console.log("json");
var ret = "("+ajax.responseText+")";
console.log(ret);
var jsonArr = eval("("+ajax.responseText+")");
var opHTML="";
for(var i=0;i< jsonArr.length;i++){
opHTML += "<option value='"+jsonArr[i].id+"'>"+jsonArr[i].name+"</option>";
}
pEl.innerHTML+=opHTML;
}
}
ajax.send();
//城市:通过省份id获取
pEl.onchange=function(){
var pid = pEl.value;
//清空原来的值
cEl.innerHTML="<option value='-1'>--请选择--</option>";
//当用户选中的省份是 请选择的时候没有必要发ajax请求
if(pid==-1){
return ;
}
//页面加载完毕之后,通过ajax 获取所有的省份
var ajax = new XMLHttpRequest();
ajax.open("get","/json/getCities.do?pid="+pid,true);
ajax.onreadystatechange=function(){
if(ajax.readyState == 4&& ajax.status ==200){
//已经返回结果json格式,所以拼接即可
var jsonArr = eval("("+ajax.responseText+")");
console.log("json");
console.log(jsonArr);
var opHTML="";
for(var i=0;i< jsonArr.length;i++){
opHTML += "<option value='"+jsonArr[i].id+"'>"+jsonArr[i].name+"</option>";
}
cEl.innerHTML+=opHTML;
}
}
ajax.send();
}
}