JavaWeb三大组件:Servlet、.Filter、Listener

Servlet

JavaWeb三大组件:Servlet、.Filter、Listener;

Servlet是 Java提供的一门 动态web资源开发技术。

Servlet是javaEE规范之一,也就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。

Servlet可以接收客户端发过来的请求,并响应数据给客户端;

public interface Servlet

使用servlet:

  1. 创建Web项目,导入Servlet依赖坐标
   	<dependencies>
       <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api </artifactId>
            <version>3.1.0</version>
        	<scope>provided</scope>			<!-- Tomcat有servlet的jar包,所以这里的servlet不要带到运行环境去,因此使用provided;-->
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
  	</dependencies>
  1. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法。

    public class ServletDemo1 implements Servlet{
    	public void service(){}
    	....
    }
    
  2. 配置:在类上使用@WebServlet注解,配置该Servlet的访问路径

    @WebServlet("/demo1")
    public class ServletDemo1 implements Servlet{}
    
  3. 访问:启动Tomcat,浏览器输入URL访问该Servlet

    http://localhost:8080/web-demo/demo1
    

执行流程

image-20220228110919940


生命周期

Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:

  1. 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象

  2. 初始化:在Servlet实例化之后,容器将调用Servlet的 init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

    可以在注解中修改init()调用的时机:

    @WebServlet(urlPatterns="/demo",loadOnStartup=1)
    //负整数:第一次被访问时创建 Servlet对象
    //0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
    
  3. 请求处理/服务:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。

  4. 服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收


Servlet体系结构

image-20220228113253739

开发B/S架构的web项目,都是针对HTTP协议,所以自定义的Servlet都是继承HttpServlet。

@WebServlet("/demo1")
public class ServletDemo1 extends HttpServlet{
    @Override
    protected void doGet((HttpServletRequest req,HttpServletResponse resp){
		//TOOD Get 请求方式处理逻辑
    }
	@override
	protected void doPost(HttpServletRequest req,HttpservletResponse resp){
	//TOOD Post 清求方式处理逻辑
    }
}

ServletConfig类

ServletConfig类是Servlet程序的配置信息类。

  • Servlet程序和ServletConfig对象都是由Tomcat负责创建;
  • Servlet程序默认第一次访问时创建,而每个Servlet程序创建时都会创建一个对应的ServletConfig对象。

方法:

  • getServletName() —— 获取Servlet程序的别名 servlet-name 的值
  • getInitParameter(" ") —— 获取初始化参数 init-param (括号里写param-name的值,得到param-value值)
  • getServletContext() —— 获取ServletContext对象

注: 如果重写了HttpServlet类的init方法,一定要调用父类的init(ServletConfig),因为HttpServlet类的init方法里,保存了ServletConfig对象,不然的话,调用getInitParameter(" ")方法会报错。

web.xml配置:设置servlet程序的别名,访问路径

<!-- servlet 标签给 Tomcat 配置 Servlet 程序 -->
<servlet>
	<!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) -->
	<servlet-name>HelloServlet</servlet-name>
	<!--servlet-class 是 Servlet 程序的全类名-->
	<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
	<!--init-param 是初始化参数-->
	<init-param>
		<!--是参数名-->
		<param-name>username</param-name>
		<!--是参数值-->
		<param-value>root</param-value>
	</init-param>
	<!--init-param 是初始化参数-->
	<init-param>
		<!--是参数名-->
		<param-name>url</param-name>
		<!--是参数值-->
		<param-value>jdbc:mysql://localhost:3306/test</param-value>
	</init-param>
</servlet>

<!--servlet-mapping 标签给 servlet 程序配置访问地址-->
<servlet-mapping>
	<!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个 Servlet 程序使用-->
	<servlet-name>HelloServlet</servlet-name>
<!--
	url-pattern 标签配置访问地址 <br/>
		/ 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径 <br/>
		/hello 表示地址为:http://ip:port/工程路径/hello <br/>
-->
	<url-pattern>/hello</url-pattern>
</servlet-mapping>

ServletContext

  • ServletContext是一个接口,它表示Servlet上下文对象
  • 一个 web工程中只有一个 ServletContext 对象实例
  • ServletContext 对象是一个域对象
  • ServletContext 是在 web工程部署启动的时候创建。在 web工程停止的时候销毁;

域对象: 是可以像Map一样存取数据的对象,这里的域指存取数据的操作范围,即整个web工程;

//获取ServletContext对象
ServletContext context = getServletConfig().getServletContext();
//直接get也可以,本质上也是调用getServletConfig().getServletContext();
ServletContext context = getServletContext();

