Cookie对象
浏览器缓存技术,只存储在浏览器中
cookie的大小在4kb左右,每个浏览器在同一域名下能存放cookie数量是有限的
优缺点:提高网页的效率,减轻服务器的负载;安全性较差。
1 创建及发送
Cookie cookie = new Cookie("key","value")
response.addCookie(cookie对象)
注:创建同名的cookie会覆盖之前的cookie(在相同的domain和path下)
2 获取cookie
request.getCookies() 获取所有上传的cookie对象数组 再遍历获取
单个cookie对象获取数据 对象.getName()和对象.getValue()
3 中文处理
URLEncoder.encode("姓名")将中文字符串进转码
URLDecoder.decode(value)将对象解码为中文,(若本来就是中文不会乱码)
Cookie cookie = new Cookie(URLEncoder.encode("姓名"),URLEncoder.encode("张三")) |
4 到期时间设置
在创建后发送前设置
cookie.setMaxAge(int)
参数为 负数 默认该cookie在关闭浏览器后失效
0 立即删除cookie 用在对同名cookie进行删除中
正数 cookie保留秒数
5只有访问的地址中包含cookie的path值时,才能得到cookie对象
httpSession对象
session用于标记一次会话,一次会话中服务端与客户端的多次请求响应交互
用在确认当前当前交互的用户 并且在一次会话(一个用户的多次请求)期间共享数据
依赖cookie技术环境
在cookie总存储了JSESSIONID和对应的SessionId值, SessionId值用于标识会话
session的作用域是整个项目,请求转发和项目内重定向都有效
获取session对象
HttpSession session = req.getSession(); 获取session
session对象的方法
getId() 获取会话标识符
getCreationTime() 获取创建时间
getLastAccessedTime() 获取最后访问时间
isNew() 判断是否是新创建的对象
setMaxInactiveInterval(int) 设定 session 的最大不活动时间,单位为秒
getMaxInactiveInterval() 获取 session 的最大不活动时间
invalidate() session直接失效
session对象的参数处理方法
setAttribute(name,value) 方法向域对象中添加数据,
getAttribute(name) 从域对象中获取数据,
removeAttribute(name) 从域对象中移除数据
SessionId 是为了标识一次会话的唯一标志。
一个请求到达服务器后,若开启了会话(访问了 session),
服务器第一步会查看是否从客户端回传一个名为 JSESSIONID 的 cookie
如果JSESSIONID不存在,则服务器会新建session对象,并重新标识
如果JSESSIONID存在,服务器根据ID去服务器中查找与之对应的session对象
如果没找到,则服务器会新建session对象,并重新标识
如果找到,则获取 session对象,响应给客户端
Session的失效
1、达到最大不活动时间
Tomcat中默认30分钟,可通过服务器的(web.xml)配置进行修改
<session-config>
<session-timeout>30</session-timeout>
</session-config>
2、自己设定过期时间
setMaxInactiveInterval(int) 设定 session 的最大不活动时间,单位为秒。
getMaxInactiveInterval() 获取Session 对象的最大不活动时间。
3、立即失效
方法 .invalidate()
4、关闭浏览器 session的底层依赖于cookie,默认关闭浏览器失效。
5、关闭服务器
非正常关闭服务器时才会失效。
正常关闭服务器,session会被钝化存储,下次访问时自动活化出来。
ServletContext对象
服务器中每个web项目只有一个ServletContext对象(application对象)应用对象
作用:
1提供应用的相关信息
getServerInfo() 获取服务器版本
getRealPath() 获取项目在服务器中真实路径
2作为域对象,共享数据, 整个应用中都有效
获取sevletcontext对象
request.getServletContext() 通过request对象获取
sexsion. getServletContext() 通过sexsion回话对象获取
getServletConfig().getServletContext() 直接获取
getServletContext() 直接获取
对sevletcontext域对象进行操作的方法
setAttribute(name,value);方法向域对象中添加数据
getAttribute(name) 从域对象中获取数据
removeAttribute(name)从域对象中移除数据
过滤器
过滤器用于对服务器的请求和响应进行预处理
1实现步骤
1创建实现javax.servlet.Filter接口的类
public class Filter01 implements Filter { }
2类中实现过滤方法
doFilter() 过滤方法
传入了ServletRequest, ServletResponse, FilterChain对象
通过FilterChain对象执行doFilter ()放行方法
在response()之前的代码处理request内容
在response()之后的代码处理response内容
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException { // req代码 System.out.println("Filter01准备过滤..."); // 放行资源 chain.doFilter(request, response); // 处理响应要在放行之后 System.out.println("Filter01过滤完毕..."); } |
init()
初始化方法,内部写入初始化参数和代码
destroy()
过滤器销毁,正常销毁执行内部代码
3配置web.xml
<filter> <display-name>Filter02</display-name> <filter-name>Filter02</filter-name> <filter-class>com.shsxt.filter.Filter02</filter-class> </filter> |
<filter-mapping> <filter-name>Filter02</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
配置方式与servlet基本相同
1 url-pattern 指代需要设置筛选器的资源的路径
可以设置多个,一般选择通用也就是/*
2 两个<filter-name>需要保持一致
3 filter-mapping还可以设置
<servlet-name> 要拦截的servlet的servlet-name的值
<dispatcher> 拦截资源被servlet容器嗲用的方式
2 过滤器链
服务器资源被多个过滤器绑定
在request请求阶段,以过滤器在web.xml中的配置顺序执行代码
在response响应阶段,以与请求阶段相反的顺序执行代码
通过在response阶段不做处理
3 通用字符乱码过滤器
POST请求使用request.setCharacterEncoding("UTF-8")
GET请求在判断为tomcat7版本以下时根据自定义包装类进行处理响应
定义
自定义包装类继承HttpServletRequestWrapper,重写getParameter方法
调用
HttpServletRequest myRequest = new MyWapper(request);
chain.doFilter(myRequest, response);
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { // 基于Http HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; // 处理POST请求 request.setCharacterEncoding("UTF-8");
// ========= GET请求 ======== // 得到请求类型 String method = request.getMethod(); // 判断是否是GET请求 if ("GET".equalsIgnoreCase(method)) { // 得到服务器的版本信息 String serverInfo = request.getServletContext().getServerInfo(); // 通过截取,得到具体的版本号Apache Tomcat/8.0.45 Apache Tomcat/7.0.79 String versionStr = serverInfo.substring(serverInfo.indexOf("/")+1,serverInfo.indexOf(".")); // System.out.println(versionStr); // 判断服务器的版本是否是Tomcat7以下版本 if (versionStr != null && Integer.parseInt(versionStr) < 8) { // GET放行 放行的是做好乱码处理的request对象 HttpServletRequest myRequest = new MyWapper(request); chain.doFilter(myRequest, response); return; } } // POST请求放行 chain.doFilter(request, response); return; } /** * 处理Tomcat7及以下的GET请求 * 1、定义内部类 * 2、继承HhttpServletRequestWapper包装类 * 3、重写HttpServletRequestWrapper的父类ServletRequestWrapper的getParameter()方法 * 注:自定义类继承了HttpServletRequest接口,所以MyWapper类的本质就是request */ class MyWapper extends HttpServletRequestWrapper { // 定义HttpServletRequest对象,用来提升带参构造器中的request private HttpServletRequest request; public MyWapper(HttpServletRequest request) { super(request); this.request = request; // 提升作用域 } /*处理乱码 */ @Override public String getParameter(String name) { // 得到请求的参数值 String value = request.getParameter(name); try { // 判断参数不为空,则做乱码处理 if (value != null && !"".equals(value)) { // 处理乱码问题 value = new String(value.getBytes("ISO-8859-1"),"UTF-8"); } } catch (Exception e) { e.printStackTrace(); } return value; } } |
4 拦截非法访问过滤器
用于控制用户在登录后才能访问特定页面
基于session中的参数进行判断
需要指定特定放行内容
1、指定页面(无需登录即可访问的页面,比如登录页面、注册页面等)
2、指定资源(静态资源;控制statics目录下的资源放行)
注:通常代用的css,js,image等均存放在statics
3、指定操作(无需用户登录即可执行的操作;比如登录曹组、注册操作等)
4、登录状态(session作用域中是否存在指定对象)
若以上内容均不符合则跳转回登录页面
// 基于Http HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 得到请求路径 String path = request.getRequestURI(); // 站点名+资源名 // 放行指定页面 (不需要用户登录即可访问页面 登录页面等) if (path.contains("/login.html")) { chain.doFilter(request, response); return; } // 放行静态资源 statics目录下的资源 (js、css、images等) if (path.contains("/statics")) { chain.doFilter(request, response); return; } // 放行操作放行 (不需要用户登录之后才能执行操作 登录操作、注册操作等) if (path.contains("/s01")) { chain.doFilter(request, response); return; } // 获取session对象,判断用户是否登录 String str = (String) request.getSession().getAttribute("user"); if (str != null) { chain.doFilter(request, response); return; } // 拦截跳转到登录页面 response.sendRedirect("login.html"); |
监听器
用于对ServletContext,HttpSession,ServletRequest三大域对象进行监听
1监听对象生命周期:分别实现接口
ServletRequestListener、HttpSessionListener 、 ServletContextListener
2 监听对象的存储数据的变化,分别实现接口
ServletRequestAttributeListener
HttpSessionAttributeListener
ServletContextAttributeListener
3 session事件监听,分别实现接口
HttpSessionBindingListener session绑定对象和解除绑定
HttpSessionActivationListener 监听session对象被活化和被钝化
例子:在线人数监听
//后台监听计数 public class OnlineListener implements HttpSessionListener { private Integer onlineNumber = 0; // 默认人数 // 创建 public void sessionCreated(HttpSessionEvent se) { // 人数加1 onlineNumber++; // 将在线人数存到作用域中 se.getSession().getServletContext().setAttribute("onlineNumber", onlineNumber); } // 销毁 public void sessionDestroyed(HttpSessionEvent se) { // 人数减1 onlineNumber--; // 将在线人数存到作用域中 se.getSession().getServletContext().setAttribute("onlineNumber",onlineNumber); } } |
//后台回传数据 public class OnlineServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 创建seesion对象 HttpSession session = request.getSession(); // 获取在线人数的数量 Integer onlineNumber = (Integer) session.getServletContext().getAttribute("onlineNumber"); // 得到当前用户的IP String ip = request.getRemoteAddr(); System.out.println("当前IP:" + ip); // 输出 // 设置响应类型及编码 response.setContentType("text/html;charset=UTF-8"); // 得到字符输出流 PrintWriter out = response.getWriter(); // 输出结果 out.write("<h2>在线人数:"+onlineNumber+"</h2><h3><a href='logout'>退出</a></h3><h4>当前IP:"+ip+"</h4>"); } } |