Java基础_Tomcat容器实践入门

使用Tomact容器构建java项目之前 需要先了解一些http协议的知识。

HTTP

HTTP(超文本传输协议),是制定了客户端请求和服务器响应的标准的协议,用户在输入地址(http://域名:端口)后可以从服务器上取得响应信息。该协议规定了客户端发送给服务器的内容格式和服务器响应客户端的内容格式。

服务器的资源由浏览器通过地址去访问。输入的地址需要满足http协议格式。请求的格式为 ——http:// 域名:端口/资源地址?参数1&参数2#锚点

如:http://localhost:8080/server/login?username=zhangsan&psw=123

浏览器会解析该地址,并发送给服务器。当接受到服务器端的响应时,也按http协议的格式进行解析获取到的数据,最后展示。

特点
  • 支持浏览器/服务器模式 B/S
  • 简单快速——客户端向服务器发送请求,只需要传地址和请求的方法。一般来说请求方法为Get和Post。Get不安全,但是效率高,有缓存。Post相对安全,但是效率不高。通常Get是Post速率的2倍。Http协议简单使得通信效率高
  • 无连接——无连接指的是,每次连接只处理一个请求。服务器接受到客户端请求并得到客户端的应答后就关闭连接,(Http1.1版本支持持续连接,可以发送连续请求。)
  • 无状态——指的是服务器对事务处理没有记忆能力。这样使得如果要用到前面的信息,客户端必须重新发送。这样可能会导致单次接收的数据量过大,但是同样,不需要先前信息的时候,应答的速度相对就会很快。
HTTP请求

Http请求由3部分组成,分别是:请求行,请求头,请求正文(请求体)

  • get请求

     没有请求体
    
  • post请求

     有请求体 Form Data
    

统一格式

请求行
请求头1
请求头2
…
请求空行
请求体

请求行 由请求方式开头+空格+资源地址+请求协议
请求头 由名称:空格+值组成
请求空行就是换行
post请求有参数,get请求参数在资源地址后

HTTP响应

接受并分析请求后,服务器会返回一个响应信息。响应信息也由:响应行
响应头 响应体3部分组成。

状态行
响应头1
响应头2
…
响应空行
响应体
消息头

请求和响应都是由开始行,消息报头(可有无),空行,消息正文(可有无)组成,并且每个消息报头域中的报头都是由 键值对形式组成键: 值 中间有空格。大小写无关。

请求头
请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。

Referer头:指明请求从哪里来。
		如果是直接从地址栏输入的,都没有该报头,或者该报头是自身地址,如果是超链接跳转
		过来的,可以看到并且后面的值 为该请求从哪里发出。
			可以用作百度竞价
			防盗链:判断d网页的referer值是不是c。c判断referer值是不是b 一层层往上。
			邀请好友:是否是通过该用户的页面过来的

响应头
响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对 Request-URI 所标识的资源进行下一步访问的信息。

  • Location:location报头用于重定向接收者到另一个位置。经常用在域名更换时候。

     response.sendRedirect("http://www.baidu.com");//重定向。可以跳转到任何地方。
     		相对地址时跳转当前web项目下的资源。如果前面加/ 默认加上当前域名地址。
     		绝对地址时:跳转该地址 
     resp.addHeader("Location"," http://www.baidu.com");//这种加报头的方式不行,因为
     location报头只是一种标识,不具备跳转效果。
    
  • Refresh :自动跳转(单位是秒)通过html标签的<meta‘>实现

     <meta http-equiv="refresh" content="3;url=http://www.baidu.com">
     服务端也可以实现
     resp.setContentType("text/html");
     resp.getWriter().println("<meta http-equiv='refresh'  content='1;url=http://www.baidu.com'>");
    

Tomcat

Tomcat 是一个符合 JavaEE WEB标准的最小的 WEB容器,所有的 JSP 程序一定要有 WEB容器的支持才能运行,而且在给定的 WEB 容器里面都会支持事务处理操作

Tomcat 是由 Apache 提供的(www.apache.org)提供的可以用安装版和解压版,安装版可以在服务中出现一个 Tomcat 的服务,免安装没有,开发中使用免安装版。 Tomcat 简单的说就是一个运行 Java 的网络服务器,底层是 Socket 的一个程序,它也是 JSP 和 Servlet 的一个容器。 Tomcat 是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun和其他一些公司及个人共同开发而成。

Tomcat 技术先进、性能稳定,而且免费,因而深受 Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的 Web 应用服务器

Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器, 在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选。 对于一个初学者来说,可以这样认为,当在一台机器上配置好 Apache 服务器,可利用它响应 HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上 Tomcat 部分是 Apache 服务器的扩展,但它是独立运行的,所以当你运行 tomcat 时,它实际上作为一个与 Apache 独立的进程单独运行的。

当配置正确时,Apache 为 HTML 页面服务,而 Tomcat 实际上是在运行 JSP 页面和 Servlet。另外,Tomcat 和 IIS 等 Web 服务器一样,具有处理 HTML 页面的功能,另外它还是 一个 Servlet 和 JSP 容器,独立的 Servlet 容器是 Tomcat 的默认模式。不过,Tomcat 处理静态 HTML 的能力不如 Apache 服务器。目前 Tomcat 最新版本为 9.0。

安装Tomcat
运行 Tomcat 需要 JDK 的支持【Tomcat 会通过 JAVA_HOME找到所需要的 JDK】

安装就是解压缩过程。启动 Tomcat,能访问则算安装好了

Tomcat目录结构
  • bin:启动和关闭 tomcat 的 bat 文件

  • conf:配置文件server.xml 该文件用于配置 server 相关的信息

     tomact的端口号,配置主机,web.xml文件配置
     tomcat-user.xml 配置用户名密码和相关权限
    
  • lib:该目录放置运行 tomcat 运行需要的 jar 包

  • logs:存放日志。

  • webapps:存放web应用

  • work 工作目录:存放jsp资源,和对应生成的文件

Servlet

servlet 是server和applet的缩写。意思是服务器脚本。使用java程序编写的服务器端程序。可以像生成动态的 WEB页面。Servlet主要运行在服务器端,由服务器调用执行。是按照servlet标准来开发的类。要实现 web 开发,需要实现 Servlet 标准

Servlet 本质上也是 Java 类,但要遵循 Servlet 规范进行编写,没有 main()方法,他的创建和销毁都是由Servlet容器管理(即tomcat) 。自动调用,并且在服务器启动的时候就加载各个Servlet类。使用到的时候实例化对应类。

Servlet 是和 HTTP 协议是紧密联系的,其可以处理 HTTP 协议相关的所有内容。这也是 Servlet 应用广泛的原因之一。

提供了 Servlet 功能的服务器,叫做 Servlet 容器,其常见容器有很多,如 Tomcat, Jetty, WebLogic Server, WebSphere, JBoss 等等。

Servlet的实现
  • 创建类,实现http规范

即继承HttpServlet类。该类中已经完成了通信的规则,我们只需要进行业务的实现即可。
-public class servlet01 extends HttpServlet {}

  • 重写Service方法

满足 Servlet 规范只是让我们的类能够满足接收请求的要求,接受到请求后还需要进行分析和响应。因此要重写service方法。专门用来处理请求的。

protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { 
System.out.println("Hello world!");
}
  • 设置注解

使用@WebServlet将一个继承于javax.servlet.http.HttpServlet 的类定义为Servlet组件。

在Servlet3.0中 , 可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的 Servlet。

@WebServlet("/ser01")  //该注解中有多个值。其中value代表该类在url中的访问路径。
public class Servlet01 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Hello Servlet!");
    }
}