方法:

  • getInitParameter(“…”) —— 获取 web.xml 中配置的上下文参数 context-param (括号里写param-name值,得到param-value值)

  • getContextPath() —— 获取当前的工程路径,格式: /工程路径

  • getRealPath(“/”) —— 获取工程部署后在服务器硬盘上的绝对路径

    getRealPath(“/”) —— 工程部署的路径

    getRealPath(“/css”) —— 工程下 css 目录的绝对路径

  • 像 Map 一样存取数

    存数据取数据删除数据
    Mapput()get()remove()
    域对象setAttribute()getAttribute()removeAttribute()
<!-- web.xml中相关配置信息  -->
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
	<param-name>username</param-name>
	<param-value>context</param-value>
</context-param>
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
	<param-name>password</param-name>
	<param-value>root</param-value>
</context-param>

HTTP协议

HTTP协议是 客户端和服务器之间通信时要发送的数据,需要遵守的规则; HTTP 协议中的数据又叫报文。

  • 请求 Request:客户端给服务器发送数据。
    • GET请求
    • POST请求
  • 响应 Response:服务器给客户端回传数据。

GET请求的组成:

  • 请求行: 请求方式 请求的资源路径 请求的协议版本号

    如: GET /servlet_1/a.html HTTP/1.1

  • 请求头:以键值对的形式组成

    • Accept: 告诉服务器,客户端可以接收的数据类型;
    • Accept-Language:告诉服务器,客户端可以接收的语言类型,如:zh_CN指中文中国,en_US指英文美国;
    • User-Agent:就是浏览器的信息;
    • Accept-Encoding:告诉服务器,客户端可以接收的数据编码(压缩)格式
    • Host:表示请求的股务器ip和端口号
    • Connection:告诉服务器诗求连接如何处理
      • Keep-Alive :告诉服务器回传数据不要马上关闭,保持一小段时间的连接;
      • Closed:马上关闭

POST请求的组成:

  • 请求行: 请求方式 请求的资源路径 请求的协议版本号

  • 请求头:

    • Accept:表示客户端可以接收的数据类型;

    • Accept-Language:表示客户端可以接收的语言类型;

    • Referer:表示请求发起时,浏览器地址栏中的地址(从哪来)

    • User-Agent:表示浏览器的信息

    • Content-Type:表示发送的数据的类型

      如:application/x-www-form-ur lencoded : 表示提交的数据格式是 name=value&name=value,然后对其进行urI编码,使非英文内容转换为:%xx%xx

      multipart/form-data :表示以多段的形式提交数据给服务器 (以流的形式提交,用于上传)

    • Content-Lnegth:表示发送的数据的长度

    • Cache-Control:表示如何控制缓存, no-cache 指不缓存

  • 空行 (请求头和请求体之间隔一空行)

  • 请求体:发给服务器的数据

区分GET请求和POST请求:

POST请求有:

  • form 标签中 method=post

GET请求有:

  • form 标签 method=get
  • a标签
  • link标签引入css
  • Script标签引入js文件
  • img标签引入图片
  • iframe 引入html页面
  • 在浏览器地址栏中输入地址后敲回车

响应 的组成:

  • 响应行:响应的协议和版本号 状态码 状态描述符
  • 响应头:以键值对形式组成
    • Server:表示服务器的信息;
    • Content-Type:表示响应体的数据类型;
    • Content-Length:响应体的长度;
    • Date:请求响应的时间(格林时间);
  • 空行
  • 响应体:(就是回传给客户端的数据)

常用响应码:

  • 200 —— 请求成功
  • 302 —— 请求重定向
  • 404 —— 表示请求服务器已收到,但所要的数据不存在/请求地址错误
  • 500 —— 表示服务器已经收到请求,但服务器内部错误(错误代码)

MIME类型

MIME类型 指的是HTTP协议中的数据类型 —— Multipurpose Internet Mail Extensions 多功能Internet邮件扩充服务。

格式:大类型/小类型

常见的MIME类型:

文件后缀MIME类型
超文本标记语言文本.html .htmtext/html
普通文本.txttext/plain
RTF文本.rtfapplication/rtf
GIF图形.gifimage/gif
JPEG图形.jpeg .jpgimage/jpeg
au声音文件.auaudio/basic
MIDI音乐文件.mid .midiaudio/midi, audio/x-midi
RealAudio音乐文件.ra .ramaudio/x-pn-realaudio
AVI文件.avividio/mpeg
GZIP文件.gzvideo/x-msvideo
TAR文件.tarapplication/x-gzip
MPEG文件vapplication/x-tar

HttpServletRequest类

每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用。

而通过 HttpServletRequest 对象,可以获取到所有 请求 的信息。

方法:

  • getRequestURI() 获取请求的资源路径
  • getRequestURL() 获取请求的统一资源定位符(绝对路径)
  • getRemoteHost() 获取客户端的ip地址
  • getHeader() 获取请求头
  • getParameter() 获取请求的参数
  • getParameterValues() 获取请求的参数(多个值的时候使用)
  • getMethod() 获取请求的方式GET或POST
  • setAttribute(key,value) 设置域数据
  • getAttribute(key) 获取域数据
  • getRequestDispatcher() 获取请求转发对象

如果doPost中获取数据出现中文乱码,可以设置请求体的字符集为UTF-8:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	req.setCharacterEncoding("UTF-8");	//设置字符集要写在获取请求参数之前,否则不生效
}

HttpServletResponse类

HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。

HttpServletRequest表示请求过来的信息,HttpServletResponse 表示所有响应的信息,;我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse对象来进行设置。

两个输出流:

  • 字节流 getOutputStream() —— 常用于下载(传递二进制数据)
  • 字符流 getWriter() —— 常用于回传字符串(常用)

两个流同时只能使用一个。

public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //resp.setContentType("text/html; charset=UTF-8");  用于解决响应中文乱码:它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头;注:要在获取流对象之前使用才有效;    
    // 要求: 往客户端回传 字符串 数据。
    PrintWriter writer = resp.getWriter();
    writer.write("response's content!!!");
    }
}

请求重定向

是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问,叫请求 重定向。(因为之前的地址可能已经被废弃)

response.sendRedirect("新地址");

请求转发/内部转发:

意思是:服务器收到请求后,从一个资源跳转到另一个资源。即服务器内部转发

request.getRequestDispatcher("demo07").forward(request,response);

image-20220329114857941

//办事处1 —— Servlet1程序
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
	// 获取请求的参数(办事的材料)查看
	String username = req.getParameter("username");
	System.out.println("在 Servlet1(柜台 1)中查看参数(材料):" + username);
    
	// 给材料 盖一个章,并传递到 Servlet2(柜台 2)去查看
	req.setAttribute("key1","柜台 1 的章");
    
    // 问路:Servlet2(柜台 2)怎么走
    // 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到 IDEA 代码的 web 目录
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
    // RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");
    
    // 走向 Sevlet2(柜台 2)
    requestDispatcher.forward(req,resp);
}

//办事处2 —— Servlet2程序
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
    // 获取请求的参数(办事的材料)查看
    String username = req.getParameter("username");
    System.out.println("在 Servlet2(柜台 2)中查看参数(材料):" + username);
    
    // 查看 柜台 1 是否有盖章
    Object key1 = req.getAttribute("key1");
    System.out.println("柜台 1 是否有章:" + key1);
    
    // 处理自己的业务
    System.out.println("Servlet2 处理自己的业务 ");
}

保存作用域

作用域一般有四个:

  • page(页面级别,现在几乎不用)

  • request(一次请求响应范围)

    重定向中,客户端实际发起了两次请求;所以在第一次请求中在request的作用域中保存数据,数据不会保存到第二次请求。

    //在 /Servlet_1 中
    req.setAttribute("key","value");
    req.sendRedirect("/Servlet_2");
    //在 /Servlet_2 中
    System.out.println(req.getAttribute("key"));	//打印null,不能得到结果
    
  • session(一次会话范围)

    //在 /Servlet_1 中
    req.getSession().setAttribute("key","value");
    req.sendRedirect("/Servlet_2");
    //在 /Servlet_2 中
    System.out.println(req.getAttribute("key"));	//能得到结果
    
  • application(整个应用程序范围)

    //这里假设/Servlet_1和/Servlet_2是两个不同的用户
    //在 /Servlet_1 中
    ServletContext application = req.getServletContext();
    application.setAttribute("key","value");
    req.sendRedirect("/Servlet_2");
    //在 /Servlet_2 中
    ServletContext application = req.getServletContext();
    System.out.println(application.getAttribute("key"));	//能得到结果
    

文件传输

文件上传:

<form action="url地址" enctype="multipart/form-data" method="提交方式" name="名称">
    
<!-- 如果要设置上传文件,需要加上 enctype="multipart/form-data" ,然后在 input的属性type值为"file" -->

multipart/form-data表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器
查看http协议内容时,context-type部分有属性boundary:表示每段数据的分隔符,分隔符是由浏览器每次都随机生成,它就是每段上传数据的分界符。

文件接收:

<!-- 上传文件的表单 -->
<form action="http://192.168.31.74:8080/09_EL_JSTL/uploadServlet" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username" /> <br>
    头像:<input type="file" name="photo" > <br>
    <input type="submit" value="上传">
