6.请求重定向
- 请求重定向是指服务器接收到客户端请求后,可能由于某些条件限制,不能访问请求指定的资源,让客户端去访问另一个指定的资源
- HttpServletResponse定义了一个sendRedirect()方法,用于生成304响应状态码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL
- 方法:
void sendRedirect(String location)
- location可以使用相对路径重定向到同一个Web服务器的其他Servlet,也可以绝对路径重定向到其他Web服务器
- 注意:重定向时会重新生成另一个HttpServletRequest对象,所以不能实现Servlet的共享数据,如果需要共享数据那么可以使用请求转发
7.设置缓存时间
- 对于不经常变化的数据,可以设置缓存时间减少频繁访问服务器,提高效率
- 使用
void setDateHeader(String name,long time)
方法来设置响应头 - 范例:
resp.setDateHeader("Expires",System.currentTimeMills+1*60*60*1000)
,设置缓存时间为1个小时
8.设置定时刷新
- 定时刷新是指设置经过某个时间后自动跳转到某个页面
- 使用
void setHeader(String name,String value)
方法 - 范例:
resp.setHeader("Refresh","3;URL=/虚拟目录/demo.html");
8.文件下载
- 实现在浏览器中下载文件的功能,步骤如下:
- 创建字节输入流,关联读取的文件
- 设置响应消息头支持的类型
- 设置响应消息头以下载方式打开资源
- 通过响应对象获得字节输出流对象
- 循环读写
- 释放资源
- 范例
@WebServlet("/ServletDownloadDemo") public class ServletDownloadDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 创建字节输入流,关联读取的文件 String realPath = getServletContext().getRealPath("/img/ServletLive.png"); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath)); //2. 设置响应消息头支持的类型 //Content-Type是消息头名称,表示支持的类型 //application/octet-stream是消息头参数,表示字节流 resp.setHeader("Content-Type","application/octet-stream"); //3. 设置响应消息头以下载方式打开资源 //Content-Disposition是消息头名称,表示处理形式 //attachment;filename=ServletLive.png是消息头参数,表示附件形式处理,filename表示文件名称 resp.setHeader("Content-Disposition","attachment;filename=ServletLive.png"); //4. 通过响应对象获得字节输出流对象 ServletOutputStream outputStream = resp.getOutputStream(); //5. 循环读写 byte[] bytes = new byte[1024]; int len; while((len = bis.read(bytes)) != -1){ outputStream.write(bytes,0,len); } //6. 释放资源 bis.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
六.会话技术
1. 概述
- 会话是指客户端和服务器之间的多次请求和响应
- 为了实现一些功能,浏览器和服务器可能会产生多次的请求和响应,从浏览器访问服务器开始,到访问服务器结束,这期间产生的多次请求和响应加在一起就称为浏览器和服务器之间的一次会话
- 为了保存会话过程中产生的数据,我们可以通过会话技术(Cookie和Session)来实现
2.Cookie
- Cookie是一种会话技术,可以将会话过程中的数据保存在用户的浏览器中,从而使浏览器和服务器之间更好的进行数据交互
- Cookie是一个类,有一些属性和方法,用于设置Cookie
- 发送一个Cookie使用HttpServletResponse的
void addCookie(Cookie cookie)
方法,通过这个方法可以将Cookie添加到响应头中然后响应给浏览器 - 浏览器最多接收20个来自同一个网站的Cookie,并且浏览器只允许存放300个Cookie,每个Cookie的大小限制在4k以内
- 浏览器通过将Cookie添加到请求头中发送到服务器端,可以通过HttpServletRequest的
Cookie[] getCookie()
方法获取到一个Cookie数组,这些Cookie可能有相同的名称但是路径不同 - 构造方法
public Cookie(String name,String value)
,name属性一旦创建将不能更改,但是value可以更改 - Cookie常用属性
属性 |
作用 |
是否重要 |
name |
Cookie名称 |
必须属性 |
value |
Cookie的值(不支持中文) |
必须属性 |
path |
Cookie的路径 |
重要 |
domain |
Cookie的域 |
重要 |
maxAge |
Cookie存活时间 |
重要 |
version |
Cookie版本号 |
不重要 |
comment |
Cookie描述 |
不重要 |
- Cookie常用方法
- Cookie常用方法是对Cookie相关属性的get或者set,但是需要注意name属性没有set方法
- setMaxAge(int expirt)和getMaxAge()方法解析
- 这两个方法用于设置和返回Cookie在浏览器上保持的有效秒数,其中设置的值有如下规则
- 正整数表示在没有超过指定秒数之前这个Cookie会一直存在
- 负整数表示当浏览器关闭时Cookie信息会被清除
- 0表示浏览器会立即删除这个Cookie信息
- 默认是-1
- setPath(String uri)和getPath()方法解析
- 这两个方法是针对path属性的设置和获取
- 如果创建的Cookie对象没有设置path属性的值,那么默认该Cookie只对当前请求路径所属的目录以及子目录有效
- 如果想让某个Cookie对象对站点的所有目录下的访问路径的都有效,那么可以设置为"/"
- 设置path的格式是contextPath+自定义路径
- setDomain(String pattern)和getDomain()
- 这两个方法是针对domain属性的设置和获取,domain属性用于指定Cookie所在的域
- 默认为服务器主机地址,当浏览器想要访问该服务器的资源时会将该Cookie信息发送给服务器
- 如果想让不同的域之间都可以访问到某个Cookie,那么Cookie的domain应该是这些域的相同后缀,而且必须以.开头
3.Session
- Session也是会话技术的一种,与Cookie不同的是,在客户端保存的是一个标识,而会话产生的数据保存在服务器端
- 当浏览器第一次请求服务器时,服务器会创建一个Session对象,该对象有唯一的一个标识,然后服务器将这个标识以Cookie的方式发送给浏览器
- 当浏览器再一次请求服务器时会将这个标识发送过来,服务器根据这个标识就可以找到对应的Session对象了
- Session也是域对象之一,可以实现数据共享
- 通过创建一个HttpSession对象来实现Session,HttpSession是一个接口,我们不直接创建这个对象而是服务器负责创建,我们使用的时候获取即可
- 获取方式:通过HttpServletRequest对象获取,有两个方法
HttpSession getSession()
,获取HttpSession对象HttpSession getSession(boolean create)
,获取HttpSession对象,未获取到是否创建
- HttpSession常用方法
方法 |
说明 |
String getID() |
返回与当前HttpSession对象关联的会话标识号 |
long getCreationTime() |
返回Session创建时间 |
long getLastAccessedTime() |
返回客户端最后一次发送与Session相关请求的时间 |
void setMaxInactiveInterval(int interval) |
用于设置当前Session对象可空闲的最长时间,单位为秒 |
boolean isNew() |
判断当前HttpSession对象是否是新建的 |
void invalidate() |
强制使Session对象无效 |
ServletContext getServletContext() |
返回当前HttpSession对象所属的ServletContext对象 |
void setAttribute(String name,Object value) |
存储一个指定名称的数据对象,可以用于共享 |
String getAttribute() |
用于从当前HttpSession对象中返回指定名称的属性值 |
void removeAttribute(String name) |
用于从当前HttpSession对象中删除指定名称的属性值 |
- Session生命周期
- Session生效
- Session在用户第一次访问服务器时创建
- 只有访问JSP、Servlet等程序时才会创建Sessin
- 只访问HTML、IMAGE等静态资源时不会创建Session
- Session失效
两种方式:
- Web服务器使用“超时限制”判断客户端是否还在继续访问。在一定时间内,如果某个客户端没有请求访问,那么Web服务器认为该客户端已经结束请求,并且与该客户端会话所对应的HttpSession对象会变成垃圾对象,等待垃圾收集器将其从内存中清除。如果超时后再次向服务器发出请求访问,那么Web服务器会创建一个新的HttpSession对象,并分配一个新的标识
- 使用
invalidate()
方法,可以强制使得Session失效
设置失效时间:使用setInactiveInterval(int interval)
方法可以设置Session最长的空闲时间,当超过这个时间客户端没有请求访问则Session失效
七.Filter
1.概述
- Filter称为过滤器,位于客户端与处理程序之间,能够对请求和响应进行检查和修改
- 当客户端对服务器资源发送请求时,服务器根据过滤规则进行检查,如果满足过滤规则,则对客户请求进行拦截,然后对请求头或请求数据进行修改或检查,并依次通过Filter链,最后将请求交给处理程序
- 请求信息可以在过滤器中被修改,也可以根据请求条件不让请求发往处理程序
- 拦截过程
2.Filter接口
- 编写一个Filter必须实现Filter接口
- 相关方法
方法名 |
说明 |
default void init(FilterConfig filterConfig) |
创建Filter后用于初始化Filter,通过参数FilterConfig对象获取配置参数 |
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) |
用于完成过滤的操作,其中Request对象和Response对象是由上一个过滤器或者Web服务器传递过来的请求和响应对象,FilterChain对象代表当前过滤链对象 |
default void destroy() |
用于释放过滤器中占用的资源,在对象被销毁之前调用 |
- Filter接口提供了三个方法,其中init()方法和destroy()方法是默认方法不强制重写,而doFilter()方法是抽象方法,在实现Filter接口时必须重写
3.Filter配置
- 配置Filter有两种方式,一种是通过web.xml文件进行配置,一种是通过@WebFilter注解进行配置
- web.xml配置方式
FilterDemo com.liaoxiangqian.filter.FilterDemo FilterDemo /ServletDemo
- @WebFilter注解配置方式
@WebFilter("/ServletDemo") public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("FilterDemo执行了"); } }
@WebFilter常用属性
属性名 |
类型 |
说明 |
filterName |
String |
指定过滤器名称 |
urlPattren |
String[] |
指定需要过滤的资源,如某个Servlet或Jsp |
value |
String[] |
等价于urlPattern,不能同时使用 |
servletNames |
String[] |
指定过滤器将应用于哪些Servlet,取值是@WebServlet中name属性的取值 |
dispatcherTypes |
DispatcherType |
指定过滤器转发模式,取值有ERROR、FORWARD、INCLUDE、REQUEST |
initParams |
WebInitParam[] |
指定过滤器的一组初始化参数 |
- 注意
- DispatcherType是枚举类,取值的作用如下:
- DispatcherType.ERROR表示过滤器拦截那些跳转到某个异常处理页面的请求
- DispatcherType.FORWARD表示过滤器拦截那些通过forward()方法来请求的转发的请求
- DispatcherType.INCLUDE表示过滤器拦截那些通过include()方法来请求包含的请求
- DispatcherType.REQUEST表示过滤器只会拦截普通的请求,而请求转发和请求包含类的请求不会拦截
- 如果需要拦截用户的所有请求,则可以使用*号通配符,如
/*
4.FilterConfig接口
- FilterConfig接口用于封装Filter的配置信息,在Filter初始化时,服务器将FilterConfig对象作为参数传递给Filter对象的init()方法
- FilterConfig相关方法
方法名 |
说明 |
String getFilterName() |
获取Filter的名称 |
ServletContent getServletContext() |
获取ServletContext对象 |
String getInitParameter(String name) |
根据名称获取初始化参数值 |
Enumeration getInitParameterNames() |
返回一个包含所有初始化参数名的Enumeration对象 |
- 配置初始化参数的方式
- 在web.xml中配置,注意是在标签下方进行配置
username liaoxiangqian
- 在@WebFilter中使用initParams属性配置
@WebFilter(initParams = {@WebInitParam(name="username",value="liaoxiangqian")})
注意initParams属性类型是注解型数组
- 添加初始化的参数后可以通过FilterConfig来获取这些参数
5.FilterChain接口
- FilterChain对象表示当前过滤器所在的过滤链
- 一个Web应用程序中存在多个Filter,每个Filter都可以对某个请求进行拦截,如果多个Filter都对同一个请求进行拦截,那么这些Filter就组成一个Filter链,使用FilterChain对象表示
- 一个方法
void doFilter(ServletRequest var1, ServletResponse var2)
FilterChain提供的doFilter()方法,作用是让Filter链上的当前过滤器放行,使请求进入下一个Filter
6.Filter生命周期
- Filter生命周期可以分为创建、执行、销毁三个阶段
- 创建阶段:Web服务器启动的时候会创建Filter对象,并调用init()方法,完成对象的初始化,在一次完整请求中Filter对象只会被创建一次,init()方法只会被调用一次
- 执行阶段:客户端发出请求时,服务器筛选出符合拦截条件的过滤器,按照类名的顺序依次执行doFilter()方法,doFilter()在一次完整请求中会执行多次
- 销毁阶段:服务器关闭时,Web服务器调用destroy()方法销毁对象
八.Listener
1.概述
- Web程序开发中,可以对对象的创建和销毁、域对象中属性的变化、会话相关内容进行监听
- Servlet中提供八个监听器,都是以接口的形式提供,具体功能需要自行完善
- 相关概念
- 事件:触发的动作
- 事件源:产生事件的对象
- 事件监听器:监听发生在事件源上的事件
- 事件处理器:监听器的成员方法,事件发生时会触发该方法
2.监听对象的创建和销毁的监听器
- ServletContextListener接口
- 用于监听ServletContext对象的创建与销毁
- 核心方法
方法 |
说明 |
void contextInitialized(ServletContextEvent sce) |
ServletContext对象创建时执行 |
void contextDestroyed(ServletContextEvent sce) |
ServletContext对象销毁时执行 |
- HttpSessionListener接口
- 用于监听HttpSession对象的创建与销毁
- 核心方法
方法 |
说明 |
void sessionCreated(HttpSessionEvent se) |
HttpSession对象创建时执行 |
void sessionDestroy(HttpSessionEvent se) |
HttpSession对象销毁时执行 |
- ServletRequestListener接口
- 用于监听ServletRequest对象的创建与销毁
- 核心方法
方法 |
说明 |
void requestInitialized(ServletRequestEvent sre) |
ServletRequest对象创建时执行 |
void requestDestroyed(ServletRequestEvent sre) |
ServletRequest对象销毁时执行 |
3.监听域对象属性变化的监听器
- ServletContextAttributeListener接口
- 用于监听ServletContext中属性的变化
- 核心方法
方法 |
说明 |
void attributeAdded(ServletContextAttributeEvent scae) |
域中添加属性时执行 |
void attributeRemoved(ServletContextAttributeEvent scae) |
域中移除属性时执行 |
void attributeReplaced(ServletContextAttributeEvent scae) |
域中替换属性时执行 |
- HttpSessionAttributeListener接口
- 用于监听HttpSession中属性的变化
- 核心方法
方法 |
说明 |
void attributeAdded(HttpSessionBindingEvent se) |
域中添加属性时执行 |
void attributeRemoved(HttpSessionBindingEvent se) |
域中移除属性时执行 |
void attributeReplaced(HttpSessionBindingEvent se) |
域中替换属性时执行 |
- ServletRequestAttributeListener接口
- 用于监听ServletRequest中属性的变化
- 核心方法
方法 |
说明 |
void attributeAdded(ServletRequestAttributeEvent srae) |
域中添加属性时执行 |
void attributeRemoved(ServletRequestAttributeEvent srae) |
域中移除属性时执行 |
void attributeReplaced(ServletRequestAttributeEvent srae) |
域中替换属性时执行 |
4.监听会话相关的感知型监听器
- HttpSessionBindingListener接口
- 用于监听JavaBean对象绑定到HttpSession对像和从HttpSession对象解绑的事件
- 核心方法
方法 |
说明 |
void valueBound(HttpSessionBindingEvent event) |
数据绑定(添加)到会话域时执行 |
void valueUnbound(HttpSessionBindingEvent event) |
数据从会话域解绑(移除)时执行 |
- HttpSessionActivationListener接口
- 用于监听HttpSession中对象活化(恢复到内存)和钝化(持久化到硬盘)的过程
- 核心方法
方法 |
说明 |
void sessionWillPassivate(HttpSessionEvent se) |
会话域中数据钝化时执行 |
void sessionDidActivate(HttpSessionEvent se) |
会话域中数据活化时执行 |
5.监听器的实现
- 步骤
- 将监听器绑定到事件源,也就是注册监听器
- 监听器监听到事件发生时,将事件对象作为参数传给相关的成员方法
- 成员方法可以根据事件对象获取事件源,然后进行处理
- 注册监听器的方式有两种,一种是通过web.xml文件,一种是通过注解的方式
- 通过web.xml注册
com.liaoxiangqian.listener.MyListener
- 通过注解注册
//在监听器实现类上方使用该注解进行注册
@WebListener