注解中的值
可以配置多路径访问

  • String name() default “”; ——注解的名称

  • String[] value() default {}; ——配置url访问的servlet的路径

  • String[] urlPatterns() default {};——和value一样。两个中写一个就行

     @WebServlet(name="Servlet01",value="/ser01")
     @WebServlet(name="Servlet01",urlPatterns = "/ser01")
    
Servlet工作流程
  1. 通过请求头获知浏览器访问的是哪个主机
  2. 再通过请求行获取访问的是哪个一个web应用
  3. 再通过请求行中的请求路径获知访问的是哪个资源
  4. 通过获取的资源路径在配置中匹配到真实的路径,
  5. 服务器会创建servlet对象,(如果是第一次访问时,创建servlet实例,并调用init方法进行初始化操作)
  6. 调用service(request, response)方法来处理请求和响应的操作
  7. 调用service完毕后返回服务器 由服务器讲response缓冲区的数据取出,以http响应的格式发送给浏览器
Servlet 生命周期

因为Servlet没有main方法,因此不能独立运行。完全是Servlet引擎来控制的。(tomcat)

  • 实例和初始化—— init 方法,在 Servlet 实例创建之后执行

     当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会创建实例并进行
     初始化。
    
  • 就绪/调用阶段—— service 方法,每次有请求到达某个 Servlet 方法时执行,用来处理请求

     有请求到达容器,容器调用 servlet 对象的 service()方法处理请求。该方法可以多次调用。
     而service方法会根据请求的方式来调用是doGet方法还是doPost方法。 如果重写service才会
     自动去判断调用doget还是doPost这两个 do 方法默认情况下,会抛出异常,需要子类去
      override。
    
  • 销毁时机——destroy 方法,Servlet 实例销毁时执行

     当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。
    

    上述的生命周期方法,不用我们调用,在特定的时机容器会自动调用

