章节:
(一)Session对象 (重点)
1.1Session的概述
Session用于记录用户的状态。Session指的是在一段时间内,单个客户端与WEb服务器的一连串相关交互的过程
在Session中,客户可能会多次请求访问同一个资源,也有可能请求访问各种不同的服务器资源
1.2Session原理
服务器会为每一次会话分配一个Session对象
同一个浏览器发起的多次请求,属于同一次会话(Session)
首次使用Session时,服务器会自动创建Session,并创建Cookie存储SessionId发送回客户端
需要注意的是Session是由服务器创建的
1.3Session的使用
Session作用域:拥有 存储数据的空间,作用范围是一次会话有效
一次会话时使用同一浏览器发送的多次请求。一旦浏览器关闭,则表示会话结束
可以将数据存进Session中,在绘画的任意位置进行获取
可传递任何类型的数据(基本类型数据,对象,集合,数组)
1.3.1获取Session
session是由服务器端自动创建的,通过request对象获取
//获取Session对象
HttpSession session = request.getSession();
System.out.println("Id:" +session.getId()); //唯一标记
1.3.2Session保存数据
setAttribute(属性名 , Object); //保存数据到Session中
Session.setAttribute("key" , value); //以键值对形式存储到session作用域中
//在session中存储数据
session.setAttribute("username" ,"taotao");
1.3.3Session获取数据
getAttribute("key"); 获取session中的数据
session.getAttribute("key"); //通过String类型的key访问Object类型的value
//将从Session获取的Object类型的Session数据做一个强转,转成String类型
String s = (String) session.getAttribute("username");
System.out.println("这是我从Session中获取的username:"+ s );
1.3.4session移除数据
removeAttribute(属性名); //从session中删除数据
session.removeAttribute("key"); //通过键移除session作用域中的值
System.out.println("这是我要移除的"+session.getAttribute("username"));
//移除session中的username的数据
session.removeAttribute("username");
2.1Session与Request应用区别
request是一次请求有效,请求改变,则request改变
session是一次绘画有效,浏览器改变,则session改变
2.1.1Session 应用
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(name = "SessionServlet" ,value = "/ss")
public class SessionServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过request中获取session对象
HttpSession session = request.getSession();
//在session中存储数据
session.setAttribute("username" ,"taotao");
//在Session中存入一个数据,通过重定向,看看是否在其他页面中是否拿得到拿不到值
request.setAttribute("password" , "root");
//重定向路径
response.sendRedirect("/Session/getss");
System.out.println(session.getId());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
2.1.2 getss
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(name = "getSessionServlet" ,value = "/getss")
public class getSessionServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过request获取Session对象
HttpSession session = request.getSession();
//将从Session获取的Object类型的Session数据做一个强转,转成String类型
String s = (String) session.getAttribute("username");
String string=(String) request.getAttribute("password");
System.out.println("这是我从Session中获取的username:"+ s );
//通过重定向过来的 里边是没有值的 所以request是null 重定向是客户端发送里两次请求
System.out.println("这是我从Request中获取的password:"+ string );
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request ,response);
}
}
3.1Session的生命周期
开始:第一次使用到Session的请求产生,则创建Session
结束:
浏览器关闭,失效
Session超时,失效
session.setMaxInactiveInterval(60*60);//设置最大有效时间(单位:秒)
手工销毁,失效
session.invalidate(); //退出登录或者注销
3.1.2Session失效
//设置session最大有效时间
session.setMaxInactiveInterval(60*60);
//手工销毁
session.invalidate();
4.1浏览器禁用Cookie解决方案
4.1.1浏览器禁用Cookie的后果
服务器在默认情况下,会使用Cookie的方式将SessionID发送给浏览器,如果用户禁用Cookie,那么SessionID就不会被浏览器保存,这种情况下,服务器还可以使用URL重写这样的方式来发送SessionID
4.1.2URL重写
浏览器在访问服务器上的某个地址时,不再使用原来的那个地址,而是使用经过改写的(即原来的地址后面加上了sessionID)
4.1.3实现URL重写
//通过request获得session对象
HttpSession session = request.getSession();
//生成重写的URL
String newUrl = response.encodeRedirectURL("/Session/getslife"); System.out.println(newUrl); //通过response进行重定向
response.sendRedirect(newUrl);
5.1Session实战权限认证
6.1 ServletContext对象(重点)
6.1.1ServletContext概述
全局对象,也拥有作用域,对应一个tomcat中的Web应用
当Web服务器启动时,会为每一个Web应用程序创建一块共享的存储区域(ServletContext)。
ServletContext在Web服务器启动时创建,服务器关闭时销毁。
6.1.2获取ServletContext对象
GenericServlet提供了getServletContext()方法。(推荐) this.getServletContext();
HttpServletRequest提供了getServletContext()方法。(推荐)
HttpSession提供了getServletContext()方法。
6.2ServletContext作用
6.2.1获取项目真实路径
获取当前项目在服务器发布的真实路径
String realpath=servletContext.getRealPath(" / ");
6.2.2获取上下文路径
获取上下文的路径(指的是项目的名称或应用程序名称)
System.out.println(servletContext.getContextPath());
//输出上下文路径
System.out.println(req.getContextPath());
6.2.3全局容器
ServletContext拥有作用域,可以存储数据到全局容器中
存储数据:servletContext.setAttribute("name" , value);
获取数据:servletContext.getAttribute("name" , value);
移除数据:servletContext.removeAttribute("name" , value);
6.3ServletContext应用场景
package com.tao.counter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(value = "/counter")
public class CounterController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//编码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取一个ServletContext全局对象,统计当前项目的被访问次数
ServletContext servletContext = req.getServletContext();
//获取一个计数器
Integer counter = (Integer) servletContext.getAttribute("counter");
//如果为空 就开始加一
if (counter==null){
counter =1;
servletContext.setAttribute("counter",counter);
}else { //如果不为空,就++
counter++;
servletContext.setAttribute("counter",counter);
}
PrintWriter unt = resp.getWriter();
unt.write("项目servlet共访问次数:"+counter);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
6.4作用域总结
HttpServletRequest:一次请求,请求响应之前有效
HttpSession:一次会话开始,直到浏览器关闭或者session超时才会失效
ServletContext:服务器启动开始(启动tomcat),服务器停止之前有效(关闭tomcat)
7 过滤器(重点)
7.1现有问题
在以往的Servlet中,有没有冗余的代码,多个Servlet都要进行编写。
7.2 概念
过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。
7.3过滤器作用
执行地位在Servlet之前,客户端发送请求时,会先经过Filter,在达到目标Servlet中;响应时,会根据执行流程再次反向执行Filter
可以解决多个Servlet共性代码的冗余问题:比如:乱码现象,登陆验证
7.4编写过滤器
Servlet API中提供了一个Filter接口,开发人员编写了一个Java类实现了这个接口,这个Java类称之为过滤器(Filter)
7.4.1 实现过程
编写Java实现Filter接口
在doFilter方法中编写拦截逻辑
设置拦截路径 @WebFilter("/bl") 就是你要访问的资源路径,只不过要先拦截,在放行
package com.tao.web.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/bl") //配置过滤器路径 public class MyFilter implements Filter { //初始化过滤器路径 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("过滤器初始化了-------init----:"+filterConfig); } //执行过滤 @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("过滤前-----doFilter "); //放行,让请求继续 filterChain.doFilter(servletRequest, servletResponse); System.out.println("过滤后----doFilter"); } //销毁 @Override public void destroy() { System.out.println("销毁了----------destroy"); } }
7.5 过滤器配置
7.5.1 xml配置
<!-- 过滤器的xml配置--> <filter> <!--名称--> <filter-name>xml</filter-name> <!-- 过滤器类全称--> <filter-class>com.tao.web.filter.FiterXml</filter-class> </filter> <!--映射路径配置--> <filter-mapping> <!--名称--> <filter-name>xml</filter-name>
<!--过滤的url匹配规则和Servlet类似 拦截/test--> <url-pattern>/test</url-pattern> </filter-mapping>
7.5.2 过滤器路径
过滤器的过滤路径通常有三种形式:
精确匹配过滤 , 比如/index.jsp /myservlet
后缀过滤匹配, 比如 *.jsp *.html *.jpg 等
通配符过滤匹配 /* 。表示拦截所有。注意过滤器不能使用 / 匹配
/tao/tao/* 就允许
7.6 过滤器链和优先级
7.6.1过滤器链
客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这一组过滤器就称之为就称之为一条过滤器链。
每个过滤器实现某个特定的功能,当地一个Filter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有Filter,如果有的话,就调用第二个filter,如果没有的话,就会调用目标资源。
7.6.2过滤器优先级
在一个Web应用中,可以开发编写多个Filter,这些Filter组合起来就称之为一个Filter链 。优先级:
如果为注解的话,是按照类全名称的字符串顺序决定作用顺序
如果web.xml ,按照filter-mapping注册顺序,从上往下
web.xml配置高于注解方式
如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次
8.1 过滤器典型应用
8.1.1 利用过滤器处理乱码
package com.tao.web.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter(filterName = "AllFilter" ,value = "/*") //拦截所有 public class AllFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //统一处理请求和响应乱码 req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=utf-8"); System.out.println("拦截所有请求"); chain.doFilter(req, resp); } public void init(FilterConfig config) throws ServletException { } }
8.1.2权限验证
因为过滤器中的ServletRequest 是HttpServletRequest的父类,所以客户端发送过来的请求 ServletRequest是没有办法接收到的 ,所以要向下转型
Filter权限验证
package com.tao.web.filter; import com.tao.bean.Manager; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter(value = "/showallcontroller") public class LoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //利用Filter做权限验证 //向下转型 也就是拆箱 HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; HttpSession session = request.getSession(); Manager manager = (Manager) session.getAttribute("mgr"); if (manager!=null){ //登陆过就放行 filterChain.doFilter(request , response); }else { //未进行登录操作就踢回登录页 response.sendRedirect(request.getContextPath()+"/loginMgr.html"); } } @Override public void destroy() { } }
Session权限验证
package com.tao.controller; import com.tao.bean.Manager; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.List; @WebServlet(name = "ShowAllController", value="/showallcontroller") public class ShowAllController extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过HttpSession完成权限控制 // HttpSession session = request.getSession(); // Manager mgr = (Manager) session.getAttribute("mgr"); // if (mgr!=null){ //只负责调用业务逻辑功能 AdminService adminService = new AdminServiceImp(); List<Admin> adminList = adminService.showAllAdmin(); //request作用域存储数据 request.setAttribute("admins" ,adminList); //通过转发 跳转到显示结果servlet request.getRequestDispatcher("/showall/jsp").forward(request,response); // }else { // response.sendRedirect("/WebProject/LoginMgr.html"); // } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }