2019尚硅谷大数据 Javaweb篇三Ajax、JSTL、会话技术、过滤器、监听器
tags:
- 大数据
- 2019尚学堂
categories:
- Ajax异步请求
- JSTL中的if和forEach
- 会话cookie
- session
- 过滤器
- 监听器
- xml
- json
文章目录
第一节 Ajax异步处理
1.1 同步请求和异步请求
- 同步处理
- AJAX出现之前,我们访问互联网时一般都是同步请求,也就是当我们通过一个页面向服务器发送一个请求时,在服务器响应结束之前,我们的整个页面是不能操作的,也就是直观上来看他是卡住不动的。
- 这就带来了非常糟糕的用户体验。首先,同步请求时,用户只能等待服务器的响应,而不能做任何操作。其次,如果请求时间过长可能会给用户一个卡死的感觉。最后,同步请求的最大缺点就是即使整个页面中只有一小部分内容发生改变我们也要刷新整个页面。
- 异步处理
- 而异步处理指的是我们在浏览网页的同时,通过AJAX向服务器发送请求,发送请求的过程中我们浏览网页的行为并不会收到任何影响,甚至主观上感知不到在向服务器发送请求。当服务器正常响应请求后,响应信息会直接发送到AJAX中,AJAX可以根据服务器响应的内容做一些操作。
- 使用AJAX的异步请求基本上完美的解决了同步请求带来的问题。首先,发送请求时不会影响到用户的正常访问。其次,即使请求时间过长,用户不会有任何感知。最后,AJAX可以根据服务器的响应信息局部的修改页面,而不需要整个页面刷新。
1.2 异步请求对象
- XMLHttpRequest对象是AJAX中非常重要的对象,所有的AJAX操作都是基于该对象的。
- XMLHttpRequest对象用来封装请求报文,我们向服务器发送的请求信息全部都需要封装到该对象中。
- 这里需要稍微注意一下,XMLHttpRequest对象并没有成为标准,但是现在的主流浏览器都支持该对象,而一些如IE6的老版本浏览器中的创建方式有一些区别,但是问题不大。
- Xhr对象的获取
<script type= "text/javascript">
//获取XMLHttpRequest的通用方法
function getXMLHttpRequest(){
var xhr;
try{
//大部分浏览器都支持
xhr = new XMLHttpRequest();
}catch(e){
try{
//如果不支持,在这里捕获异常并且采用IE6支持的方式
xhr = new ActiveXobject("Msxm12.XMLHTTP");
}catch(e){
//如果还不支持,在这里捕获异常并采用IE5支持的方式
xhr = new ActiveX0bject("Microsoft.XMLHTTP");
}
}
return xhr ;
}
</script>
- Xhr对象的方法
- open(method,url,async)
- open()用于设置请求的基本信息,接收三个参数。
- method: 请求的方法:get或post 接收一个字符串
- url 请求的地址,接收一个字符串
- Assync 发送的请求是否为异步请求,接收一个布尔值。 true 是异步请求,false 不是异步请求(同步请求)
- send(string)
- send()用于将请求发送给服务器,可以接收一个参数
- string参数:该参数只在发送post请求时需要, string参数用于设置请求体
- setRequestHeader(header,value)
- 用于设置请求头
- header参数 字符串类型,要设置的请求头的名字
- value参数 字符串类型,要设置的请求头的值
- open(method,url,async)
- XMLHttpRequest对象的属性
- readyState 描述XMLHttpRequest的状态 一共有五种状态分别对应了五个数字:
- 0 :请求尚未初始化,open()尚未被调用
- 1 :服务器连接已建立,send()尚未被调用
- 2 :请求已接收,服务器尚未响应
- 3 :请求已处理,正在接收服务器发送的响应
- 4 :请求已处理完毕,且响应已就绪。
- status 请求的响应码
- 200 响应成功
- 404 页面为找到
- 500 服务器内部错误
- onreadystatechange
- 该属性需要指向一个函数
- 该函数会在readyState属性发生改变时被调用
- responseText 获得字符串形式的响应数据。
- responseXML(用的比较少)获得 XML 形式的响应数据。
- readyState 描述XMLHttpRequest的状态 一共有五种状态分别对应了五个数字:
1.3 异步请求Js原生写法(不推荐)
//发送异步请求GET
//获取xhr对象
var xhr = getXMLHttpRequest();
//设置请求信息 random防止缓存 尤其ecplise内部浏览器缓存更严重 防止重复不发请求
xhr.open("get", "AjaxServ1et?&t="+Math.random(),true);
//发送请求
xhr.send() ;
//监听请求状态
xhr.onreadystatechange = function(){
//当响应完成
if(xhr.readyState == 4){
//且状态码为200时
if(xhr.status == 200){
//接收响应信息(文本形式)
var text = xhr.responseText;
//弹出消息
alert(text);
}
};
};
//发送异步请求POST
//获取xhr对象
var xhr = getXMLHttpRequest();
//设置请求信息
xhr.open("post", "2.jsp" ,true) ;
//设置请求头 必须设置 平时提交表单也默认设置了它enctype="application/x-www-form-urlencoded"
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//发送请求
xhr.send("he11o=123456");
//监听请求状态
xhr.onreadystatechange = function(){
//当响应完成
if(xhr.readyState == 4){
/且状态码为200时
if(xhr.status == 200){
//接收响应信息(文本形式)
var text = xhr.responseText;
//弹出消息
alert(text);
}
};
1.4 jQuery框架来发送异步请求
- jQuery是当前比较主流的 JavaScript 库,封装了很多预定义的对象和实现函数,帮助使用者建立有高难度交互的页面,并且兼容大部分主流的浏览器.
- JQuery对同样提供了对Ajax的支持,可以更加方便快速的进行Ajax的开发,相关的方法有$.get $.post $.ajax等.
- JQuery的对象的本质就是dom对象的数组/集合
- Query对象与dom对象的相互转换
- JS 转 JQuery: var jObj = $(dObj);
- JQuery 转 JS: var dObj = jObj[0] 或者 var dObj = jObj.get(0)
- $.ajax方法: 功能局部刷新页面
- jQuery 底层 AJAX 实现。简单易用的高层实现见 $.get, $.post 等。
- $.ajax() 返回其创建的 XMLHttpRequest 对象。大多数情况下你无需直接操作该函数,除非你需要操作不常用的选项,以获得更多的灵活性。
- 最简单的情况下,$.ajax()可以不带任何参数直接使用。
- $.ajax方法的参数
- url[settings] 必需的, 用来设置请求地址。
- url:一个用来包含发送请求的URL字符串。必需的, 用来设置请求地址。
- settings:AJAX请求设置。所有选项都是可选的。
- type: 可选的 一般为post或get 默认为get请求
- data: 也是可选的, 用来设置请求参数
- success: 可选的, 用来设置回调函数, 响应成功之后系统会自动调用该函数,响应数据会以参数形式传到该函数中
- dataType: 可选的, 用来设置响应数据的类型,默认是text,也可以是xml,json类型
-
.post方法 这是一个简单的GET请求功能以取代复杂
.ajax。
- 相当于jQuery.get或者post(url, [data], [callback], [type])
- url:必须的。用来设置请求地址
- data:可选的。用来设置请求参数
- callback: 可选的。用来设置一个回调函数,响应成功之后系统会自动调用该函数,响应数据会以参数的形式传入到该函数中
- type:可选的。用来设置响应数据的类型 xml, html, script, json, text,_default.
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${pageContext.request.contextPath}/script/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function(){
// 给按钮绑定单击事件
$("#btnId").click(function(){
//通过$.Ajax()方法发送Ajax请求
//alert("绑定成功");
/*
url是必需的, 用来设置请求地址。默认发送的是get请求
type: 可选的 一般为post或get 默认为get请求
data: 可选的, 用来设置请求参数
success: 可选的, 用来设置回调函数, 响应成功之后系统会自动调用该函数,响应数据会以参数形式传到该函数中。
dataType: 可选的, 用来设置响应数据的类型,默认是text,也可以是xml,json。
*/
$.ajax({
url:"${pageContext.request.contextPath}/AjaxServlet",
type: "get",
data:"username=admin&password=123456",
success: function(res){
//alert(res);
$("#span").text(res)
},
dataType: "text",
});
});
});
/* $(function(){
// 给按钮绑定单击事件
$("#btnId1").click(function(){
var url ="${pageContext.request.contextPath}/AjaxServlet";
var params = "username=admin&password=123456"
$.get(url,params,function(res){
alert(res);
}, "text");
});
}); */
$(function(){
// 给按钮绑定单击事件
$("#btnId1").click(function(){
var url ="${pageContext.request.contextPath}/AjaxServlet";
var params = "username=admin&password=123456"
$.post(url,params,function(res){
alert(res);
}, "text");
});
});
</script>
</head>
<body>
<h1><%=new Date() %></h1>
<button id="btnId">通过$.Ajax()方法发送Ajax</button><span style="color:red" id="span"></span><br>
<button id="btnId1">通过$.get/post()方法发送Ajax</button><span style="color:red" id="span1"></span>
</body>
</html>
第二节 JSTL的if和forEach标签
- JSTL全称: JSP Standard Tag Library, JSP的标准标签库。
- 导入资料中的jtsl中jstl和standard的jar包。放到->WebContent 下的lib
- jsp页面中引入标准库alt+/。<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
- 测试引入是否成功:输入<c 然后Alt+/ 看可用的语法。
- if标签:相当于Java中if条件判断
- test属性:用来接收一个布尔类型的值,通常通过EL表达式获取该值,当值是true时才执行标签题中的内容
- forEach标签:相当于Java中的for循环
- items属性:接收一个要遍历的集合
- var属性:设置一个遍历接收遍历到的值,同时会以变量值为key将遍历到的值放到page域中
- empty运算符:主要用来判断一个字符串或一个集合是否为空
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ 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>
</head>
<body>
<!--
JSTL全称:JSP Standard Tag Library,JSP的标准标签库
-->
<!-- if标签:相当于Java中if条件判断
test属性:用来接收一个布尔类型的值,通常通过EL表达式获取该值,当值是true时才执行标签题中的内容
-->
<%
int age = 86;
pageContext.setAttribute("age", age);
%>
<c:if test="${age < 18 }">
禁止未成年人入内!
</c:if>
<c:if test="${age > 18 }">
请尽情浏览,注意身体!!!
</c:if>
<%
List<String> list = new ArrayList();
list.add("吉沢明步");
list.add("蓝泽润");
list.add("京香JULIA");
list.add("潘金莲");
list.add("文章");
list.add("白百何");
list.add("李小璐");
list.add("林丹");
list.add("吴秀波");
//将list放到page域中
pageContext.setAttribute("stars", list);
%>
<hr>
<!-- forEach标签:相当于Java中的for循环
items属性:接收一个要遍历的集合
var属性:设置一个遍历接收遍历到的值,同时会以变量值为key将遍历到的值放到page域中
-->
<c:forEach items="${stars}" var="star">
<a href="#">${pageScope.star }</a><br>
</c:forEach>
<!--
empty运算符:主要用来判断一个字符串或一个集合是否为空
-->
<c:if test="${empty pageScope.stars }">
世界很美好,没有人乱搞!!!
</c:if>
<c:if test="${!empty pageScope.stars }">
世界很风骚,明星都耐不住寂寞!!!!
</c:if>
<c:if test="${not empty pageScope.stars }">
世界很风骚,明星都耐不住寂寞!!!!
</c:if>
</body>
</html>
第三节 会话技术cookie和session
3.1 cookie
- HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分中两次请求是否由一个客户端发出。这样的设计严重阻碍的Web程序的设计。如:在我们进行网购时,买了一条裤子,又买了一个手机。由于http协议是无状态的,如果不通过其他手段,服务器是不能知道用户到底买了什么。而Cookie就是解决方案之一。
- Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求。
- Cookie的用途
- 网上商城购物车
- 用户登录状态的保持
- Cookie的限制性 => 导致session产生
- Cookie作为请求或响应报文发送,无形中增加了网络流量。
- Cookie是明文传送的安全性差。
- 各个浏览器对Cookie有限制,使用上有局限
- Cookie的值只能是String类型,不能保存对象
- Cookie的运行原理:
- 第一次向服务器发送请求时在服务器端创建一个Cookie对象
- 将CooKie对象发送给浏览器
- 以后浏览器再发请求就会携带着该Cookie对象
- 服务器根据不同的Cookie对象来区分不同的用户
// 创建Cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 创建cookie对象
//Cookie对象的名字不能使用中文,
//Cookie对象的值可以使用中文但是需要指定字符集进行编码
//而且获取Cookie对象还需要指定字符集进行解码
Cookie cookie = new Cookie("user","admin");
// 2.将cookie发送给浏览器
response.addCookie(cookie);
Cookie cookie1 = new Cookie("user2","pathcookie");
//设置Cookie对象的有效路径,默认Cookie对象的有效路径是项目的根目录
cookie1.setPath(request.getContextPath()+"/pages");
response.addCookie(cookie1);
}
// 获取Cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取cookie参数
Cookie[] cookies = request.getCookies();
if (cookies != null) {
// 遍历得到每一个cookies对象
for(Cookie cookie : cookies){
// 获得cookie的名字
String name = cookie.getName();
// 获取cookie的值
String value = cookie.getValue();
System.out.println("cookies的名字是:"+name);
System.out.println("cookies的值是:"+value);
}
}
}
// 持久化cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("user3","man");
//持久化Cookie对象为1分钟
/*
* setMaxAge(int age)
* age > 0 : Cookie对象age秒后失效
* age = 0 : Cookie对象立即失效
* age < 0 :默认,会话级别的Cookie对象
*/
cookie.setMaxAge(60) ;
response.addCookie(cookie);
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
</head>
<body>
<!--
Cookie的运行原理:
1.第一次向服务器发送请求时在服务器端创建一个Cookie对象
2.将Coolie对象发送给浏览器
3.以后浏览器再发请求就会携带着该Cookie对象
4.服务器根据不同的Cookie对象来区分不同的用户
-->
<a href="${pageContext.request.contextPath }/CreateCookie">创建Cookie对象</a><br>
<a href="${pageContext.request.contextPath }/GetCookies">获取Cookie对象</a><br>
<a href="${pageContext.request.contextPath }/PersistCookies">持久化Cookie对象</a><br>
</body>
</html>
3.2 session
- 使用Cookie有一个非常大的局限,就是如果Cookie很多,则无形的增加了客户端与服务端的数据传输量。而且由于浏览器对Cookie数量的限制,注定我们不能再Cookie中保存过多的信息,于是Session出现。
- Session的作用就是在服务器端保存一些用户的数据,然后传递给用户一个名字为JSESSIONID的Cookie,这个JESSIONID对应这个服务器中的一个Session对象,通过它就可以获取到保存用户信息的Session。
- Session的工作原理
- Session的创建时机是在request.getSession()方法第一次被调用时。
- Session被创建后,同时还会有一个名为JSESSIONID的Cookie被创建。
- 这个Cookie的默认时效就是当前会话。
- 简单来说,Session机制也是依赖于Cookie来实现的
- Session的运行原理解释
1.第一次向服务器发送请求时在服务器端创建一个Session对象,该对象有一个全球唯一的ID
2.在创建Session对象的同时会创建一个特殊的Cookie对象,该Cookie对象的名字是一个固定值:JSESSIONID,该Cookie对象的值就是Session对象的ID值,并将该Cookie对象发送给浏览器
3.以后浏览器再发送请求就会携带着这个特殊的Cookie对象
4.服务器获取Cookie对象的值之后再服务器端寻找与之对象的Session对象以此来区分不同的用户 - Session的时效问题
Session默认有效时间为30分钟,可以在服务器的web.xml配置中修改. session-timeout中配置。
3.3 钝化和活化
- 当服务器关闭后,如果保存的对象的类实现了序列化接口Serializable,然后加上默认serialVersionUID。它就会把session中的数据给你保存到硬盘上,这个过程就叫钝化。
- 文件存在硬盘:\tmp0\work\Catalina\localhost\Web_Ex\SESSIONS.ser
- 当服务器重启时,session中的值从硬盘上反序列化到服务器中。这个过程叫做活化。
- 这样就可以实现服务器重启,session不丢失。
3.4 注销
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取session对象
HttpSession session = request.getSession();
// 使session对象失效
session.invalidate();
// 重新定向到首页
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
第四节 权限访问控制-过滤器
- 对于WEB应用来说,过滤器是一个驻留在服务器中的WEB组件,他可以截取客户端和WEB资源之间的请求和响应信息。WEB资源可能包括Servlet、JSP、HTML页面等
- 当服务器收到特定的请求后,会先将请求交给过滤器,程序员可以在过滤器中对请求信息进行读取修改等操作,然后将请求信息再发送给目标资源。目标资源作出响应后,服务器会再次将响应转交给过滤器,在过滤器中同样可以对响应信息做一些操作,然后再将响应发送给浏览器。
- 也就是说过滤器可以在WEB资源收到请求之前,浏览器收到响应之前,对请求和响应信息做一些相应的操作。
- 在一个WEB应用中可以部署多个过滤器,多个过滤器就组成了一个过滤器链,请求和响应必须在经过多个过滤器后才能到达目标
- 使用举例:比如不登录的状况下,不可以访问登录后的接口功能。
4.1 过滤器基本使用
- 右键->new-> Filter
- 设置要拦截的地址
<filter>
<display-name>HelloFilter</display-name>
<filter-name>HelloFilter</filter-name>
<filter-class>com.hynqn.filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HelloFilter</filter-name>
<!-- 设置要拦截的地址 -->
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
package com.hynqn.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Servlet Filter implementation class HelloFilter
*/
public class HelloFilter implements Filter {
public HelloFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
// 拦截请求的方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("①啊哈哈 过来 给钱");
// 放行请求
chain.doFilter(request, response);
System.out.println("③小鬼又回来了");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
<%
System.out.println("②小鬼又回来了");
%>
<h1>看到我了吗</h1>
4.2 多个过滤器使用
- 在设置一个过滤器对同一个资源index.jsp进行过滤。
- 执行顺序为, 第一个过滤器->第二个过滤器->网页返回->第一个过滤器->第二个过滤器
- 第一个和第二个的区分,按照web_xml中filter-mapping中的配置路径先后顺序区分。
<filter- mapping>
<filter-name>HelloFilter2</filter-name>
<!--设置要拦截的路径-->
<url -pattern>/ index.jsp</url-pattern>
<!--如要拦截向Servlet发送的请求,还可以通过Servlet的名字进行配置-->
<!--<servlet - name></servlet-name>-->
</filter-mapping>
第五节 监听器
- Listener用于监听JavaWeb程序中的事件。
- 例如:ServletContext、HttpSession、ServletRequest的创建、修改和删除。
- 监听器的类型分为
- 生命周期 (监听对象的创建和销毁)
- 数据绑定(属性变化)
- 钝化活化 不需要再web.xml中注册
- sesion存取 不需要再web.xml中注册
5. 1 监听器简单实用
- 创建动态工程
- 创建监听器ServletContext,选第一个,监听生命周期
- 运行服务器。发现服务器一运行,这个对象就被创建啦。服务器关闭时, 对象被销毁。
- 它的配置也很简单
<listener>
<listener-class>com.hynqn.listener.MyServletContextListener</listener-class>
</listener>
package com.hynqn.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* ServletContext的生命周期监听器
*/
public class MyServletContextListener implements ServletContextListener {
public MyServletContextListener() {
// TODO Auto-generated constructor stub
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁");
}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建");
}
}
5. 2 监听器统计在线人数
- 在之前的User类中实现HttpSessionBindingListener接口。
- 一二三章笔记的实战应用都写在Web_Ex中。
package com.hynqn.bean;
import java.io.Serializable;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements Serializable, HttpSessionBindingListener{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;
private String password;
private String email;
// 所有参数的构造器
public User(Integer id, String username, String password, String email) {
super();
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
// 无参构造器
public User() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + "]";
}
// 向session中添加User对象时调用
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("向session中添加User对象");
// 获取session对象
HttpSession session = event.getSession();
// 获取ServletContext对象
ServletContext application = session.getServletContext();
// 从application获取当前人数
Integer count = (Integer)application.getAttribute("count");
if(count == null) {
// 之前还没有人在线 我是第一人
// 向application中设置当前人数为1
application.setAttribute("count", 1);
}else{
// 证明已经有人在线
application.setAttribute("count", count + 1);
}
}
// 从session中移除User对象时调用
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("从session中移除User对象");
// 获取session对象
HttpSession session = event.getSession();
// 获取ServletContext对象
ServletContext application = session.getServletContext();
// 从application获取当前人数
Integer count = (Integer)application.getAttribute("count");
application.setAttribute("count", count - 1);
}
}
第六节 数据交换格式xml
6.1 xml简介
- XML-可扩展标记语言eXtensible Markup Language
- 由W3C组织发布,目前推荐遵守的是W3C组织于2000年发布的XML1.0规范
- XML的使命,就是以一个统一的格式,组织有关系的数据,为不同平台下的应用程序服务
- XML用来传输和存储数据,HTML用来显示数据
- XML没有预定义标签,均为自定义标签
6.2 xml用途
- 配置文件
- JavaWeb中的web.xml
- C3P0中的c3p0-config.xml
- 数据交换格式
- Ajax
- WebService
- 数据存储
- 保存关系型数据
6.3 xml基本语法
- XML文档组成
- XML声明
- version属性指定XML版本,固定值是1.0
- encoding指定的字符集,是告诉解析器使用什么字符集进行解码,而编码是由文本编辑器决定的
- CDATA区
- 当XML文档中需要写一些程序代码、SQL语句或其他不希望XML解析器进行解析的内容时,就可以写在CDATA区中
- XML解析器会将CDATA区中的内容原封不动的输出
- CDATA区的定义格式:<![CDATA[…]]>
- XML声明
- 语法规则
- XML声明要么不写,要写就写在第一行,并且前面没有任何其他字符
- 只能有一个根标签
- 标签必须正确结束
- 标签不能交叉嵌
- 严格区分大小写
- 属性必须有值,且必须加引号
- 标签不能以数字开头
- 注释不能嵌套
- 这里测试时创建的是java工程。
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1">
<name>孙悟空</name>
<gender>男</gender>
<age>520</age>
<address>花果山水帘洞</address>
</student>
<student id="2">
<name>猪八戒</name>
<gender>男</gender>
<age>556</age>
<address>高老庄</address>
</student>
<student id="3">
<name>沙悟净</name>
<gender>男</gender>
<age>556</age>
<address>流沙河</address>
</student>
<!-- CDATA 内容不被解析 直接输出-->
<![CDATA[select * from employees where age < 500]]>
</students>
6.4 xml解析
- XML解析是指通过解析器读取XML文档,解释语法,并将文档转化成对象
- 常用的解析方式
- DOM(Document Object Model)
- SAX(Simple API for XML)
- DOM 和SAX解析的对比
- Dom4j解析示例.
- Java工程导入jar包的方法。
- 创建文件夹lib.先导入资料中dom4j-1.6.1jar的jar包。具体使用可以看资料中的文档。
- 右击dom4j-1.6.1jar,选择bulid path. 把它添加到当前路径下。就可以导入了。
package com.hynqn.dom4j;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.hynqn.students.Students;
public class Dom4jtest {
public static void main(String[] args) throws DocumentException {
//1.创建解析器对象。
SAXReader saxReader = new SAXReader();
//2.解析xml文件获取document对象。
Document document = saxReader.read("students.xml");
//3.得到根元素
Element rootElement = document.getRootElement();
//4.获取所有的student标签
List<Element> stus = rootElement.elements("student");
//System.out.println(stus.size());
// 5. 遍历得到所有标签
for(Element stu : stus) {
// 获取id
String id = stu.attributeValue("id");
System.out.println(id);
// 获取name 标签中的值
Element nameEle = stu.element("name");
String name = nameEle.getText();
System.out.println(name);
// 获取gender标签中的值
Element genderEle = stu.element("gender");
String gender = genderEle.getText();
System.out.println(gender);
// 获取age 标签中的值
Element ageEle = stu.element("age");
String age = ageEle.getText();
System.out.println(age);
// 获取address标签中的值
Element addressEle = stu.element("address");
String address = nameEle.getText();
System.out.println(address);
// 封装Students对象
Students student = new Students(id, name, gender, age, address);
System.out.println(student);
}
}
}
第七节 数据交换格式JSON
7.1 json介绍
- AJAX一开始使用的时XML的数据格式,XML的数据格式非常简单清晰,容易编写,但是由XML中包含了过多的标签,以及十分复杂的结构,解析起来也相对复杂,所以目前来讲,AJAX中已经几乎不使用XML来发送数据了。取而代之的是一项新的技术JSON。
- JSON是JavaScript Object Notation 的缩写,是JS提供的一种数据交换格式。
- JSON对象本质上就是一个JS对象,但是这个对象比较特殊,它可以直接转换为字符串,在不同语言中进行传递,通过工具又可以转换为其他语言中的对象。
- 例,有如下一个JSON对象:
- {“name”:”sunwukong” , ”age”:18 , ”address”:”beijing” }
- 这个对象中有三个属性name、age和address
- 如果将该对象使用单引号引起了,那么他就变成了一个字符串
- ‘{“name”:”sunwukong” , ”age”:18 , ”address”:”beijing” }’
- 变成字符串后有一个好处,就是可以在不同语言之间传递。
- 比如,将JSON作为一个字符串发送给Servlet,在Java中就可以把JSON字符串转换为一个Java对象。
7.2 JSON通过6种数据类型来表示
- 字符串
- 例子:”字符串”
- 注意:不能使用单引号
- 数字:
- 例子:123.4
- 布尔值:
- 例子:true、false
- null值:
- 例子:null
- 对象
- 例子:{“name”:”sunwukong”, ”age”:18}
- 数组
- 例子:[1,”str”,true]
7.3 在JS中操作JSON
- 创建JSON对象
- var json = {“name1”:”value1”,”name2”:”value2” , “name3”:[1,”str”,true]};
- var json = [{“name1”:”value1”},{“name2”:”value2”}];
- JSON对象转换为JSON字符串
- JSON.stringify(JSON对象)
- JSON字符串转换为JSON对象
- JSON.parse(JSON字符串)
7.4 在Java中操作JSON
- 在Java中可以从文件中读取JSON字符串,也可以是客户端发送的JSON字符串,所以第一个问题,我们先来看如何将一个JSON字符串转换成一个Java对象。
- 首先解析JSON字符串我们需要导入第三方的工具,目前主流的解析JSON的工具大概有三种json-lib、jackson、gson。三种解析工具相比较json-lib的使用复杂,且效率较差。而Jackson和gson解析效率较高。使用简单,这里我们以gson为例讲解。
- Gson是Google公司出品的解析JSON工具,使用简单,解析性能好。(在资料中导入jar包)
- Gson中解析JSON的核心是Gson的类,解析操作都是通过该类实例进行。
- JSON字符串转换为对象
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// 假设从数据库中查询到一条信息
Students student = new Students("1", "白骨精", "男", "18", "你猜");
// 创建Gson对象
Gson gson = new Gson();
// 把Students对象转换为json字符串
String json = gson.toJson(student);
System.out.println(json);
response.getWriter().write(json);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试</title>
<script type="text/javascript" src="script/jquery-1.7.2.min.js"></script>
<script>
// 1.Java对象
//属性名必须使用双引号括起来;属性名和属性值之间使用冒号分隔;多个属性之间使用逗号分隔
var jsonObj = {"name":"孙悟空", "age":"520"};
// alert(jsonObj);
//alert(jsonObj.name);
// 2.Java数组
//获取JSON数组中的第五个元素中的age属性值
var jsonArray = ["猪八戒", 1000, false, null, jsonObj]
//alert(jsonArray[4].age);
// 创建一个复杂的json对象
var fzJson = {
"name":"唐僧",
"age":"18",
"sons":[
{"name":"孙悟空"},
{"name":"猪八戒", "wives":[
{"name":"小红"},
{"name":"小兰"},
{"name":"小萨"}
]},
{"name":"沙悟净"},
{"name":"白龙马"}
]
};
// 获取猪八戒第三个媳妇
//alert(fzJson.sons[1].wives[2].name);
// 将JSON对象转换成JSON字符串
var objToStr = JSON.stringify(jsonObj);
//alert(objToStr);
// 将JSON字符串转换为json对象
var StrToobj = JSON.parse(objToStr);
//alert(StrToobj);
$(function(){
// 给按钮绑定单机事件
$("#btnId").click(function(){
// 设置请求地址
var url = "JsonServlet";
// 发送Ajax请求
//$.get(url, function(res){
// alert(res);
//});
// 直接转为json对象
$.get(url, function(res){
alert(res);
}, "json");
});
});
</script>
</head>
<body>
<button id="btnId">发送Ajax请求, 接收JSON格式的响应数据</button>
</body>
</html>