Web03
1.Listener
Listener 监听器
Listener 是 JavaEE 的规范,接口
监听某种事物的变化通过回调函数反馈给客户(程序)相应处理
ServletContextListener
监听 ServletContext 对象的创建和销毁:
-
web 工程启动的时候创建,调用contextInitialized(ServletContextEvent sce);
-
在 web 工程停止的时候销毁,调用contextDestroyed(ServletContextEvent sce);
使用:
-
编写一个类去实现 ServletContextListener
-
实现其两个回调方法
-
到 web.xml 中去配置监听器
<listener>
<listener-class>
com.atguigu.listener.MyServletContextListenerImpl
</listener-class>
</listener>
2.文件上传
非常常见的功能
2.1 上传
1#步骤
-
form 标签,method=post
-
form 标签的 encType 属性值必须为 multipart/form-data 值
(提交的数据多段拼接,每个表单项对应一个数据段,以二进制流形式发给服务器)
-
form 标签中使用 input type=file 添加上传的文件
-
服务器代码(Servlet 程序)接收,处理上传的数据
2#commons-fileupload.jar
导入两个 jar 包:
-
commons-fileupload-1.2.1.jar
-
commons-io-1.4.jar
常用的类:
ServletFileUpload 类:解析上传的数据
-
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request);
判断当前上传的数据格式是否是多段的格式
-
public List<FileItem> parseRequest(HttpServletRequest request) 解析上传的数据
FileItem 类:表示每一个表单项
-
boolean FileItem.isFormField() 判断当前表单项:true 普通表单项/false 上传文件类型
-
String FileItem.getFieldName() 获取表单项 name 属性
-
String FileItem.getString() 获取当前表单项的值
-
String FileItem.getName() 获取上传的文件名
-
void FileItem.write( file )上传文件写到 file 指向的硬盘位置
3#fileupload 类库
实例:
public class UploadServlet extends HttpServlet {
2.2 下载
实例:
file文件夹放在web目录下,访问此servlet即下载此文件
public class DownloadServlet extends HttpServlet {
中文乱码
判断请求头中 User-Agent
String ua = request.getHeader("User-Agent"); // 判断是什么浏览器
if (ua.contains("Firefox")) { }
1.URLEncoder IE 和谷歌浏览器
// 把中文名进行 UTF-8 编码操作。 String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
// 然后把编码后的字符串设置到响应头中
response.setHeader("Content-Disposition", str);
2.BASE64 编解码 火狐浏览器
// 使用下面的格式进行 BASE64 编码后
String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
// 设置到响应头中
response.setHeader("Content-Disposition", str);
3.Cookie
Cookie 是服务器通知客户端保存键值对的一种技术
每个 Cookie 的大小不能超过 4kb
每次请求都发送给服务器
3.1 创建Cookie
-
客户端请求
-
服务器创建 Cookie cookie = new Cookie("key","value");可多个
-
回应客户端 response.addCookie(cookie);
-
客户端收到响应头 Set-Cookie,新建或修改Cookie
3.2 服务器获取Cookie
-
客户端发送Cookie
-
服务器获取 request.getCookies(); 返回Cookie[]数组
public class CookieUtils {
/**
* 查找指定名称的 Cookie 对象
* @param name
* @param cookies
* @return
*/
public static Cookie findCookie(String name , Cookie[] cookies){
if (name == null || cookies == null || cookies.length == 0) {
return null;
}
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
}
3.3 修改Cookie
方法一
-
创建一个同名 key 的 Cookie 对象,同时赋于新的 Cookie 值
-
Cookie cookie = new Cookie("key1","newValue1");
-
-
通知客户端保存修改
-
resp.addCookie(cookie);
-
方法二
-
查找要修改的 Cookie 对象 使用上节工具类方法
-
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
-
-
调用 setValue()方法赋新的 Cookie 值
-
cookie.setValue("newValue2");
-
-
调用 response.addCookie()通知客户端保存修改
-
resp.addCookie(cookie);
-
3.4 Cookie生命控制
管理 Cookie 什么时候被销毁
setMaxAge()
-
正数,表示在指定的秒数后过期
-
负数,表示浏览器一关,Cookie 就会被删除(默认值是-1)
-
零,表示马上删除 Cookie
设置后再addCookie(cookie);保存修改
3.5 Cookie有效路径
path 属性可以有效的过滤哪些 Cookie 可以发送给服务器
path 属性是通过请求的地址来进行有效的过滤
CookieA path=/工程路径
请求地址为 http://ip:port/工程路径/xxxx 时会发送CookieA
4.Session
Session 是一个接口(HttpSession)
Session 会话 用来维护客户端和服务器之间关联
每个客户端都有自己的一个 Session 会话
保存用户登录之后的信息,保留在服务器
4.1 创建 获取
request.getSession()
-
第一次调用:创建 Session 会话
-
之后调用:获取前面创建好的 Session 会话对象
isNew()
-
true 表示刚创建
-
false 表示获取之前创建
getId()
-
得到 Session 的会话 id 值
4.2 获取数据
req.getSession().setAttribute("key1", "value1");
Object attribute = req.getSession().getAttribute("key1");
4.3 Session生命周期
public void setMaxInactiveInterval(int interval)
设置 Session 的超时时间(以秒为单位)
-
值为正数的时候,设定 Session 的超时时长 默认30 分钟
-
负数表示永不超时
public int getMaxInactiveInterval()
获取 Session 的超时时间
public void invalidate()
让当前 Session 会话马上超时无效
web.xml中配置全局
<!--表示当前 web 工程。创建出来 的所有 Session 默认是 20 分钟 超时时长-->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
5.Filter
5.1 过滤 登录
Filter 过滤器是 JavaEE 的规范、接口
只关心请求地址是否匹配,不关心请求资源是否存在
作用是:拦截请求,过滤响应

使用步骤:
-
编写一个类去实现 Filter 接口
-
实现过滤方法 doFilter()
public class AdminFilter implements Filter {
/*** doFilter 方法,专门用于拦截请求。可以做权限检查 */
-
到 web.xml 中去配置 Filter 的拦截路径
<!--filter 标签用于配置一个 Filter 过滤器-->
<filter>
<!--给 filter 起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置 filter 的全类名-->
<filter-class>com.atguigu.filter.AdminFilter</filter-class>
</filter>
<!--filter-mapping 配置 Filter 过滤器的拦截路径-->
<filter-mapping>
<!--filter-name 表示当前的拦截路径给哪个 filter 使用-->
<filter-name>AdminFilter</filter-name>
<!--url-pattern 配置拦截路径
/ 表示请求地址为:http://ip:port/工程路径/ 映射到 IDEA 的 web 目录
/admin/* 表示请求地址为:http://ip:port/工程路径/admin/*
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
5.2 Filter生命周期
web 工程启动时执行:(Filter 已经创建)
-
构造器方法
-
init 初始化方法
每次拦截到请求,就会执行:
-
doFilter 过滤方法
停止 web 工程时:
-
destroy 销毁
5.3 FilterConfig类
Filter 过滤器的配置文件类
每次创建 Filter ,同时创建一个 FilterConfig 类
获取 filter 过滤器的配置内容:
-
获取 Filter 的名称 filter-name 的内容 :filterConfig.getFilterName()
-
获取在 Filter 中配置的 init-param 初始化参数 :filterConfig.getInitParameter("username")
-
获取 ServletContext 对象:filterConfig.getServletContext()
web.xml 配置
<filter>
<!--给 filter 起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置 filter 的全类名-->
<filter-class>com.atguigu.filter.AdminFilter</filter-class>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
</filter>
5.4 FilterChain过滤器链
多个过滤器:
-
所有filter和目标资源默认同一线程
-
多个filter共同执行时共享一个Request对象
-
执行的优先顺序为web.xml的配置顺序
FilterChain.doFilter()方法:
-
执行下一个过滤器
-
若没有则执行目标资源
5.5 Filter拦截路径
精确匹配:
<url-pattern>/target.jsp</url-pattern>
请求地址必须为:http://ip:port/工程路径/target.jsp
目录匹配:
<url-pattern>/admin/*</url-pattern>
请求地址必须为:http://ip:port/工程路径/admin/*
后缀名匹配:
<url-pattern>*.xxx</url-pattern>
请求地址必须以.xxx 结尾才会拦截到
6.ThreadLocal
解决多线程的数据安全问题
特点:
-
ThreadLocal 可以为当前线程关联一个数据(可以像 Map 一样存取数据,key 为当前线程)
-
每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例
-
每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型
-
ThreadLocal 中保存数据,在线程销毁后由 JVM 虚拟自动释放
方法:
-
ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
-
ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
-
ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
-
ThreadLocal.initialValue: ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值
6.1 组合管理事务
使用 ThreadLocal 来确保所有 dao 操作都在同一个 Connection 连接对象中完成

浙公网安备 33010602011771号