全面学习Servlet与JSP入门与提高(第二篇)

6. 状态管理–cookie
7.状态管理–session
8.Servlet声明周期
9.过滤器,Servlet处理多个请求
10.监听器,Servlet上下文,Servlet线程安全

<6>.状态管理–cookie

(1)什么是状态管理?

将浏览器与web服务器之间多次交互当做一个整体来处理,并且将多次交互所产生的数据(即状态)保存下来。

(2)如何进行状态管理?

a.方式一  将状态保存在浏览器端
通常使用Cookie技术。

b.方式二  将状态保存在服务器端
通常使用Session技术。

(3)Cookie

1)什么是Cookie?

服务器临时存放在浏览器端的少量数据,用于跟踪用户的状态。

当浏览器访问服务器时,服务器会将少量数据以
set-cookie消息头的方式发送给浏览器,浏览器
会将这些数据保存下来。
当浏览器再次访问服务器时,会将这些数据以cookie
消息头的方式发送给服务器。

在这里插入图片描述

2)如何添加Cookie?
Cookie c = new Cookie(String name,String value);
注:
	name一般称之为cookie名,value称之为cookie值,都必须是字符串。
response.addCookie(c);
3)如何读取Cookie?
Cookie[] request.getCookies();
注:
	该方法有可能返回null。
String cookie.getName();
String cookie.getValue();
4)cookie的生存时间

a.默认情况下,浏览器会将cookie保存在内存里面,浏览器只要关闭,cookie会被删除。

b.可以调用setMaxAge方法来设置cookie的生存时间

cookie.setMaxAge(int seconds);
注:
	a.单位是秒。
	b.当seconds > 0,浏览器会将cookie保存在硬盘上,当超过指定的时间,浏览器会将cookie删除。
	c.当seconds < 0,缺省值(浏览器会将cookie保存在内存里面)。
	d.当seconds = 0,删除cookie。
		比如,要删除一个名称为"username"的cookie,代码如下:
			Cookie c = new Cookie("username","");
			c.setMaxAge(0);
			response.addCookie(c);
5)cookie的编码问题

a.什么是cookie的编码问题?

cookie只能存放合法的ascii字符,如果要存放中文,需要将中文转换成合法的ascii字符的形式。

b.如何处理?

String URLEncoder.encode(String str,String charset);
String URLDecoder.decode(String str,String charset);

建议,在实际开发时,对添加的数据统一使用encode方法来编码。
6)cookie的路径问题

a.什么是cookie的路径问题?

浏览器访问服务器时,会比较请求地址是否与cookie的路径匹配,只有匹配的cookie才会被发送。

b.cookie的默认路径

cookie的默认路径等于添加该cookie的web组件的路径,比如AddCookieServlet(/day06/addCookie) 添加了一个cookie,则该cookie的默认路径是
"/day06"。

c.匹配规则

请求地址要么是等于cookie的路径,要么是cookie的子路径,只有符合该条件的cookie,浏览器才会发送出去。

在这里插入图片描述

d.修改路径

cookie.setPath(String path);
注:
	path就是路径。
7)cookie的限制

a. cookie可以被用户禁止。
b. cookie不安全。
对于敏感数据,一定要加密。

c. cookie只能保存少量的数据。
大约4k左右

d. cookie的数量也有限制。
大约是几百个

e. cookie只能保存字符串。

练习

写一个Servlet,该Servlet先查看有没有一个名称为"cart"的cookie,如果有,则显示该Cookie的值;如果没有,则添加之。

练习

在这里插入图片描述

<7>.状态管理–session

(1)session是什么?

服务器端为了保存状态而创建的一个特殊的对象。

注:
	当浏览器访问服务器时,服务器端创建一个特殊的对象(该对象一般称之为session对象,该对象有一个
唯一的id,一般称之为sessionId)。服务器会将sessionId以cookie的方式发送给浏览器。
	当浏览器再次访问服务器时,会将sessionId发送过来,服务器端可以依据sessionId找到对应的session
对象。

(2)如何获得session对象?

1)方式一:
HttpSession s = 
	request.getSession(boolean flag);