Servlet 的生命周期,简单的概括这就分为四步:servlet 类加载–>实例化–>服务–>销毁。

Tomcat与Servlet 执行步骤

  1. 客户端向Tomcat发起请求
  2. Tomcat 接收请求
  3. Servlet 容器创建一个 HttpServletRequest 对象,将客户端请求信息封装到该对象
  4. Servlet 容器创建一个 HttpServletResponse 对象
  5. Servlet 容器调HttpServlet 对象service 方法,把 Request 与 Response 作为参数,传给 HttpServlet
  6. HttpServlet 调用 HttpServletRequest 对象的有关方法,获取 Http 请求信息
  7. HttpServlet 调用 HttpServletResponse 对象的有关方法,生成响应数据
  8. Servlet 容器把 HttpServlet 的响应结果传给 客户端

Tomcat 5大对象

HttpServletRequest对象

HTTPServletRequest 对象:用来接受并封装客户端发送过来的请求。例如:请求的参数,头信息,协议域名等等都是客户端发送过来的消息。service方法中形参接收的是Tomcat封装好的HttpServletRequest实例对象。该对象对应Http协议的请求。

HttpServletRequest 是 ServletRequest 的子接口,ServletRequest 只有一个子接口,就是 HttpServletRequest。既然只有一个子接口为什么不将两个接口合并为一个?

​ 从长远上讲:现在主要用的协议是 HTTP 协议,但以后可能出现更多新的协议。若以后想要支持这种新协议,只需要直接继承 ServletRequest 接口就行了。

常用方法
  • StringBuffer getRequestURL(); ——获取请求的地址 (不包含参数)

     String str=   req.getRequestURL().toString();
     返回http://localhost:8080/alion01/03
    
  • String getRequestURI();——获取请求的资源地址(端口后到参数前)

     String str=   req.getRequestURI();   
     返回/alion01/03
    
  • String getProtocol(); ——获取请求的协议

     返回HTTP/1.1
    
  • String getMethod(); ——获取请求的方式(Get/Post)

     返回GET
    
  • String getContextPath();——获取项目名称(环境地址)

     返回当前项目名称,修改后的名称/alion01。
    
  • String getParameter(String var1);——根据参数名获取参数值。

     	str = req.getParameter("userName");
     	返回afdaf
    
  • String[] getParameterValues(String var1);——根据参数名获取多个参数值。

  • Map<String, String[]> getParameterMap();——参数值封装在map中

  • String getQueryString(); ——获取参数部分的全部字符串。

     返回userName=afdaf&id=12
    

以上请求链接都用http://localhost:8080/Alion01/S03?userName=afdaf&id=12
最常用的是获取请求参数的方法。

乱码问题