</form>
//fileupload类库的适用:
//需要导入两个jar包:commons-fileupload.jar 和 commons-io.jar
//解析上传的数据
public class Servlet_1 extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
        //1 先判断上传的数据是否多段数据(只有是多段的数据,才是文件上传的)
        if (ServletFileUpload.isMultipartContent(req)) {
        // 创建 FileItemFactory 工厂实现类
        FileItemFactory fileItemFactory = new DiskFileItemFactory();
        // 创建用于解析上传数据的工具类 ServletFileUpload 类
        ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
        try {
            // 解析上传的数据,得到每一个表单项 FileItem
            List<FileItem> list = servletFileUpload.parseRequest(req);
            // 循环判断,每一个表单项,是普通类型,还是上传的文件
            for (FileItem fileItem : list) {
                if (fileItem.isFormField()) {
                    // 普通表单项
                    System.out.println("表单项的 name 属性值:" + fileItem.getFieldName());
                    // 参数 UTF-8.解决乱码问题
                    System.out.println("表单项的 value 属性值:" + fileItem.getString("UTF-8"));
                } else {
                    // 上传的文件
                    System.out.println("表单项的 name 属性值:" + fileItem.getFieldName());
                    System.out.println("上传的文件名:" + fileItem.getName());
                    fileItem.write(new File("e:\\" + fileItem.getName()));
                }
            }
        } catch (Exception e) {
        	e.printStackTrace();
        }
    }
}

文件下载:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 获取要下载的文件名
        String downloadFileName = "2.jpg";
        //2. 获取要下载的文件内容(通过ServletContext对象可以获取)
        ServletContext servletContext = getServletContext();
        //获取要下载的文件类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        //4.在回传前,通过响应头告诉客户端返回的数据类型
        response.setContentType(mimeType);
        //5.告诉客户端收到的数据是用于下载的,还是适用响应头的
        response.setHeader("Content-Disposition","attachment;filename=文件名");
        //输入流获取文件内容
        InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
        //获取响应的输出流
        OutputStream outputStream = response.getOutputStream();
        //读取输入流中全部数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream, outputStream);
}

Filter

Filter表示过滤器,可以把对资源的请求拦截下来;

通常用过滤器完成一些通用的操作,比如:权限控制、统一编码处理、敏感字符处理等等…

JavaWeb三大组件:Servlet、.Filter、Listener;

使用:实现Filter接口 ,并重写三个方法;注意是javax.servlet. 下的Filter接口。

@WebFilter("/*")       //设置拦截路径, “/*” 指拦截全部
public class Filter_1 implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         // 放行前逻辑(已被拦截)
        filterChain.doFilter(servletRequest, servletResponse);     //放行
        // 放行后逻辑
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化
    }

    @Override
    public void destroy() {
        // 销毁
    }
}

Filter执行流程:

执行放行前逻辑——放行——访问资源——执行放行后逻辑


Filter拦截路径配置

