前言
会话:浏览器和服务器之间的多次请求和响应.
- 为了实现一些功能,浏览器和服务器之间可能会产生多次请求和响应,从浏览器开始,到访问服务器结束(关闭浏览器,到了过期时间).这期间产生的多次请求和响应加在一起称之为浏览器和服务器之间的一次会话.
- 会话过程中所产生的一些数据,可以通过会话技术(Cookie和Session)保存.
1.Cookie
1.1介绍
cookie:客户端会话管理技术,他是一个普通的类.
把要共享的数据保存到客户端.
每次请求时,把会话信息带到服务器端,从而实现请求的数据共享.
作用:可以保存客户端访问网站的相关内容,从而保证每次访问时先从本地缓存中获取,以此提高效率.
1.由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
2.Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
3.Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
1.2属性
name Cookie的名称
value Cookie的值
path Cookie的路径
domain Cookie的域名
maxAge Cookie的存活时间
version Cookie的版本号
comment Cookie的描述
1.3方法
- Cookie(String name,String value) : cookie只有一个有参构造没有无参构造.
- 属性对应的set和get方法 : 赋值和获取值
- void addCookie(Cookie cookie) : 向客户端添加cookie(使用resp调用)
- Cookie[] getCookies() : 获取所有cookie(使用req调用)
1.4cookie的使用
共享数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应格式
resp.setContentType("text/html;charset=utf-8");
//生成与一个cookie
Cookie cookie = new Cookie("time",System.currentTimeMillis()+"");
//给cookie设置存活时间
cookie.setMaxAge(3600);
//通过响应将服务器生成的cookie写入浏览器
resp.addCookie(cookie);
//打印上次访问的时间
String cookie1 = req.getHeader("Cookie");
System.out.println(cookie1);
System.out.println("--------------------");
Cookie[] cookies = req.getCookies();
//resp.getWriter().write("您最后一次访问的时间:");
if(null != cookies){
for (Cookie cookieTmp : cookies) {
//System.out.println(cookieTmp.toString());
if("time".equals(cookieTmp.getName())){
String time = cookieTmp.getValue();
Date lastTime = new Date(Long.parseLong(time));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
resp.getWriter().write("您最后一次访问的时间:" + sdf.format(lastTime));
}
}
}
}
1.5cookie的细节
- 数量限制
每个网站最多只能由20个Cookie,且大小不能超过4KB.所有网址的Cookie总数不能超过300个. - 名称限制
Cookie的名称只能包含ASCII码表中的字母,数字字符.不能包含逗号,分号,空格,不能以$开头. - 存活时间限制 setMaxAge()方法接收数字
负整数:当前会话有效,浏览器关闭则清除
0:立即清除
正整数:以秒为单位设置存货时间. - 访问路径限制
默认路径:取自第一次访问的资源路径前缀.只要以这个路径开头就能访问到.
设置路径:setPath()方法设置指定路径.
2.HttpSession
2.1介绍
HttpSession"服务器端会话管理技术,是一个接口.
本质也是采用客户端会话管理技术.
只不过在客户端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中.
每次请求时,会将特殊标识带到服务器端,根据这个标识来找对应的内存空间,从而实现数据共享.是servlet规范中四大域对象之一的会话域对象.作用是数据共享.
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户所携带的特殊标识(jsessionid)就可以了。
如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
2.2 HttpSession的获取
获取HttpSession对象: HttpSession getSession()
获取HttpSersion对象,create未获取到是否自动创建: HttpSession getSession(boolean create)
2.3 常用方法
设置共享数据:void setAttribute(String name,Object value)
获取共享数据:Object getAttribute(String name)
移除共享数据:void removeAttribute(String name)
获取唯一标识:String getId()
让session立即失效:void Invalidate()
2.4 HttpSession的使用
//ServletSession1
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的用户名
String username = req.getParameter("username");
//获取HttpSession的对象
HttpSession session = req.getSession();
//将用户名信息添加到共享数据中
session.setAttribute("username",username);
}
//ServletSession2
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取httpSession对象
HttpSession session = req.getSession();
//获取共享数据
Object username = session.getAttribute("username");
//将数据响应给浏览器
resp.getWriter().write(username+"");
}
2.5 HttpSession的细节
- 浏览器禁用 Cookie
方式一:通过提示信息告知用户,大部分网站采用的解决办法.
方式二:访问时拼接jsessionid标识,通过encodeURL()方法重写地址. - 钝化和活化
- 什么是钝化和活化
钝化:序列化.把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上.
活化:相反的状态. - 何时钝化
第一种情况:当访问量很大时,服务器会根据getLastAccessTime来进行排序.
对长时间不用,但是还没到过期时间的HttpSession进行序列化.
第二种情况:当服务器进行重启的时候,为了保护客户HttpSession中的数据.也要对其进行序列化.
- 什么是钝化和活化
- 注意
HttpSession的序列化由服务器自动完成.
3.JSP
JSP:动态网页技术,本质上是一个servlet.
JSP部署在服务器上,可以处理客户端发送的请求,并根据请求内容动态的生成HTML,XML或其他格式文档Web网页,然会再响应给客户端.
3.1 JSP的执行过程
3.2JSP语法
- JSP注释
<% --注释内容–%> - java代码块
<% java 代码块 %> - JSP表达式
<%=表达式%>:表示把表达式输出到页面中 - JSP声明
<%!声明变量或方法%>
如果加!,是成员变量.如果不加!,就是局部变量.
<body>
<%
System.out.println("hello jsp");
out.print("hello<br/>"); //打印
String str="HELLO<br/>";
out.println(str);
Date date = new Date();
long time = date.getTime();
out.print(time);
if(time % 2 == 1){
%>
<h1>奇数</h1>
<%
}else{
%>
<h1>偶数</h1>
<%
}
%>
</body>
3.3 jsp的指令
-
page指令
<%@page 属性名=属性值 属性名=属性值…%> -
include指令:可以包含其他页面,使用其他界面的数据
<%@ include file=包含的页面映射地址%> -
taglib指令:可以引入外部的标签库
<%@ taglib uri=标签库的地址 prefix=前缀名称%>
3.4JSP细节
- 九大隐式对象
- PageContext对象
是JSP独有的,Servlet中没有
是四大域对象之一的页面域对象,还可以操作其他三个域对象中的属性.
还可以获取其他八大隐式对象.(有对应的getXxx方法)
生命周期是随着JSP的创建而存在,随着JSP的结束而消失,每个JSP页面都是一个PageContext对象. - 四大域对象
4.EL表达式
作用:在JSP页面中获取域中的数据.
语法:${表达式内容}
EL表达式输出:${username}
4.1快速入门
<body>
<%--1.向域对象中添加数据--%>
<%request.setAttribute("username","zhangsan");%>
<%--2.获取数据--%>
java代码块:<% out.print(request.getAttribute("username"));%><br/>
JSP表达式:<%=request.getAttribute("username")%><br/>
EL表达式:${username}<br/>
</body>
4.2EL表达式获取数据
<body>
<%--1.获取基本数据类型--%>
<%pageContext.setAttribute("num",10);%>
${num}<br/>
<%--2.获取自定义对象类型--%>
<%
Student stu = new Student("张三","23");
pageContext.setAttribute("stu",stu);
%>
学生姓名:${stu.username}<br/>
学生年龄:${stu.age}<br/>
<%--3.获取数组类型--%>
<%
String[] arr = {"hello","world"};
pageContext.setAttribute("arr",arr);
%>
数组:${arr}<br/>
0索引:${arr[0]}<br/>
1索引:${arr[1]}<br/>
<%--4.获取List集合--%>
<%
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
pageContext.setAttribute("list",list);
%>
集合:${list}<br/>
<%--5.获取一个map集合--%>
<%
Map<String,Student> map = new HashMap<>();
map.put("hm01",new Student("李四","24"));
map.put("hm02",new Student("王五","25"));
pageContext.setAttribute("map",map);
%>
map集合:${map}<br/>
第一个学生对象:${map.hm01}<br>
第二个学生对象的姓名:${map.hm02.username}<br>
</body>
1.3注意事项
- EL表达式没有空指针异常
- EL表达式没有索引越界异常
- EL表达式没有字符串的拼接
1.4EL表达式运算符
- 关系运算符
- 逻辑运算符
- 其他运算符
<body>
<%--
empty
1.可以判断对象是否为空
2.可以判断字符串是否为空字符串
3.可以判断集合长度是否为0
--%>
<%
Student stu = new Student("zhangsan","23");
String str = "hello";
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
pageContext.setAttribute("stu",stu);
pageContext.setAttribute("str",str);
pageContext.setAttribute("list",list);
%>
${empty stu}<br>
${empty str}<br>
${empty list}<br>
<%--三元运算符--%>
<%pageContext.setAttribute("gender","women");%>
<input type="radio" name="gender" value="men" ${gender eq "men" ?"checked":""}/>男
<input type="radio" name="gender" value="women" ${gender eq "women" ?"checked":""}/>女
</body>
- EL表达式能够获取四大域对象中的数据,根据名称从小到大在域对象中查找.还可以回去JSP其他八大隐式对象,并调用对象中的方法.
5.JSTL
5.1JSTL介绍
jsp标准标签库:开发人员可以利用这些标签取代JSP页面上的java代码,从而提高程序的可读性,降低程序的维护难度.
核心标签库: core 通用的逻辑处理
国际化: fmt 不同地域显示不同语言
EL函数: functions EL表达式可以使用的方法
5.2 JSTL核心标签库
< 标签名:if> 用于条件判断
< 标签名:choose>< 标签名:when>< 标签名:otherwise> 用于多条件判断
< 标签名:forEach> 用于循环遍历
5.3jstl的基本使用
//导包
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<body>
<%--向域对象中添加数据--%>
<%pageContext.setAttribute("score","C");%>
<%--对成绩进行判断--%>
<c:if test="${score eq 'A'}">
优秀
</c:if>
<%--
对程序进行多条件判断
chooes:多条件选择
when:当...的时候.相当与if
test是接收集合的判断条件
eq是==
otherwise:其他条件都不满足时执行这条语句,相当于default
--%>
<c:choose>
<c:when test="${score eq 'A'}">优秀</c:when>
<c:when test="${score eq 'B'}">良好</c:when>
<c:when test="${score eq 'C'}">及格</c:when>
<c:when test="${score eq 'D'}">较差</c:when>
<c:otherwise>成绩非法</c:otherwise>
</c:choose>
</body>
<body>
<%--向域中添加集合--%>
<%
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
pageContext.setAttribute("list",list);
%>
<%--
遍历集合
var用于接收集合中的值.
items用于确定是哪个集合
--%>
<c:forEach items="${list}" var="str">
${str}<br>
</c:forEach>
</body>
6.Filter过滤器
6.1filter介绍
- Filter 是一个接口。如果想实现过滤器的功能,必须实现该接口!
- 核心方法
初始化方法: void init(FilterConfig config)
对请求资源和响应资源过滤: void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
销毁方法: void destroy()
6.2 filterChain
- FilterChain 是一个接口,代表过滤器链对象。由 Servlet 容器提供实现类对象。直接使用即可。
- 过滤器可以定义多个,就会组成过滤器链。
- 核心方法
放行方法: void doFilter(ServletRequest request,ServletResponse response)
如果有多个过滤器,在第一个过滤器中调用下一个过滤器,依次类推。直到到达最终访问资源。如果只有一个过滤器,放行时,就会直接到达最终访问资源。
6.3过滤器使用
//servlet
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("FilterServlet1执行了...");
resp.getWriter().write("FilterServlet1执行了..");
}
//flter
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterDemo执行了...");
//处理乱码
servletRequest.setCharacterEnCoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
//放行
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("FilterDemo执行完后回来了...");
}
}
6.4使用细节
- 配置方式
注解方式 @WebFilter(拦截路径)
配置文件方式
与servlet的配置方式一样 - 多个过滤器使用循序
配置文件方式取决于过滤器映射顺序
注解方式取决于类名的字母顺序.
6.5 过滤器生命周期
- 创建
当应用加载时实例对象并执行init初始化方法 - 服务
对象提供服务的过程,执行 doFilter 方法。 - 销毁
当应用卸载时或服务器停止时对象销毁。执行 destroy 方法。
6.6 FilterConfig
- FilterConfig 是一个接口。代表过滤器的配置对象,可以加载一些初始化参数。
- 核心方法
获取过滤器对象名称: String getFilterName()
根据key获取value: String getInitParameter(String key)
获取所有参数的key: Enumeration getInitParameterNames()
获取应用上下文对象: ServletContext getServletContext()