由于现在的 request 属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为 ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。要想解决这种乱码问题,需要设置 request 中的编码方式,告诉服务器以何种方式来解析数据。或者在接收到乱码数据以后,再通过相应的编码格式还原。

  • 方式一

     request.setCharacterEncoding("UTF-8");  //该方法只针对post有效。
    
  • 方式二

     new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
    

方式二原因说明: ——传入的数据是utf-8 用utf-8 如果是gbk 用 gbk。

一般情况。我们进行编码格式转换。如GBK转成Unicode编码。
实际上,我们系统读入程序。已经将字符转成JVM指定的编码格式(Unicode)格式存储在内存中。比如我们设置编码环境是gbk。那么jvm会将gbk转成Unicode存储在内存中,显示的时候再转成gbk格式。

一般我们将GBK转成utf-8 实际上是把Unicode 转成 utf-8

例如str是gbk格式的字符串。实际上存储再内存中是Unicode格式。
-byte[] bt= str.getBytes("UTF-8"); //用utf-8将Unicode编码成utf-8格式字节数组
-str= new String(bt, "UTF-8"); //然后利用utf-8格式 将utf-8字节数组解码成字符串。
该字符串就是utf-8格式的字符串。
即 转什么编码。就用什么获取字节数组,然后进行解码。

但是tomact中 却使用ISO-8859-1可以转对应字符。那是因为tomcat默认是用ISO-8859-1进行编码的 。就是说 原本是gbk的字符串参数 经过tomcat处理会编程 ISO-8859-1格式的。则我们应该将ISO-8859-1转成GBK 再转成utf-8 但是因为ISO-8859-1是单个字节进行编码,所以不会对字节数组造成任何改变。因此Gbk经过tomact转码后 依然是GBK的内容。
则 new String(s.getBytes(“iso-8859-1”) ,“GBK”) 就可以正确解码。

请求转发

请求转发是服务器行为,客户端请求到达后,服务器进行请求转发。此时请求对象会被传递,并且浏览器中的url地址栏不会发送改变。得到响应后,服务器再将响应发送给客户端。从始至终只有一个请求被发出。

	request.getRequestDispatcher(url).forward(request,response);

只能跳转本地资源。
dispatcher方法中 地址默认会加上/alion01,即当前应用下。所以只能跳当前应用的资源。并且将request对象和response对象通过forward传入。那么之后的地址用到的对象也是这两个。 但实际上 不是同一个对象,只是把request对象的内容封装传入

打印这两个对象
org.apache.catalina.connector.RequestFacade@2a40d2ca
org.apache.catalina.core.ApplicationHttpRequest@37257912

request作用域

通过request对象可以再请求中传递参数,作用范围:在一次请求中有效,即服务器跳转有效。

  • request.setAttribute(String var1, Object var2);——设置域对象内容

     可以是任意类型的value值
    
  • request.getAttribute(String name); ——根据名称获取值

  • request.removeAttribute(String name);——删除域对象中某个值。

request 域对象中的数据在一次请求中有效,则经过请求转发,request 域中的数据依然存在,则在请求转发的过程中可以通过 request 来传输/共享数据。

HttpServletResponse对象

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的 request 对象和代表响应的 response 对象。

request 和 response 对象代表请求和响应:获取客户端数据,需要通过 request 对象;向客户端输出数据,需要通过 response 对象

HttpServletResponse 的主要功能用于服务器对客户端的请求进行响应,将 Web 服务器处理后的结果返回给客户端。service()方法中形参接收的是 HttpServletResponse 接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

响应数据方式

接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流。

  • getWriter();——该方法获取一个字符流,IO知识
  • getOutputStream();——获取一个字节流,可以传任意数据。

响应回的数据到客户端被浏览器解析。
两者不能同时使用。因为传递数据response响应一次就关闭了。无连接特性。

PrintWriter writer = response.getWriter();
writer.write("Hello");
writer.write("<h2>Hello</h2>");
// 字节输出流
ServletOutputStream out = response.getOutputStream();
out.write("Hello".getBytes());
out.write("<h2>Hello</h2>".getBytes());

设置响应类型,默认是字符串
-response.setHeader("content-type","text/html"); // html

响应乱码问题

响应中也会出现乱码,所以要指定服务器和客户端的编码格式一致。