注:
	a.HttpSession是一个接口。
	b.如果flag为true:
			先查看请求当中是否有sessionId,如果没有,则创建一个session对象;如果有sessionId,则依据sessionId查找对应的session对象,如果找到了,则返回该对象,找不到,则创建一个新的
		session对象。
	c.如果flag为false:
		先查看请求当中是否有sessionId,如果没有,返回null;如果有sessionId,则依据sessionId查找对应的session对象,如果找到了,则返回该对象,找不到,返回null。

在这里插入图片描述

方式二:
HttpSession s = request.getSession();
等价于 request.getSession(true);

(3)常用方法

1)session.setAttribute(String name,Object obj);

注:
	以name作为key,以obj作为value,将数据存放到了一个Map对象里面。

2)Object session.getAttribute(String name);

注:
	如果绑订值不存在,返回null。

3)session.removeAttribute(String name);

注:
	解除绑订。

在这里插入图片描述

(4)session超时

a.什么是session超时?

服务器会将空闲时间过长的session对象删除掉。
注:
	缺省的超时时间长度一般是30分钟。

b.如何修改超时时间长度?

方式一 修改web.xml配置文件。

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

方式二  
session.setMaxInactiveInterval(int seconds)
注:
	设置两次请求之间的最大间隔时间,如果超过了该时间,则session对象会被删除。

(5)删除session

session.invalidate()

2. 登录
3. session验证

step1.登录成功之后,在session对象上绑订一些数据,
比如:

session.setAttribute("user",user);

step2.当用户访问需要受保护的资源时(即只有登录成功之后才能访问的资源,比如success.jsp),进行session验证,比如:

Object obj = session.getAttribute("user");
if(obj == null){
	//没有登录,重定向到登录页面
	response.sendRedirect("login.jsp");
	return;
}

在这里插入图片描述

练习
显示用户上一次访问的时间,如果是第一次访问,则输出“你是第一次访问”。

<8>.Servlet声明周期

1.比较session与cookie

session相对于cookie、优点是更安全、可以保存更多的数据、支持更丰富的数据类型。缺点是需要占用服务器端的内存空间。

2.Servlet的生命周期

(1)什么是servlet的生命周期?

servlet容器如何创建servlet对象、如何对该对象进行初始化处理、如何调用该对象处理请求,以及如何销毁该对象的整个过程。

在这里插入图片描述

(2)分成哪几个阶段?
1)实例化

a.什么是实例化?

容器调用servlet构造器,创建servlet对象。

b.什么时候实例化?

情形1: 容器收到请求之后,才会创建。
情形2: 容器启动之后,立即创建。
	注: 需要在web.xml文件当中,使用
		load-on-startup来配置。

在这里插入图片描述

c.容器只会创建一个实例!

2)初始化

a.什么是初始化?

容器在创建好servlet对象之后,会立即调用该对象的init(ServletConfig config)方法。
注:
	init方法只会调用一次!

b.GenericServlet已经提供了init方法的实现:

将容器传递过来的ServletConfig对象保存下来,并且提供了一个方法(getServletConfig)来获得该对象。

在这里插入图片描述

c.如何实现自已的初始化处理逻辑?

只需要override GenericServlet的init()方法。

在这里插入图片描述

d.初始化参数

在这里插入图片描述
在这里插入图片描述

3)就绪(调用)

a.什么是就绪?

容器收到请求之后,调用servlet对象的service方法来处理。

b.HttpServlet已经提供了service方法的实现:

依据请求类型调用对应的doXXX方法。
注:
	比如,get请求会调用doGet方法,post请求会调用doPost方法。

c.开发人员可以override HttpServlet的service方法,也可以override doXXX方法。

在这里插入图片描述

4)销毁

a.什么是销毁?

容器在删除servlet对象之前,会调用该对象的destroy方法。
该方法只会执行一次!

b. GenericServlet已经提供了destroy方法的实现:

什么都没有做。
开发人员可以override GenericServlet的destroy方法来实现自已的销毁处理逻辑。
(3)相关的接口与类

a. Servlet接口

init(ServletConfig config)
service(ServletRequest req,ServletResponse res)
destroy()

b. GenericServlet抽象类

实现了Servlet接口(主要是实现init、destroy方法)。

c. HttpServlet抽象类

继承了GenericServlet,实现了service方法。

2.容器处理异常

servlet可以将异常抛出给容器,由容器来处理。

step1.将异常抛出
	} catch (Exception e) {
		e.printStackTrace();
		//将异常抛出给容器,由容器来处理
		throw new ServletException(e);
	}
step2.配置异常处理页面
<!-- 配置异常处理页面 -->
<error-page>
	<exception-type>javax.servlet.ServletException</exception-type>
	<location>/error.jsp</location>
</error-page>
step3.添加异常处理页面
<%@ page pageEncoding="utf-8" 
contentType="text/html; charset=utf-8" %>
<html>
<head></head>
<body style="font-size:30px;color:red;">
	系统维护中,请稍后
	<a href="login.jsp">登录</a>
</body>
</html>

练习:计算一个人的BMI指数

bmi指数 = 体重(公斤) / 身高(米) / 身高(米);
如果 bmi指数 < 19,体重过轻。
如果 bmi指数 > 25,体重过重。
其它 体重正常。

19,25要使用初始化参数来配置。
<init-param>
	<param-name>min</param-name>
	<param-value>19</param-value>
</init-param>

<9>.过滤器,Servlet处理多个请求

(1)什么是过滤器?

servlet规范当中定义的一种特殊的组件,用于拦截servlet容器的调用过程。

注:
	容器收到请求之后,会先调用过滤器,再调用servlet或者其它资源。

在这里插入图片描述

(2)如何写一个过滤器?

step1.写一个java类,实现Filter接口。

step2.在doFilter方法里面,实现拦截处理逻辑。

step3.配置过滤器。(web.xml)

(3)过滤器的优先级

当有多个过滤器满足拦截的要求,则容器依据< filter-mapping>配置的先后顺序来执行。

(4)初始化参数

step1.配置初始化参数

<init-param>
	<param-name>size</param-name>
	<param-value>5</param-value>
</init-param>

step2.调用FilterConfig提供的getInitParameter方法来读取初始化参数

//读取初始化参数
int size = Integer.parseInt(config.getInitParameter("size"));

(5)过滤器的优点(思考)

练习

写一个过滤器,检查评论的字数,如果超过10个字,提示“评论字数过多”。

2.容器如何处理请求资源路径

比如,在浏览器地址栏输入http://ip:port/day09-2/abc.html,浏览器会将"/day09-2/abc.html"作为请求资源路径发送给服务器(容器)。

step1.默认认为访问的是一个servlet,容器会去查找对应的
servlet。

注:
	看web.xml文件中<url-pattern>的配置,有没有对应的servlet。

<url-pattern>有三种配置方式:
第一种:精确匹配
	比如 	
	<url-pattern>/abc.html</url-pattern>
