j2ee基础

目录结构

webapproot
     |------WEB-INF(web应用的安全目录)
     		  |------classes(存放字节码)
     		  |------lib(第三方jar包)
     		  |------web.xml(注册Servlet)
     |------html
     |------css
     |------javascript
     |------image
     ....
     

web.xml以及注解配置信息

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
  version="5.0"
  metadata-complete="true">

	<!--servlet描述信息-->
	<!--任何一个servlet都对应一个servlet-mapping -->
	<servlet>
		<servlet-name>fdsafdsagfdsafdsa</servlet-name>
		<!--这个位置必须是带有包名的全限定类名-->
		<servlet-class>com.bjpowernode.servlet.HelloServlet</servlet-class>
        <!--servlet初始化参数-->
        <init-param>
            <param-name></param-name>
            <param-value></param-value>
        </init-param>
	</servlet>
    
    <!-- 这是应用级的初始参数,所有servlet共享 -->
    <context-param>
        <param-name></param-name>
        <param-value></param-value>
    </context-param>

	<!--servlet映射信息-->
	<servlet-mapping>
		<!--这个也是随便的,不过这里写的内容要和上面的一样。-->
		<servlet-name>fdsafdsagfdsafdsa</servlet-name>
		<!--这里需要一个路径-->
		<!--这个路径唯一的要求是必须以 / 开始-->
		<!--当前这个路径可以随便写-->
		<url-pattern>/fdsa/fd/saf/d/sa/fd/sa/fd</url-pattern>
	</servlet-mapping>
	
</web-app>
@WebServlet(name=, urlPatterns=,initParams=)
name:Servlet的名字,等同于 <servlet-name>
urlPatterns:映射路径数组,等同于<url-pattern>
initParams 参数数组;要用注解@WebInitParam(name="",value="");


例:								只要路径是以/test开始都走这个servlet;
@WebServlet(name="Serv", urlPatterns="/test/*",initParams=
{@WebInitParam(name="name",value="张三"),@WebInitParam(name="gender",value="男")})

注意:
	不是每个属性都要写上,需要什么写什么
	若属性是一个数组,数组中只有一个元素,则{}可以省略;

路径说明

web 中/ 斜杠的不同意义
在web 中/ 斜杠是一种绝对路径。
/ 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
斜杠
/ 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
1、/servlet1
2、servletContext.getRealPath(“/”);
3、request.getRequestDispatcher(“/”);
特殊情况: response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到http://ip:port/

<url-pattern> 这个路径唯一的要求是必须以 / 开始  代表项目下;

网页内链接     不带/, 代表项目目录下;
             可以用  /项目名/... 但不建议写死
            
            
jsp-file元素用来指定应用中JSP文件的完整路径。这个完整
路径必须/由开始

form action: 提交的服务器地址 要从项目名开始;

GenericServlet

  • 编写一个GenericServlet类,这个类是一个抽象类,其中有一个抽象方法service。

    • GenericServlet实现Servlet接口。
    • 以后编写的所有Servlet类继承GenericServlet,重写service方法即可。

ServletConfig

  • 什么是ServletConfig?

    • Servlet对象的配置信息对象。
    • ServletConfig对象中封装了标签中的配置信息。(web.xml文件中servlet的配置信息)
  • 一个Servlet对应一个ServletConfig对象。

  • Servlet对象是Tomcat服务器创建,并且ServletConfig对象也是Tomcat服务器创建。并且默认情况下,他们都是在用户发送第一次请求的时候创建。

  • Tomcat服务器调用Servlet对象的init方法的时候需要传一个ServletConfig对象的参数给init方法。

  • ServletConfig接口的实现类是Tomcat服务器给实现的。(Tomcat服务器说的就是WEB服务器。)

  • ServletConfig接口有哪些常用的方法?

    • public String getInitParameter(String name); // 通过初始化参数的name获取value
      public Enumeration<String> getInitParameterNames(); // 获取所有的初始化参数的name
      public ServletContext getServletContext(); // 获取ServletContext对象
      public String getServletName(); // 获取Servlet的name
      
    • 以上方法在Servlet类当中,都可以使用this去调用。因为GenericServlet实现了ServletConfig接口。