对于 getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式,比如我们通常用的"UTF-8"。

  • response.setCharacterEncoding(“UTF-8”); 告知服务器使用指定的编码格式编码

  • response.setHeader(“content-type”, “text/html;charset=UTF-8”);

     该报头用于指定客户端进行解码的方式。或者直接使用
    
  • resp.setContentType();

    设置contentType的格式。这个可以直接指定服务器和客户端。
    一句话搞定
    

说到底就是要保证客户端和服务器编码格式一致。

对于outputStream来说由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码因此我们最好给他指定编码格式和解码格式。和上面一致。

重定向

重定向是服务器来做引导的客户端行为,服务器给客户端一个新的地址,(下次请求的地址 response.sendRedirect(url);)当客户端接收到响应后,会立刻、马上、自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。

  • response.sendRedirect(“index.jsp”);//重定向跳转到index.jsp

     这里可以写相对地址 相对地址就是再本应用下
     绝对地址就是,别的应用。http://开头
    

通过观察浏览器我们发现第一次请求获得的响应码为 302,并且含有一个 location 头信息。并且地址栏最终看到的地址是和第一次请求地址不同的,地址栏已经发生了变化。

请求转发与重定向的区别

在这里插入图片描述

Cookie对象

Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只须保存在客户端,或者在客户端进行处理的数据,放在本地的计算机上,不需要通过网络传输,因而提高网页处理的效率,并且能够减少服务器的负载,但是由于 Cookie 是服务器端保存在客户端的信息, 所以其安全性也是很差的。例如常见的记住密码则可以通过 Cookie 来实现。

有一个专门操作Cookie的类 javax.servlet.http.Cookie。随着服务器端的响应发送给客户端,保存在浏览器。当下次再访问服务器时把Cookie再带回服务器。

Cookie 的格式:键值对用“=”链接,多个键值对间通过“;”隔开。 cookie不支持中文。

Cookie的创建和发送

通过 new Cookie(“key”,“value”);来创建一个 Cookie 对象,要想将 Cookie 随响应发送到客户端,需要先添加到 response 对象中,response.addCookie(cookie);此时该 cookie 对象则随着响应发送至了客户端。在浏览器上可以看见。

  • new Cookie(“key”,“value”)——只能是字符串格式的
  • response.addCookie(cookie);——获取cookie,从请求的对象中
Cookie cookie = new Cookie("uname","zhangsan");
//发送cookie
response.addCookie(cookie);
Cookie的获取

它由服务器返回给浏览器,浏览器缓存并在每次请求时将 cookie 数据提交到服务器。Cookies 在请求中以明文传输,且大小限制 4KB,数量也有限制

在服务器端只提供了一个 getCookies()的方法用来获取客户端回传的所有 cookie 组成的一个数组,通过遍历该数组。并且通过getName()方法获取cookie的名称。getValue()获取对应的值

  • public String getName(); ——获取cookie对象的名称 即key
  • public String getValue();——湖区cookie对象的值 即value
Cookie cookie = new Cookie("name","zhangsan");
        resp.addCookie(cookie);

        Cookie[] cookies= req.getCookies();
        for (Cookie c : cookies){
            System.out.println(c.getName()+"----->"+c.getValue());
        }
Cookie设置到期时间

到期时间用来指定该 cookie 何时失效。默认为当前浏览器关闭即失效。我们可以手动设定 cookie 的有效时间(通过到期时间计算),通过 setMaxAge(int time);方法设定 cookie 的最大有效时间,以秒为单位。

浏览器会比较当前时间和cookie中设置的时间相加。

  • 负整数

     若为负数,表示不存储该 cookie。
     cookie 的 maxAge 属性的默认值就是-1,表示只在浏览器内存中存活,
     一旦关闭浏览器窗口,那么 cookie 就会消失。
    
  • 正整数

     若大于 0 的整数,表示存储的秒数。
     表示 cookie 对象可存活指定的秒数。当生命大于 0 时,浏览器会把 Cookie 保存到硬盘上
     就算关闭浏览器,就算重启客户端电脑,cookie 也会存活相应的时间。
    
  •  若为 0,表示删除该 cookie。
     cookie 生命等于 0 是一个特殊的值,它表示 cookie 被作废!也就是说,如果原来浏览器
     已经保存了这个 Cookie,那么可以通过 Cookie 的 setMaxAge(0)来删除这个 Cookie。
     无论是在浏览器内存中,还是在客户端硬盘上都会删除这个 Cookie。
    