第二种:通配符匹配
	使用 "*"号匹配任意的零个或者多个字符,比如
	<url-pattern>/*</url-pattern>
	<url-pattern>/demo/*</url-pattern>
第三种:后缀匹配
	使用"*."开头,后接一个后缀,比如
	<url-pattern>*.do</url-pattern>
	会匹配所有以.do结尾的请求。

step2 如果没有找到对应的servlet,容器会查找对应位置的文件。

3.如何让一个servlet处理多种请求?

step1.采用后缀匹配,比如

<servlet-mapping>
	<servlet-name>SomeServlet</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

step2.分析请求资源路径,进行相应的处理。

	//先获得请求资源路径
	String uri = request.getRequestURI();
	System.out.println("uri:"  + uri);
	//为了方便比较,截取请求资源路径的一部分
	String path = uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
	System.out.println("path:" + path);
	if("/login".equals(path)) {
		System.out.println("处理登录请求...");
	}else if("/list".equals(path)) {
		System.out.println("处理用户列表请求...");
	}

<10>.监听器,Servlet上下文,Servlet线程安全

(5)过滤器的优点

a.可以在不修改源代码的基础上,为应用添加新的功能。
b.可以将多个组件相同的功能集中写在过滤器里面,方便代码的维护。

1.监听器

(1)什么是监听器?

servlet规范当中定义的一种特殊的组件,用于监听servlet容器产生的事件并进行相应的处理。

注:
	主要有两大类事件:
	a.生命周期相关的事件:
		 当容器创建了或者销毁了request,session,servlet上下文时产生的事件。
	b.绑订数据相关的事件:
		 调用了request,session,servlet上下文的setAttribute和removeAttribute方法时产生的事件。
(2)servlet上下文
1)什么是servlet上下文?

容器在启动之后,会为每一个web应用创建唯一的一个符合ServletContext接口要求的对象,该对象会一直存在,除非应用被卸载或者容器关闭。

注:
	该对象有两个特点:
	a.唯一性:一个web应用对应一个上下文。
	b.持久性:上下文会一直存在,除非应用被卸载或者容器关闭。
2)如何获得servlet上下文

GenericServlet,ServletConfig,FilterConfig,HttpSession都提供了一个方法(getServletContext)来
获得该对象。

3)作用1 绑订数据
注:
	request,session,servlet上下文都提供了绑订数据相关的方法,区别如下:
	a.绑订的数据,生存的时间不一样:
	request < session < servlet上下文。
	在满足使用条件的情况下,优先使用生命周期短的。

在这里插入图片描述

	b.绑订的数据,可访问的范围不一样:
	绑订到session对象上的数据,只有与之对应的用户能够访问到;绑订到servlet上下文上的数据,所有用户都可以访问。

在这里插入图片描述

4)作用2:读取全局的初始化参数

step1.配置全局的初始化参数

<!-- 配置全局的初始化参数 -->
<context-param>
	<param-name>company</param-name>
	<param-value>IBM</param-value>
</context-param>

step2.调用servlet上下文的方法来读取

String company = 
		sctx.getInitParameter("company");
(3)如何写一个监听器?

step1.写一个java类,依据监听的事件类型选择实现相应的监听器接口。

注:
	比如,要监听session对象的创建和销毁,需要实现HttpSessionListener接口。

step2.在接口方法当中,实现监听处理逻辑。

step3.配置监听器。(web.xml)

统计在线人数

在这里插入图片描述

练习

在这里插入图片描述

2.servlet的线程安全问题

(1)为什么说servlet会有线程安全问题?

a.容器只会创建一个servlet实例。

b.容器收到一个请求,就会启动一个线程,由该线程来处理对应的请求。
如果有多个线程同时去调用某个servlet实例的方法,就有可能产生线程安全问题,比如,这些线程要修改servlet的某个属性值。

在这里插入图片描述

(2)如何解决?

使用synchronized对有可能产生线程安全问题的代码加锁。

注:
	加锁会影响性能。

3.servlet小结

(1)servlet基础
1)什么是servlet?
2)如何写一个servlet?
3)servlet是如何运行的?
4)http协议(了解)	
(2)servlet核心
1)如何读取请求参数值?
2)表单包含有中文参数值,如何处理?
3)servlet输出中文,如何处理?
4)容器如何处理请求资源路径?
5)如何让一个servlet处理多种请求?
6)转发与重定向
	a.什么是重定向?
	b.如何重定向?
	c.重定向的特点?
	d.什么是转发?
	e.如何转发?
	f.转发的特点?
	g.比较转发与重定向
7)线程安全问题
8)servlet的生命周期
	a.什么是servlet的生命周期?
	b.生命周期分成哪几个阶段?
	c.容器会创建几个servlet实例?
	d.load-on-startup
	e.如何实现自已的初始化处理逻辑?
	f.初始化方法会执行几次?
	g.doGet/doPost方法的作用?
	h.相关的接口与类(Servlet,GenericServlet,
		HttpServlet)。
	i.ServletConfig。
	j.初始化参数的配置。
9)路径问题
10)servlet上下文
	a.什么是servlet上下文?
	b.有什么特点?
	c.如何获得servlet上下文?
	d.作用
11)将异常抛给容器来处理	
(3)状态管理
1)什么是状态管理?
2)如何进行状态管理?
3)Cookie
	a.什么是cookie?
	b.如何添加cookie?
	c.添加cookie时需要考虑的三个问题:
		生存时间
		编码问题
		路径问题
	d.如何读取cookie?
	e.cookie有哪些限制?
4)Session
	a.什么是session?
	b.如何获得session对象?
	c.session常用的方法
	d.session超时
	e.如何删除session?	
	f.比较session与cookie?
(4)数据库访问
1)什么是dao?
2)如何写一个dao?
(5)过滤器与监听器
(6)典型案例
用户管理
登录(session验证)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值