@WebFilter("...")   //括号中设置拦截路径
  • 拦截具体的资源: /index.jsp 只有访问index.jsp时才会被拦截;
  • 目录拦截:/user/* 访问/user下的所有资源都会被拦截;
  • 后缀名拦截: *.jsp 访问后缀名为jsp的资源都会被拦截;
  • 拦截所有: /*

如果要拦截多个页面或分散文件,要在括号例写urlPatterns属性,然后在里面写属性的值,逗号分割;

@WebFilter(urlPatterns = {"...","...","..."})  

过滤器链

一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链。

例如:对同一应用,如果执行了2个过滤器,执行顺序为:Filter1的放行前逻辑,Filter1放行,Filter2放行前逻辑,Filter2放行,Filter2放行后逻辑,Filter1放行后逻辑。(类似递归)

过滤器的执行顺序按 过滤器的类名的字典序排序;

FilterConfig类

Filter过滤器的配置文件类

filterConfig.getFilterName()  //获取过滤器的名称
filterConfig.getInitParameter("")   //获取过滤器中配置的初始化参数 

Listener

监听器,是在application,session,request三个对象创建、销毁或者往其中添加修改删属性时自动执行代码的功能组件。

Listener分类:JavaWeb中提供了8个监听器

监听器分类监听器名称作用
ServletContext监听ServletContextListener用于对ServletContext对象进行监听(仓创建、销毁)
ServletContextAttributeListener对ServletContext对象中属性的监听(增别改属性)
Session监听HttpSessionListener对Session对象的整体状态的监听(创建、销毁)
HttpSessionAttributeListener对Session?对象中的属性监听(增删改属性)
HttpSessionBindingListener监听对象于Sessionl的绑定和解除
HttpSessionActivationListener对Session数据的钝化和活化的监听
Request监听ServletRequestListener对Requestx对象进行监听(创建、销毁)
ServletRequestAttributeListener对Reque5t对象中属性的监听(增别改属性)

使用

实现ServletContextListener接口,并重写两个方法;

@WebListener
class a implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent sce) {
      //加载资源
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //释放资源
    }
}

会话

会话:用户打开浏览器,访问wb服务器的资源,会话建立,直到有一方断开连接, 会话结束(浏览器关闭)。在一次会话中可以包含多次请求和响应

会话跟踪:服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据

由于HTTP协议是无状态的,每次浏览器发出请求,服务器都会将请求视为新的请求,所以需要会话跟踪技术。

  • 客户端会话跟踪技术:Cookie
  • 服务端会话跟踪技术:Session

cookie

客户端会话技术,将数据保存到客户端,以后客户端每次请求都携带Cookie数据进行访问。

客户端第一次向服务端发送请求,服务器会生成一个cookie对象,和响应一起发给客户端;客户端之后向服务端发送请求时,会携带cookie一起发送,服务端识别cookie就会知道客户端的身份。

使用:

//发送:
//创建Cookie对象,设置数据
Cookie cookie = new Cookie("key","value");

//发送Cookie到客户端,使用response对象
response.addCookie(cookie);

//获取:
//获取客户端所有Cookie,使用request对象
Cookie[] cookies = request.getCookies();
//遍历数组,获取每一个Cookie对象
//使用Cookie对象方法获取数据
for (Cookie cookie : cookies){
	String name = cookie.getName();
	if("key".equals(name)){
		String value = cookie.getValue();
		break;
    }
}

//修改Cookie的值
//方法一:创建一个同名的Cookie对象,直接覆盖
Cookie cookie = new Cookie("key","newValue");
resp.addCookie(cookie);
//方法二:找到对应的Cookie对象,用setValue()修改
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
if (cookie != null) {
    cookie.setValue("newValue2");
    resp.addCookie(cookie);	//修改后还要通知客户端保存修改
}

原理:

Cookie的实现是基于HTTP协议的;
响应头:set-cookie
请求头:cookie

注:

Cookie存活时间:

  • 默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁。

  • setMaxAge(int seconds) :设置Cookie存活时间

    • 正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储;到时间自动删除。

    • 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁;

    • 零:删除对应Cookie;

Cookie存储中文:

  • 默认情况不能存储中文;如果要存中文,则需要进行转码:可用URL编码

session

服务端会话跟踪技术:将数据保存到服务端;

JavaEE提供HttpSession接口,来实现一次会话的多次请求之间的 数据共享功能。

使用:

//获取Session对象
HttpSession session = request.getSession();
//Session对象功能:
void setAttribute(String name,Object o) //存储数据到session域中
Object getAttribute(String name) //根据key,获取值
void removeAttribute(String name) //根据key,删除该键值对
boolean isNew() //判断是不是刚创建的

原理:

Session技术,底层是基于Cookie技术实现的。

如果客户端发送的请求没有携带cookie,则服务端会新创建一个session和cookie,cookie的key值session的id值相同,然后session保存在服务端,cookie返回给客户端。

如果客户端发送的请求携带了cookie,则服务端会通过cookie的key值找到对应保存的session,然后返回相应的cookie。

注意事项

Session 钝化、活化:

  • 钝化:在服务器正常关闭后,Tomcats会自动将Session数据写入硬盘的文件中;
  • 活化:再次启动服务器后,从文件中加载数据到Session中;

Session销毁:

  • 默认30分钟无操作,销毁;

    <!-- 在web.xml中配置所有session的超时时长 -->
    <session-config>
    	<session-timeout>30</session-timeout>
    </session-config>
    
    //也可以使用session的方法设置单个
    void setMaxInactiveInterval(int interval) //设置session的超时时间,单位为秒,设置负数表示永不超时
    int getMaxInactiveInterval()  //获取超时间
    void invalidate()	//立即超时,销毁
    

Cookie和Session异同点:

Cookie和Session都是来完成一次会话内多次请求间数据共享的;
区别:

  • 存储位置:Cookie是将数据存储在客户端,Session将数据存储在服务端;
  • 安全性:Cookie不安全,Session安全;
  • 数据大小:Cookie最大KB,Session无大小限制;
  • 存储时间:Cookie可以长期存储,Session默认30分钟;
  • 服务器性能:Cookie不占服务器资源,Session占用服务器资源;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值