// 创建Cookie对象
Cookie cookie = new Cookie("uname","zhangsan");
// 设置Cookie 3天后失效
cookie.setMaxAge(3 * 24 * 60 * 60);
// 发送Cookie对象
response.addCookie(cookie);
Cookie的注意点

Cookie保存在当前浏览器中。在一般的站点中常常有记住用户名这样一个操作,该操作只是将信息保存在本机上,换电脑以后这些信息就无效了。而且 cookie 还不能跨浏览器。

Cookie 中不能出现中文,如果有中文则通过 URLEncoder.encode()来进行编码,获取时通过 URLDecoder.decode()来进行解码。但是已经废弃。所以一般不用来传中文。

如果服务器端发送重复的Cookie那么会覆盖原有的Cookie。

不同的浏览器对Cookie也有限定,Cookie的存储有是上限的。Cookie是存储在客户端(浏览器)的,而且一般是由服务器端创建和设定。后期结合Session来实现回话跟踪。

Cookie的路径

Cookie的setPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些cookie。

  • 当前服务器下任何项目的任意资源都可获取Cookie对象

     cookie.setPath("/"); 表示在当前服务器下==任何项目==都可访问到Cookie对象
     需要通过response.addCookie来输出到浏览器(传递cookie)
    
  • 指定项目下的资源可获取Cookie对象 (默认不设置Cookie的path)
    不设置的话,默认是当前项目下所有资源。

     cookie.setPath("/s01"); 代表  /s01应用下的所有servlet组件都能访问到该类。
    
  • 指定目录下的资源可获取Cookie对象

     cookie.setPath("/s01/cook");  //只能是s01应用下的cook 类能访问到该cookie
    

如果我们设置path,如果当前访问的路径包含了cookie的路径(当前访问路径在cookie路径基础上要比cookie的范围小)cookie就会加载到request对象之中。

cookie的路径指的是可以访问该cookie的顶层目录,该路径的子路径也可以访问该cookie。

HttpSession对象

HttpSession对象是 javax.servlet.http.HttpSession 的实例,该接口只是一个纯粹的接口

对于服务器而言,每一个连接到它的客户端都是一个 session,servlet 容器使用此接口创建 HTTP 客户端和 HTTP 服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。可以通过此接口查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间。在整个 session 中,最重要的就是属性的操作。

session 无论客户端还是服务器端都可以感知到,若重新打开一个新的浏览器,则无法取得之前设置的 session,因为每一个 session 只保存在当前的浏览器当中,并在相关的页面取得。
Session 的作用就是为了标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数据。我们可以通过 request.getSession()方法,来获取当前会话的 session 对象。

  • HttpSession session = request.getSession();

     如果session对象存在,则获取;如果session对象不存在,则创建
    
标识符 JSESSIONID

Session 既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是 sessionId。

每当一次请求到达服务器,如果开启了会话(访问了 session),服务器第一步会查看是否从客户端回传一个名为 JSESSIONID 的 cookie,如果没有则认为这是一次新的会话,会创建 一个新的 session 对象,并用唯一的 sessionId 为此次会话做一个标志。如果有 JESSIONID 这 个cookie回传,服务器则会根据 JSESSIONID 这个值去查看是否含有id为JSESSION值的session 对象,如果没有则认为是一个新的会话,重新创建一个新的 session 对象,并标志此次会话; 如果找到了相应的 session 对象,则认为是之前标志过的一次会话,返回该 session 对象,数据达到共享。

​ 这里提到一个叫做 JSESSIONID 的 cookie,这是一个比较特殊的 cookie,当用户请求服务器时,如果访问了 session,则服务器会创建一个名为 JSESSIONID,值为获取到的 session(无论是获取到的还是新创建的)的 sessionId 的 cookie 对象,并添加到 response 对象中,响应给客户端,有效时间为关闭浏览器。(必须要访问到session )