ServletContext

  • 一个Servlet对象对应一个ServletConfig。

  • 只要在同一个webapp当中,只要在同一个应用当中,所有的Servlet对象都是共享同一个ServletContext对象的。

  • ServletContext对象在服务器启动阶段创建,在服务器关闭的时候销毁。这就是ServletContext对象的生命周期。ServletContext对象是应用级对象。

  • 一个ServletContext对象通常对应的是一个web.xml文件。

  • ServletContext接口中有哪些常用的方法?

    • public String getInitParameter(String name); // 通过初始化参数的name获取value
      public Enumeration<String> getInitParameterNames(); // 获取所有的初始化参数的name
      
      
Enumeration<String> parameterNames = request.getParameterNames();
    while (parameterNames.hasMoreElements()) {
    	String name = parameterNames.nextElement();
    	out.println(name + "=" + request.getParameter(name));
    }
  • <!--以上两个方法是ServletContext对象的方法,这个方法获取的是什么信息?是以下的配置信息-->
    <context-param>
        <param-name>pageSize</param-name>
        <param-value>10</param-value>
    </context-param>
    <context-param>
        <param-name>startIndex</param-name>
        <param-value>0</param-value>
    </context-param>
    <!--注意:以上的配置信息属于应用级的配置信息,一般一个项目中共享的配置信息会放到以上的标签当中。-->
    <!--如果你的配置信息只是想给某一个servlet作为参考,那么你配置到servlet标签当中即可,使用ServletConfig对象来获取。-->
    
  • // 获取应用的根路径(非常重要),因为在java源代码当中有一些地方可能会需要应用的根路径,这个方法可以动态获取应用的根路径
    public String getContextPath();
    //String contextPath = application.getContextPath();
    
  •   // 获取文件的绝对路径(真实路径)
      public String getRealPath(String path);
    
  •   // 通过ServletContext对象也是可以记录日志的
      public void log(String message);
      public void log(String message, Throwable t);
      // 这些日志信息记录到哪里了?
      // localhost.2021-11-05.log
      
      // Tomcat服务器的logs目录下都有哪些日志文件?
      //catalina.2021-11-05.log 服务器端的java程序运行的控制台信息。
      //localhost.2021-11-05.log ServletContext对象的log方法记录的日志信息存储到这个文件中。
      //localhost_access_log.2021-11-05.txt 访问日志
    
  •   // ServletContext对象还有另一个名字:应用域(后面还有其他域,例如:请求域、会话域)
      
      // 存(怎么向ServletContext应用域中存数据)
      public void setAttribute(String name, Object value); // map.put(k, v)
      // 取(怎么从ServletContext应用域中取数据)
      public Object getAttribute(String name); // Object v = map.get(k)
      // 删(怎么删除ServletContext应用域中的数据)
      public void removeAttribute(String name); // map.remove(k)
      
    
  • 注意:以后我们编写Servlet类的时候,实际上是不会去直接继承GenericServlet类的,因为我们是B/S结构的系统,这种系统是基于HTTP超文本传输协议的,在Servlet规范当中,提供了一个类叫做HttpServlet,它是专门为HTTP协议准备的一个Servlet类。我们编写的Servlet类要继承HttpServlet。(HttpServlet是HTTP协议专用的。)使用HttpServlet处理HTTP协议更便捷。但是你需要直到它的继承结构:

    • jakarta.servlet.Servlet(接口)【爷爷】
      jakarta.servlet.GenericServlet implements Servlet(抽象类)【儿子】
      jakarta.servlet.http.HttpServlet extends GenericServlet(抽象类)【孙子】
      
      我们以后编写的Servlet要继承HttpServlet类。
      