​ 所以 Session 的底层依赖 Cookie 来实现。

session域对象

Session 用来表示一次会话,在一次会话中数据是可以共享的,这时 session 作为域对象存在,可以通过 setAttribute(name,value) 方法向域对象中添加数据,通过 getAttribute(name) 从域对象中获取数据,通过 removeAttribute(name) 从域对象中移除数据。

/ 获取session对象 
HttpSession session = request.getSession();
// 设置session域对象
session.setAttribute("uname","admin");
// 获取指定名称的session域对象
String uname = (String) request.getAttribute("uname");
// 移除指定名称的session域对象
session.removeAttribute("uname");
数据存储在 session 域对象中,当 session 对象不存在了,或者是两个不同的 session 对象时,
数据也就不能共享了。这就不得不谈到 session 的生命周期。
生命周期

当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min,即你不操作界面的时间,一旦有操作,session 会重新计时。

可以在 Tomcat 中的 conf 目录下的 web.xml 文件中进行修改。
<session-config> <session-timeout>30</session-timeout> </session-config>
也可以自己设定

  • session.setMaxInactiveInterval(int)——设定session的最大不活动时间,秒为单位

     // 获取session对象 
     HttpSession session = request.getSession();
     // 设置session的最大不活动时间
     session.setMaxInactiveInterval(15); // 15秒
    
  • session.getMaxInactiveInterval() ——查看session的最大不活动时间

  • session.invalidate();——使session立即失效。

关闭浏览器
从前面的 JESSIONID 可知道,session 的底层依赖 cookie 实现,并且该 cookie 的有效时间为关闭浏览器,从而 session 在浏览器关闭时也相当于失效了(因为没有 JSESSION 再与之对应)。

​当关闭服务器时,session 销毁。
​Session 失效则意味着此次会话结束,数据共享结束。

ServletContext对象

每一个 web 应用都有且仅有一个ServletContext 对象,又称 Application 对象,从名称中可知,该对象是与应用程序相关的。在 WEB 容器启动的时候,会为每一个 WEB 应用程序创建一个对应的 ServletContext 对象。

该对象有两大作用
第一、作为域对象用来共享数据,此时数据在整个应用程序中共享;
第二、该对象中保存了当前应用程序相关信息。例如可以通过 getServerInfo() 方法获取当前服务器信息 ,getRealPath(String path) 获取资源的真实路径等。

获取ServletContext对象

获取 ServletContext 对象的途径有很多

  • 通过 request 对象获取

     ServletContext servletContext = request.getServletContext();
    
  • 通过 session 对象获取

     ServletContext servletContext = request.getSession().getServletContext();
    
  • 通过 servletConfig 对象获取

     ServletConfig servletConfig = getServletConfig();
     ServletContext servletContext = servletConfig.getServletContext();
    
  • 直接获取,Servlet 类中提供了直接获取 ServletContext 对象的方法

     ServletContext servletContext = getServletContext();
    
常用方法
  • request.getServletContext().getRealPath("/");——获取项目的真实路径

     后面的字符串。表示对真实路径的追加,只能跟路径
     String str=getServletContext().getRealPath("/download");
     E:\IDeaJava\WebPro1\out\artifacts\WebPro1_war_exploded\download
    
  • request.getServletContext().getServerInfo();——获取服务器的版本信息

ServletContext域对象

ServletContext 也可当做域对象来使用,通过向 ServletContext 中存取数据,可以使得整个应用程序共享某些数据。当然不建议存放过多数据,因为 ServletContext 中的数据一旦存储进去没有手动移除将会一直保存。

// 获取ServletContext对象
ServletContext servletContext = request.getServletContext();
// 设置域对象
servletContext.setAttribute("name","zhangsan");
// 获取域对象
String name = (String) servletContext.getAttribute("name");
// 移除域对象
servletContext.removeAttribute("name");

三个域对象的生命周期
request域对象:在一次请求中有效。请求转发有效,重定向失效。
session域对象:在一次会话中有效。请求转发和重定向都有效,session销毁后失效。
servletContext域对象:在整个应用程序中有效。服务器关闭后失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值