HTTP协议

  • HTTP协议包括:

    • 请求协议
      • 浏览器 向 WEB服务器发送数据的时候,这个发送的数据需要遵循一套标准,这套标准中规定了发送的数据具体格式。
    • 响应协议
      • WEB服务器 向 浏览器发送数据的时候,这个发送的数据需要遵循一套标准,这套标准中规定了发送的数据具体格式。

    Http请求协议包内部空间:【背】

     1.按照自上而下划分,分为4个空间
    
     2.空间划分:
    
                请求行:[
    	            url:请求地址(http://192.168.100.2:8080/index.html)
    	            method:请求方式(POST/GET)
    	         ]
    
                请求头:[
    	
    	              请求参数信息【GET】
    	         ]
    
                空白行:[
    	                没有任何内容,起到隔离作用
    	 
    	         ]
    
                 请求体:[
    	  
    	             请求参数信息【POST】
    	          ]
    

    Http响应协议包内部结构 【背】

          1.按照自上而下划分,分为4个空间
    
      2.空间划分:
    
                 状态行:[
    	                  Http状态码
    	     
    	              ]
    
                     响应头:[
    	                  content-type: 指定浏览器采用对应编译器
    			                对响应体二进制数据进行解析
    	     
    	              ]
    
                     空白行:[
    	                  没有任何内容,起到隔离作用
    	     
    	              ]
                     响应体:[
    	                 可能被访问静态资源文件内容
    			 可能被访问的静态资源文件命令
    			 可能被访问的动态资源文件运行结果
    	                  *****都是以二进制形式***
    	              ]
    
  • GET请求和POST请求有什么区别?

    • get请求发送数据的时候,数据会挂在URI的后面,并且在URI后面添加一个“?”,"?"后面是数据。这样会导致发送的数据回显在浏览器的地址栏上。(get请求在“请求行”上发送数据)
    • post请求发送数据的时候,在请求体当中发送。不会回显到浏览器的地址栏上。也就是说post发送的数据,在浏览器地址栏上看不到。(post在“请求体”当中发送数据)
    • get请求只能发送普通的字符串。并且发送的字符串长度有限制,不同的浏览器限制不同。这个没有明确的规范。
    • get请求无法发送大数据量。
    • post请求可以发送任何类型的数据,包括普通字符串,流媒体等信息:视频、声音、图片。
    • post请求可以发送大数据量,理论上没有长度限制。
    • get请求在W3C中是这样说的:get请求比较适合从服务器端获取数据。
    • post请求在W3C中是这样说的:post请求比较适合向服务器端传送数据。
    • get请求是安全的。get请求是绝对安全的。为什么?因为get请求只是为了从服务器上获取数据。不会对服务器造成威胁。
    • post请求是危险的。为什么?因为post请求是向服务器提交数据,如果这些数据通过后门的方式进入到服务器当中,服务器是很危险的。另外post是为了提交数据,所以一般情况下拦截请求的时候,大部分会选择拦截(监听)post请求。
    • get请求支持缓存。
      • 任何一个get请求最终的“响应结果”都会被浏览器缓存起来。在浏览器缓存当中:
      • 实际上,你只要发送get请求,浏览器做的第一件事都是先从本地浏览器缓存中找,找不到的时候才会去服务器上获取。这种缓存机制目的是为了提高用户的体验。
      • 有没有这样一个需求:我们不希望get请求走缓存,怎么办?怎么避免走缓存?我希望每一次这个get请求都去服务器上找资源,我不想从本地浏览器的缓存中取。
        • 只要每一次get请求的请求路径不同即可。
        • 怎么解决?可以在路径的后面添加一个每时每刻都在变化的“时间戳”,这样,每一次的请求路径都不一样,浏览器就不走缓存了。
    • post请求不支持缓存。(POST是用来修改服务器端的资源的。)
      • post请求之后,服务器“响应的结果”不会被浏览器缓存起来。因为这个缓存没有意义。
  • GET请求和POST请求如何选择,什么时候使用GET请求,什么时候使用POST请求?

    • 怎么选择GET请求和POST请求呢?衡量标准是什么呢?你这个请求是想获取服务器端的数据,还是想向服务器发送数据。如果你是想从服务器上获取资源,建议使用GET请求,如果你这个请求是为了向服务器提交数据,建议使用POST请求。
    • 大部分的form表单提交,都是post方式,因为form表单中要填写大量的数据,这些数据是收集用户的信息,一般是需要传给服务器,服务器将这些数据保存/修改等。
    • 如果表单中有敏感信息,还是建议适用post请求,因为get请求会回显敏感信息到浏览器地址栏上。(例如:密码信息)
    • 做文件上传,一定是post请求。要传的数据不是普通文本。
    • 其他情况都可以使用get请求。
  • 不管你是get请求还是post请求,发送的请求数据格式是完全相同的,只不过位置不同,格式都是统一的:

    • name=value&name=value&name=value&name=value
    • name是什么?
      • 以form表单为例:form表单中input标签的name。
    • value是什么?
      • 以form表单为例:form表单中input标签的value。
  • 我们编写的HelloServlet直接继承HttpServlet,直接重写HttpServlet类中的service()方法行吗?

    • 可以,只不过你享受不到405错误。享受不到HTTP协议专属的东西。
  • 到今天我们终于得到了最终的一个Servlet类的开发步骤:

    • 第一步:编写一个Servlet类,直接继承HttpServlet
    • 第二步:重写doGet方法或者重写doPost方法,到底重写谁,javaweb程序员说了算。
    • 第三步:将Servlet类配置到web.xml文件当中。
    • 第四步:准备前端的页面(form表单),form表单中指定请求路径即可。

关于一个web站点的欢迎页面

  • 什么是一个web站点的欢迎页面?

    • 对于一个webapp来说,我们是可以设置它的欢迎页面的。

    • 设置了欢迎页面之后,当你访问这个webapp的时候,或者访问这个web站点的时候,没有指定任何“资源路径”,这个时候会默认访问你的欢迎页面。

      login.html ```
      • 注意:设置欢迎页面的时候,这个路径不需要以“/”开始。并且这个路径默认是从webapp的根下开始查找。
  • 如果在webapp的根下新建一个目录,目录中再给一个文件,那么这个欢迎页该如何设置呢?

    • 在webapp根下新建page1

    • 在page1下新建page2目录

    • 在page2目录下新建page.html页面

    • 在web.xml文件中应该这样配置

      • <welcome-file-list>
            <welcome-file>page1/page2/page.html</welcome-file>
        </welcome-file-list>
        
      • 注意:路径不需要以“/”开始,并且路径默认从webapp的根下开始找。

  • 一个webapp是可以设置多个欢迎页面的

    • <welcome-file-list>
          <welcome-file>page1/page2/page.html</welcome-file>
          <welcome-file>login.html</welcome-file>
      </welcome-file-list>
      
    • 注意:越靠上的优先级越高。找不到的继续向下找。

    当我的文件名设置为index.html的时候,不需要在web.xml文件中进行配置欢迎页面。

      index.html index.htm index.jsp ```
      • 注意原则:局部优先原则。(就近原则)
  • 欢迎页可以是一个Servlet

    • 静态资源:index.html welcome.html .....

    • 动态资源:Servlet类

HttpServletRequest接口详解

  • HttpServletRequest接口的父接口:ServletRequest

    • public interface HttpServletRequest extends ServletRequest {}!
      
  • HttpServletRequest对象中都有什么信息?都包装了什么信息?

    • HttpServletRequest对象是Tomcat服务器负责创建的。这个对象中封装了什么信息?封装了HTTP的请求协议。
    • 实际上是用户发送请求的时候,遵循了HTTP协议,发送的是HTTP的请求协议,Tomcat服务器将HTTP协议中的信息以及数据全部解析出来,然后Tomcat服务器把这些信息封装到HttpServletRequest对象当中,传给了我们javaweb程序员。
    • javaweb程序员面向HttpServletRequest接口编程,调用方法就可以获取到请求的信息了。
  • request和response对象的生命周期?

    • request对象和response对象,一个是请求对象,一个是响应对象。这两个对象只在当前请求中有效。
    • 一次请求对应一个request。
    • 两次请求则对应两个request。
    • .....
  • HttpServletRequest接口中有哪些常用的方法?

    • 怎么获取前端浏览器用户提交的数据?

      • Map<String,String[]> getParameterMap() 这个是获取Map
        Enumeration<String> getParameterNames() 这个是获取Map集合中所有的key
        //循环遍历Enumeration;
            while (parameterNames.hasMoreElements()) {
                    String name = parameterNames.nextElement();
            }
        
        String[] getParameterValues(String name) 根据key获取Map集合的value
        

    String getParameter(String name) 获取value这个一维数组当中的第一个元素。这个方法最常用。
    // 以上的4个方法,和获取用户提交的数据有关系。
    ```

    • 先测试了4个常用的方法,获取请求参数的四个方法。

      Map<String,String[]> parameterMap = request.getParameterMap();
      Enumeration names = request.getParameterNames();
      String[] values = request.getParameterValues("name");
      String value = request.getParameter("name");

    • request对象实际上又称为“请求域”对象。

      • 应用域对象是什么?

        • ServletContext (Servlet上下文对象。)

        • 什么情况下会考虑向ServletContext这个应用域当中绑定数据呢?

          • 第一:所有用户共享的数据。
        • 第二:这个共享的数据量很小。

      • 第三:这个共享的数据很少的修改操作。

        • 在以上三个条件都满足的情况下,使用这个应用域对象,可以大大提高我们程序执行效率。

        • 实际上向应用域当中绑定数据,就相当于把数据放到了缓存(Cache)当中,然后用户访问的时候直接从缓存中取,减少IO的操作,大大提升系统的性能,所以缓存技术是提高系统性能的重要手段。

        • ServletContext当中有三个操作域的方法:

          • void setAttribute(String name, Object obj); // 向域当中绑定数据。
            Object getAttribute(String name); // 从域当中根据name获取数据。
            void removeAttribute(String name); // 将域当中绑定的数据移除
            
                
            
      • “请求域”对象

        • “请求域”对象要比“应用域”对象范围小很多。生命周期短很多。请求域只在一次请求内有效。

        • 一个请求对象request对应一个请求域对象。一次请求结束之后,这个请求域就销毁了。

        • 请求域对象也有这三个方法:

    void setAttribute(String name, Object obj); // 向域当中绑定数据。
    Object getAttribute(String name); // 从域当中根据name获取数据。
    void removeAttribute(String name); // 将域当中绑定的数据移除
    ```

    - 请求域和应用域的选用原则?
    
      - 尽量使用小的域对象,因为小的域对象占用的资源较少。
    
    • 跳转

      • 转发(一次请求)浏览器地址不变

      • 只能向Tomcat服务器申请调用当前网站下资源文件地址

      // 第一步:获取请求转发器对象
      RequestDispatcher dispatcher = request.getRequestDispatcher("/b");
      // 第二步:调用转发器的forward方法完成跳转/转发
      dispatcher.forward(request,response);

      // 请求转发必须要以斜杠打头,,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA 代码的web 目录
      

      request.getRequestDispatcher("/b").forward(request,response);

      ```
      
    • 重定向(浏览器又发出了一次请求)浏览器路径改变

      
          //重定向时路径需要要以项目开始      项目名          跳转路径
          response.sentRedirect(request.getContextPath()+"/a");
          
      
    • 两个Servlet怎么共享数据?

      • 将数据放到ServletContext应用域当中,当然是可以的,但是应用域范围太大,占用资源太多。不建议使用。

      • 可以将数据放到request域当中,然后AServlet转发到BServlet,保证AServlet和BServlet在同一次请求当中,这样就可以做到两个Servlet,或者多个Servlet共享同一份数据。

      • 转发的下一个资源必须是一个Servlet吗?

        • 不一定,只要是Tomcat服务器当中的合法资源,都是可以转发的。例如:html....
      • 注意:转发的时候,路径的写法要注意,转发的路径以“/”开始,不加项目名。

        • 关于request对象中两个非常容易混淆的方法:

        • // uri?username=zhangsan&userpwd=123&sex=1
          String username = request.getParameter("username");
          
            // 之前一定是执行过:request.setAttribute("name", new Object())
          Object obj = request.getAttribute("name");
            
          // 以上两个方法的区别是什么?
            // 第一个方法:获取的是用户在浏览器上提交的数据。
            // 第二个方法:获取的是请求域当中绑定的数据。
          
        • HttpServletRequest接口的其他常用方法:

          • // 获取客户端的IP地址
            String remoteAddr = request.getRemoteAddr();
            
            //get请求乱码     get请求在请求行上提交数据。
            

          // 获取请求参数
          String username = req.getParameter("username");
          //1 先以iso8859-1 进行编码
          //2 再以utf-8 进行解码
          username = new String(username.getBytes("iso-8859-1"), "UTF-8");

          // post请求乱码 post请求在请求体中提交数据。
          request.setCharacterEncoding("UTF-8");

          // 解决响应中文也是有乱码的
          response.setContentType("text/html;charset=UTF-8");

          // get请求乱码问题怎么解决?
          // get请求发送的时候,数据是在请求行上提交的,不是在请求体当中提交的。
          // get请求乱码怎么解决
          // 方案:修改CATALINA_HOME/conf/server.xml配置文件

          // 注意:从Tomcat8之后,URIEncoding的默认值就是UTF-8,所以GET请求也没有乱码问题了。

          // 获取应用的根路径
          String contextPath = request.getContextPath();

          // 获取请求方式
          String method = request.getMethod();

          // 获取请求的URI
          String uri = request.getRequestURI(); // /aaa/testRequest

          // 获取servlet path
          String servletPath = request.get# ServletPath(); // /testRequest

          
          
          

监听器接口

监听器接口需要由开发人员亲自实现,Http服务器提供jar包并没有对应的实现类
监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】

​ 监听器接口实现类开发规范:三步

1)根据监听的实际情况,选择对应监听器接口进行实现

2)重写监听器接口声明【监听事件处理方法】

3)在web.xml文件将监听器接口实现类注册到Http服务器

事件监听的声明在应用程序的web.xml里,用<listener>元素,该元素是<web-app>的子元素。
每个监听器都对应一个<listener>,有一个<listener-class>子元素用来指定对应的类名。在每种事件中,你需要指定你想调用的顺序

注解@WebListener

value      Stirng   描述信息

在应用程序启动之后,并且在第一次请求之前,servlet容器会创建并注册每个监听类的实例。
每种事件,监听器是按照他们声明的顺序来注册的。然后,当应用程序开始运行,每种事件监听器安照他们的顺序调用。在最后一次请求之前,所有的监听器都保持活动状态。一旦应用程序关闭,session事件首先发生,以他们声明的顺序相反。然后context事件发生也是以声明的顺序相反。

每个监听类文件必须打包到WAR文件,也可以是在WEB-lNF/classes或是包含在WEB-NFib下的JAR文件中。

4.ServletContextListener接口:
  1)作用:通过这个接口合法的检测全局作用域对象被初始化时刻以及被销毁时刻
  2)监听事件处理方法:
	public void contextInitlized() :在全局作用域对象被Http服务器初始化被调用
	public void contextDestory():      在全局作用域对象被Http服务器销毁时候触发调用

5.ServletContextAttributeListener接口:
  1)作用:通过这个接口合法的检测全局作用域对象共享数据变化时刻
  2)监听事件处理方法:
	public void contextAdd():在全局作用域对象添加共享数据
	public void contextReplaced():在全局作用域对象更新共享数据
	public void contextRemove():在全局作用域对象删除共享数据

6.全局作用域对象共享数据变化时刻
	ServletContext application = request.getServletContext();
	application.setAttribute("key1",100); //新增共享数据
	application.setAttribute("key1",200); //更新共享数据
	application.removeAttribute("key1");  //删除共享数据
HttpSessionListener接口:
  1)作用:通过这个接口合法的检测会话域对象被初始化时刻以及被销毁时刻
  2)监听事件处理方法:
	public void SessionCreated() :	在会话域对象被Http服务器初始化被调用
	public void SessionDestory():      在会话域对象被Http服务器销毁时候触发调用

HttpSessionAttributeListener接口:
  1)作用:通过这个接口合法的检测会话域对象共享数据变化时刻
  2)监听事件处理方法:
	public void attributeAdd():在会话域对象添加共享数据
	public void attributeReplaced():在会话域对象更新共享数据
	public void attributeRemove():在会话域对象删除共享数据

Filter接口(过滤器接口)

介绍:
1)来自于Servlet规范下接口,在Tomcat中存在于servlet-api.jar包

​ 2)Filter接口实现类由开发人员负责提供,Http服务器不负责提供

	  3)Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截

具体作用:

​ 1)拦截Http服务器,帮助Http服务器检测当前请求合法性

​ 2)拦截Http服务器,对当前请求进行增强操作

生命周期

Filter的创建

  Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作,filter对象只会创建一次,init方法也只会执行一次。通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

Filter的销毁

  Web容器调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

Filter接口实现类开发步骤:三步

​ 1)创建一个Java类实现Filter接口

2)重写Filter接口中doFilter方法

3)web.xml将过滤器接口实现类注册到Http服务器

Filter配置web.xml

<filter>
	<filter-name>filterName</filter-name>
    <filter-class>className</filter-class>
</filter>
<filter-mapping>
	<filter-name>filterName</filter-name>
	<url-pattern>/拦截地址</url-pattern>
</filter-mapping>
        

拦截地址

要求Tomcat在调用某一个文件夹下所有的资源文件之前,来调用OneFilter拦截
	<url-pattern>/img/*</url-pattern>

要求Tomcat在调用任意文件夹下某种类型文件之前,来调用OneFilter拦截
	<url-pattern>*.jpg</url-pattern>

要求Tomcat在调用网站中任意文件时,来调用OneFilter拦截
	<url-pattern>/*</url-pattern>           

注解配置@WebFilter

filterName    Stirng    等同于<filter-name>
urlPatterns   String[]  指定一组URL的匹配模式  等同于<url-pattern>
value   等同于urlPatterns
servletNames   String[]  指定过滤器将用于那些servlet,取值是@WebServlet中的name属性或web.xml														中的<servlet-name>
initParams    @WebInitParam[]   初始化参数,等同于 <init-param>标签

多个Servlet之间数据共享实现方案

1.数据共享:OneServlet工作完毕后,将产生数据交给TwoServlet来使用

2.Servlet规范中提供四种数据共享方案

1.ServletContext接口

2.Cookie类

3.HttpSession接口

​ 4.HttpServletRequest接口

ServletContext接口:

servlet1:
//1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
ServletContext application = request.getServletContext();
//2.将数据添加到全局作用域对象作为【共享数据】
application.setAttribute("key1",数据)
			    
servlet2:
//1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
ServletContext application = request.getServletContext();
//2.从全局作用域对象得到指定关键字对应数据
Object 数据 =  application.getAttribute("key1");
1.介绍:
 1)Cookie来自于Servlet规范中一个工具类,存在于Tomcat提供servlet-api.jar中
2)如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于Cookie对象进行数据共享
3) Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量


2.原理:
用户通过浏览器第一次向MyWeb网站发送请求申请OneServlet。OneServlet创建一个Cookie存储与当前用户相关数据【将Cookie写入到响应头】交还给当前浏览器。浏览器收到响应响应包之后,将cookie存储在浏览器的缓存
	一段时间之后,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请TwoServlet时。【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头】发送过去此时TwoServlet在运行时,就可以通过读取请求头中cookie中信息,得到OneServlet提供的共享数据

 3.实现命令:  同一个网站 OneServlet 与  TwoServlet 借助于Cookie实现数据共享

//1.创建一个cookie对象,保存共享数据(当前用户数据)
Cookie card = new Cookie("key1","abc");
Cookie card1= new Cookie("key2","efg");
****一个cookie中只能存放一个键值对,这个键值对的key与value只能是String,键值对中key不能是中文
//2.【发卡】将cookie写入到响应头,交给浏览器
resp.addCookie(card); 
resp.addCookie(card1)


TwoServlet:    
//1.调用请求对象从请求头得到浏览器返回的Cookie
 Cookie  cookieArray[] = request.getCookies();
//2.循环遍历数据得到每一个cookie的key 与 value
 for(Cookie card:cookieArray){
 String key =   card.getName(); 读取key  "key1"
Strign value = card.getValue();读取value "abc"
}

		  
4.Cookie销毁时机:

1.在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉

2.在手动设置情况下,可以要求浏览器将接收的Cookie存放在客户端计算机上硬盘上,同时需要指定Cookie
在硬盘上存活时间。在存活时间范围内,关闭浏览器关闭客户端计算机,关闭服务器,都不会导致Cookie
被销毁。在存活时间到达时,Cookie自动从硬盘上被删除

cookie.setMaxAge(60); //cookie在硬盘上存活1分钟

HttpSession接口:

​ 会话 session

  • 用户打开浏览器,进行一系列操作,然后最终将浏览器关闭,这个整个过程叫做:一次会话。会话在服务器端也有一个对应的java对象,这个java对象叫做:session。
  • 什么是一次请求:用户在浏览器上点击了一下,然后到页面停下来,可以粗略认为是一次请求。请求对应的服务器端的java对象是:request。
  • 一个会话当中包含多次请求。(一次会话对应N次请求。)

常用的会话追踪机制有:
cookies
SSL Sessions
URL重写
表单隐藏

可以下列的方法来做隐藏表单字段的会话追踪。
<input type="hidden"name="userlD"value="15">

session对象最主要的作用是:保存会话状态

  • equest是一次请求一个对象。

  • ServletContext对象是服务器启动的时候创建,服务器关闭的时候销毁,这个ServletContext对象只有一个。

  • request请求域(HttpServletRequest)、session会话域(HttpSession)、application域(ServletContext)

  • request < session < application

       2.HttpSession 与  Cookie 区别:【面试题】
       
       1)存储位置:  一个在天上,一个在地下
      Cookie:存放在客户端计算机(浏览器内存/硬盘)
               HttpSession:存放在服务端计算机内存
      
       2)数据类型:
               Cookie对象存储共享数据类型只能是String
      HttpSession对象可以存储任意类型的共享数据Object
               
      3) 数据数量:
               一个Cookie对象只能存储一个共享数据
      HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据
      
      4)参照物:
      Cookie相当于客户在服务端【会员卡】
             HttpSession相当于客户在服务端【私人保险柜】
    

    常用方法
    getAttribute():从session中获取以前存储的值
    getAttributeNames():返回session中所有属性的名称
    setAttribute():将键与值关联起来,存储进session
    removeAttribute(O:删除session中存储的对应键的值
    invalidate():删除整个session及其存储的键值
    logout(0:注销当前用户
    getld():获取每个session对应的唯一ID
    getCreationTime():获取session创建的时间
    getLastAccessedTime():获取session:最后被访问的时间
    getMaxInactivelnterval():在用户没有访问的情况下,会话在被自动废弃之前应该保持多长时间

    3.命令实现: 同一个网站(myWeb)下OneServlet将数据传递给TwoServlet
    OneServlet:
    //1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
    HttpSession session = request.getSession();
    //2.将数据添加到用户私人储物柜
    session.setAttribute("key1",共享数据)

    TwoServlet:
    //1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
    HttpSession session = request.getSession();
    //2.从会话作用域对象得到OneServlet提供的共享数据
    Object 共享数据 = session.getAttribute("key1");

    4.Http服务器如何将用户与HttpSession关联起来
    cookie

    5 getSession(): 同getSession(true),存在则返回,没有则创建并返回
    getSession(false):存在则返回,没有则返回null

    显式关闭
    HttpSession.invalidate()方法来关闭它
    隐式关闭--会话超时(等待超时后的自动操作)
    默认的超时时间间隔是1800秒。
    在servlet容器将其设置为无效之前,servleti可以使用setlnactivelnterval(int seconds)方法在客户请求之间控制这个时间间隔。设置负值可以确保会话永远不会超时

    7.HttpSession空闲时间手动设置
    在当前网站/web/WEB-INF/web.xml

    5

HttpServletRequest接口实现数据共享

1) 在同一个网站中,两个Servlet之间通过【请求转发】方式进行调彼此之间共享同一个请求协议包。
【请求作用域对象】


2.命令实现: OneServlet通过请求转发申请调用TwoServlet时,需要给TwoServlet提供共享数据
//1.将数据添加到【请求作用域对象】中attribute属性
req.setAttribute("key1",数据); //数据类型可以任意类型Object
//2.向Tomcat申请调用TwoServlet
req.getRequestDispatcher("/two").forward(req,response)
          
另一个servlet: two
//从当前请求对象得到OneServlet写入到共享数据
Object 数据 = req.getAttribute("key1");		

posted @ 2022-03-07 16:36  awei666  阅读(34)  评论(0编辑  收藏  举报