软件结构

  • cs结构的软件
    • cs:Client/Server 客户端和服务器,这种软件往往需要安装。比如QQ、迅雷
    • 优缺点
      • 优点
        • 可以减轻服务器端压力,将部分代码写到客户端
        • 界面美观
      • 缺点
        • 一旦服务器更新,客户端也要更新
        • 分布式开发比较弱
  • BS结构的软件

    • BS:Browser/Server 浏览器和服务器。这种软件不需要安装,只需要通过浏览器可以直接访问
    • 优缺点
      • 优点
        • 服务器更新,不需要更新客户端
        • 比较强的分布式能力
      • 缺点
        • 服务器压力会比较大
        • 界面效果不如CS结构软件

          WEB服务器

  • 服务器

    • 硬件:其实就是一台电脑
    • 软件:需要在这台电脑安装web服务的软件

      常见WEB服务器

  • Tomcat Apache 提供开源免费服务器 满足EE的serlet和JSP规范

  • WebSphere IBM 收费大型服务器 满足EE开发所有规范
  • WebLogic BEA 收费大型服务器 满足EE开发所有规范
  • IIS 应用在.NET平台上
  • Apache 应用在PHP平台上

    WEB开发中的资源

  • 静态Web资源

    • HTML
    • CSS
    • JS
  • 动态Web资源
    • Servlet、JSP
    • PHP
    • ASP

Tomcat

tomcat.apache.org/download-70.cgi

查看端口netstat -ano

Web项目目录结构

website
|——静态页面(HTML,CSS,JS,图片)
|——JSP页面
|——Web-INF
|——web.xml(必须的)
|——classes(可选的)
|——lib(可选的)

Tomcat 项目发布

  • 直接将项目复制到tomcat/websites下
  • 在tomcat/conf/server.xml配置tomcat的虚拟路径
  • 在tomcat/conf/Catalina/localhost/下配置tomcat虚拟路径

    部署项目

    server.xml 配置虚拟路径 path 虚拟地址 dosbase 真实地址

    1. <Context path="/xx" docBase="C:\Users\Administrator\Desktop\xx"></Context>
    1. ![图片.png](https://cdn.nlark.com/yuque/0/2020/png/1561487/1593675773837-23dcd730-8ce1-4d74-8a3c-1fe8ff3f40a3.png#align=left&display=inline&height=304&margin=%5Bobject%20Object%5D&name=%E5%9B%BE%E7%89%87.png&originHeight=304&originWidth=651&size=14414&status=done&style=none&width=651)<br />新建xxx.xml xml名称作为虚拟路径 dosbase 真是地址
    1. <?xml version='1.0' encoding='utf-8'?>
    2. <Context docBase="C:\Users\Administrator\Desktop\xx"></Context>
    1. ![图片.png](https://cdn.nlark.com/yuque/0/2020/png/1561487/1593676483522-3cb1b5c2-1b3d-4267-9728-30ef5472fbdf.png#align=left&display=inline&height=39&margin=%5Bobject%20Object%5D&name=%E5%9B%BE%E7%89%87.png&originHeight=39&originWidth=393&size=1232&status=done&style=none&width=393)

    HTTP协议

    请求requst 响应response

    请求部分

    Referer

    来源地址(防盗链)

    User-Agent

     获取客户端浏览器类型
    

    请求部分

    响应头

    • Location 重定向的路径
    • Refresh 定时刷新
    • Content-Disposition 文件下载时使用

      Servlet

      Servlet 其实就是一个运行web服务器上的小的Java程序,用于处理从web客户端发送的请求,并且对请求作出响应

使用Servlet

  • 编写一个Java类实现Servlet的实例

    public class HelloServlet implements Servlet{
      @Override
      public void service(ServletRequest req, ServletResponse resp)
              throws ServletException, IOException {
          // TODO Auto-generated method stub
          resp.getWriter().println("Hello world");
      }
    }
    
  • 配置Servlet

    <servlet>
          <!-- 配置Servlet的名称 -->
          <servlet-name>HelloServlet</servlet-name>
          <!-- 配置Servlet类的全路径 -->
          <servlet-class>com.xx.servlet.demo.HelloServlet</servlet-class>
      </servlet>
      <!-- 配置Servlet的映射 -->
      <servlet-mapping>
          <!-- 配置Servlet的名称 -->
          <servlet-name>HelloServlet</servlet-name>
          <!-- 配置访问路径 -->
          <url-pattern>/hello</url-pattern>
      </servlet-mapping>
    

    Servlet基本关系

    servlet 接口
    |
    |
    GenericServlet类 通用的Servlet 与协议无关的Servlet
    |
    |
    HttpServlet类 Http专用的Servlet

通常编写一个Servlet 一般都会让这个Servlet 继承 HttpServlet 重写Service方法
在service方法内部根据请求方式不同执行不同的doxxx的方法(get请求执行doGet方法,如果是post请求就会执行doPost方法)。
所以往往继承了HttpServlet 之后不需要重写Service方法,秩序重写doGet和doPost方法即可。往往请求要处理的内容的代码都是一致的,所以需要让doGet和doPost相互调用可以简化编程。

eclipse开发Servlet

  • 无需自己配置 自动生成 ```java package com.xx.servlet.demo;

import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

/**

  • Servlet implementation class ServletDemo */ @WebServlet(“/ServletDemo”) public class ServletDemo extends HttpServlet { private static final long serialVersionUID = 1L;

    /**

    • @see HttpServlet#HttpServlet() */ public ServletDemo() { super(); // TODO Auto-generated constructor stub }

      /**

    • @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append(“Served at:”).append(request.getContextPath());//append追加字符串 }

      /**

    • @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); }

}

<a name="6LPew"></a>
#### Servlet 生命周期

- servlet何时创建何时销毁

Servlet中有init,service,destroy这几个方法称为是servlet的生命周期相关的方法

- Servlet第一次被访问的时候被实例化,只要Servlet一被实例化那么Servlet中的init方法就会执行(init只会执行一次)。任何一次从客户端发送来的请求,那么Servlet中的Service方法就会执行(在Service方法的内部根据请求方式不同调用不同doxxx方法)。当Servlet从服务器中移除或服务器关闭的时候Servlet对象被销毁,里面的destroy方法就会执行,然后垃圾回收就会将其回收掉。
- 生命周期代码
```java
package com.xx.servlet.demo;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ServletDemo2 implements Servlet {

    @Override
    /**    
     * Service从服务器中移除或者服务器关闭的时候销毁Servlet,执行一次
     */
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    /**
     *Servlet 对象被实例化的时候init方法就会执行,而且只执行一次。(Servlet是单例) 
     */
    public void init(ServletConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }
    /**    
     * Service方法:任何一次请求都会执行Service方法,可以执行多次
     */
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        // TODO Auto-generated method stub

    }





    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }

}
<servlet>
        <!-- 配置Servlet的名称 -->
        <servlet-name>ServletDemo2</servlet-name>
        <!-- 配置Servlet类的全路径 -->
        <servlet-class>com.xx.servlet.demo.ServletDemo2</servlet-class>
    </servlet>
    <!-- 配置Servlet的映射 -->
    <servlet-mapping>
        <!-- 配置Servlet的名称 -->
        <servlet-name>ServletDemo2</servlet-name>
        <!-- 配置访问路径 -->
        <url-pattern>/ServletDemo2</url-pattern>
    </servlet-mapping>

servlet 启动时加载

  • 让服务器启动的时候创建Servlet

    <servlet>
          <!-- 配置Servlet的名称 -->
          <servlet-name>ServletDemo3</servlet-name>
          <!-- 配置Servlet类的全路径 -->
          <servlet-class>com.xx.servlet.demo.ServletDemo3</servlet-class>
          <load-on-startup>2</load-on-startup> //启动优先级 越小越快
      </servlet>
    

    Servlet的访问路径

  • Servlet中的urlPattern的配置

  • 的配置方式

    • 完全路径匹配
      • 以 / 开始 比如:/ServletDemo1 /xx/ServletDemo2
    • 目录匹配
      • 以 / 开始 比如 / /aaa/ /aaa/bbb/*
    • 扩展名匹配
      • 不能以 / 开始,以开始 比如.action .do .jsp
        <servlet-mapping>
        <!-- 配置Servlet的名称 -->
        <servlet-name>ServletDemo3</servlet-name>
        <!-- 配置访问路径 -->
        <!--完全路径匹配 -->
        <url-pattern>/ServletDemo3</url-pattern>
        <!--目录匹配 -->
        <url-pattern>/aaa/*</url-pattern>
        <!--扩展名匹配 -->
        <url-pattern>/*.abc</url-pattern>
        </servlet-mapping>
        

        访问的优先级

        完全路径匹配 > 目录 > 扩展名匹配
        web.xml
        eclipse-win64.zip

        ServletConfig

  • 获得一些Servlet的相关配置

  • getServletConfig(); //获得ServletConfig对象
    • 获取Servlet初始化参数
    • 获取ServletContext对象
    • 获取Servlet的名称

初始化参数
配置

 <init-param>
             <param-name>username</param-name>
             <param-value>root</param-value>
          </init-param>
          <init-param>
             <param-name>password</param-name>
             <param-value>root</param-value>
     </init-param>

代码实现

package com.xx.Servlet.Demo;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ServletConfig
 */
public class ServletConfig extends HttpServlet {



    private javax.servlet.ServletConfig config;


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获得初始化参数的API
        //获得ServletConfig
        config = this.getServletConfig(); 
        //获得参数的值
        String uin = config.getInitParameter("username");
        String pwd = config.getInitParameter("password");

        System.out.println(uin +"----------"+pwd);

        //获取所有初始化参数的名称 枚举
        Enumeration<String> names = config.getInitParameterNames();
        while (names.hasMoreElements()) {//有更多的元素
            //获取初始化参数名称
            String name = names.nextElement();
            //获取初始化参数值
            String value = config.getInitParameter(name);
            System.out.println(name+"----------"+value);

        }

        //获取Servlet的名称
        String servletName = config.getServletName();
        System.out.println(servletName);
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);
    }

}

ServletContext

  • 用来获取Web项目信息 一个项目只有一个ServletContext对象 所以这个对象对整个项目的相关内容都是了解的。
  • 获取文件的MIME类型图片.png
  • 获取web项目请求工程名:图片.png
  • 获取web项目的初始化参数图片.png

    //获取文件的MIME的类型
          //ServletContext
          ServletContext servletContext = getServletContext();
          String mimeType = servletContext.getMimeType("aa.txt");
          System.out.printf(mimeType);
          //获得请求路径的工程名
          String contextPath = servletContext.getContextPath();
          System.out.printf(contextPath);
          servletContext.getInitParameter("");
          Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
          while (initParameterNames.hasMoreElements()){
              String s = initParameterNames.nextElement();
    
              String name = servletContext.getInitParameter(s);
              System.out.printf(name);
          }
    
  • 读取Web项目下的文件

    • 使用传统IO流无法读取文件
    • 使用ServletContext获取 ```java public void test(){ Properties pr = new Properties();
    try {
        String contextPath = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");//获取磁盘的绝对路径
        pr.load(new FileInputStream(contextPath));//传统IO加载db.properties
        pr.load(this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"));//获取db.properties的绝对路径
        String driverClassName = pr.getProperty("driverClassName");
        System.out.println(driverClassName);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

- ServletContext对象 作为域对象存取数据
   - 域对象API getAttribute获取数据 setAttribute获取数据 removeAttribute移除数据
   - 域对象作用范围 启动服务器开始 关闭服务器销毁  
- 本文件可以访问 其他文件也可以
```java
 public void init(){
        this.getServletContext().setAttribute("name","三三");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object name = this.getServletContext().getAttribute("name");
        response.getWriter().write((String) name);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object name = this.getServletContext().getAttribute("name");
        response.getWriter().write((String) name);
    }

response

响应行方法

  • 设置状态码 setStatus 获取状态码 getStatus

    • 200
    • 302
    • 304
    • 404
    • 500

      响应头方法

  • 设置响应头

    • setHeader setDateHeader setIntHeader
      • set开头:一个key对于一个value的情况
  • 追加响应头

    • addHeader addDateHeader addIntHeader
      • add开头:一个key对于多个value的情况

        响应体方法

  • 设置响应体

    • getOutputStream字节流 getWriter字符流
* 功能:设置响应消息
  1. 设置响应行
    1. 格式:HTTP/1.1 200 ok
    2. 设置状态码:setStatus(int sc) 
  2. 设置响应头:setHeader(String name, String value) 

  3. 设置响应体:
    * 使用步骤:
      1. 获取输出流
        * 字符输出流:PrintWriter getWriter()

        * 字节输出流:ServletOutputStream getOutputStream()

      2. 使用输出流,将数据输出到客户端浏览器


* 案例:
  1. 完成重定向
    * 重定向:资源跳转的方式
    * 代码实现:
      //1. 设置状态码为302
          response.setStatus(302);
          //2.设置响应头location
          response.setHeader("location","/day15/responseDemo2");


          //简单的重定向方法
          response.sendRedirect("/day15/responseDemo2");

    * 重定向的特点:redirect
      1. 地址栏发生变化
      2. 重定向可以访问其他站点(服务器)的资源
      3. 重定向是两次请求。不能使用request对象来共享数据
    * 转发的特点:forward
      1. 转发地址栏路径不变
      2. 转发只能访问当前服务器下的资源
      3. 转发是一次请求,可以使用request对象来共享数据

    * forward 和  redirect 区别

    * 路径写法:
      1. 路径分类
        1. 相对路径:通过相对路径不可以确定唯一资源
          * 如:./index.html
          * 不以/开头,以.开头路径

          * 规则:找到当前资源和目标资源之间的相对位置关系
            * ./:当前目录
            * ../:后退一级目录
        2. 绝对路径:通过绝对路径可以确定唯一资源
          * 如:http://localhost/day15/responseDemo2    /day15/responseDemo2
          * 以/开头的路径

          * 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
            * 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
              * 建议虚拟目录动态获取:request.getContextPath()
              * <a> , <form> 重定向...
            * 给服务器使用:不需要加虚拟目录
              * 转发路径

response 其他API

  • 重定向 sendRedirect
  • 设置字符集类型 setContentType
  • 设置响应字符流的缓冲区 setCharacterEncoding
  • 服务器向浏览器回写cookie addCookie
  • 页面定时跳转
<script type="text/javascript">
    var i = 5;
  function load(){
      window.setInterval("changeSeconds()",1000);
  }

  function changeSeconds(){
      i--;
    document.getElementById("span1").innerHTML=i;
  }
 </script>
 <body onload="load()">
   <h1>demo1.html</h1>
   <h3>页面将在<span id="span1">5</span>秒后跳转到demo2.html</h3>
</body>

中文乱码

response.setHeader("Content-Type","text/html;charset=UTF-8");//字节流输出中文

response.setHeader("Content-Type","text/html;charset=UTF-8");//字符流输出中文
response.setCharacterEncoding("UTF-8");
//简化
response.setContentType("text/html;charset=UTF-8");

文件下载

* 文件下载需求:
  1. 页面显示超链接
  2. 点击超链接后弹出下载提示框
  3. 完成图片文件下载


* 分析:
  1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
  2. 任何资源都必须弹出下载提示框
  3. 使用响应头设置资源的打开方式:
    * content-disposition:attachment;filename=xxx


* 步骤:
  1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
  2. 定义Servlet
    1. 获取文件名称
    2. 使用字节输入流加载文件进内存
    3. 指定response的响应头: content-disposition:attachment;filename=xxx
    4. 将数据写出到response输出流


* 问题:
  * 中文文件问题
    * 解决思路:
      1. 获取客户端使用的浏览器版本信息
      2. 根据不同的版本信息,设置filename的编码方式不同

request

开发软件的都是B/S结构软件,从浏览器向服务器提交一些数据,将这些内容进行封装就封装成了一个请求对象(Request 对象)。

获得客户机信息

  • 获得请求的方式 getMthod
  • 获得请求路径后的提交参数的字符串 getQueryString
  • 获得请求路径 getRequestURL getRequestURI
  • 获得客户端的ip地址 getRemoteAddr

    获得请求头

  • 获得一个key对应一个value的请求头 getHeader

  • 获得一个key对应多个value的请求头 getHeaders

    获得请求参数

  • 获得提交参数(一个name对应一个value)getParameter

  • 获得提交参数(一个name对应多个value)getParameterValues //用于爱好多参数等等。
  • 获得提交参数(将提交的参数的名称和对应的值存入到一个Map集合中)getParameterMap

    request域对象

  • 域对象API getAttribute获取数据 setAttribute获取数据 removeAttribute移除数据 ```java //获得客户机信息 request.getMthod(); request.getQueryString(); request.getRequestURL(); request.getRequestURI();

//获取客户机请求头 request.getHeader(“User-Agent”);//获得浏览器标识

//获取请求参数 request.getParameter(“name”); request.getParameters(“names”);

request.getParameterMap();

<a name="o4STF"></a>
#### request接受数据中文乱码
> 将request的缓冲区编码修改即可 post
> 将存入到request缓冲区中的值以ISO-8859-1的方式获取到,再以UTF-8解码即可 get

```java
//POST
request.setCharacterEncoding("UTF-8");//设置request缓冲区 

//GET
URLEncoder.encode(name,"ISO-8859-1");
URLDecoder.decode(encode,"UTF-8");

String value = new String(name.getBytes("ISO-8859-1"),"UTF-8");//String构造方法 转换中文存储

会话技术

Cookie

Cookie是客户端技术,程序把每个程序的数据以cookie的形式保存到各自浏览器中,当用户使用浏览器再次访问服务器中的web资源的时候,就会带个各自的数据过去,这样web资源处理的就是用户各自的数据了

  • 客户端 setCookie
  • 默认级别的Cookie
    • 指的是没有设置有限时间的Cookie,默认的情况下只要关闭了浏览器,Cookie也会被销毁。(Cookie 存在于浏览器的内存中,当关闭了浏览器Cookie就销毁了)
  • 持久级级别的Cookie
    • 指的是有有时间的Cookie,这种Cookie的内容不是保存在浏览器的内存中,将Cookie的内容保存(持久化)到硬盘上,关闭浏览器,再次打开就会加载硬盘上的文件,从而Cookie中的数据就不会丢失
  • Cookie 的API
    • 设置Cookie名称的方法 setName()
    • 设置Cookie值的方法 setValue()
    • 设置Cookie有效域名的方法 setDomain()
    • 设置Cookie有效路径的方法 setPath()
    • 设置Cookie有效时长的方法 setMaxAge()

记录用户上次访问时间

  • 思维导图 JavaWeb - 图4

    代码实现

  • 通过HttpservletRequest对象中的方法

    • getCookies() 获取Cookie addCookies 回写Cookie

VisitServlet

/**
 * 用户访问Servlet
 *  * 如果第一次访问
 *      * 显示 您好,欢迎来到本网站
 *      * 记录当前访问时间,存入Cookie,回写到浏览器
 *  * 如果不是第一次访问
 *      * Cookie中获得上次时间,显示到页面
 *      * 记录当前访问时间,存入到Cookie,回写到浏览器
 * */
package com.xx.Servlet;

import com.xx.Utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet("/VisitServlet")
public class VisitServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        Cookie cookie = CookieUtils.findCookie(cookies,"lastVisit");
        if (cookie == null){

            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("<h1>您好,欢迎来到本网站!</h1>");
        }else {
            String value = cookie.getValue();
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("<h1>您上次访问时间为"+value+"!</h1>");
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date d = new Date();
        System.out.println(d.toLocaleString());
        Cookie c = new Cookie("lastVisit",d.toLocaleString());
        c.setPath("/");
        c.setMaxAge("60*30");
        response.addCookie(c);
    }
}
  • Cookie工具类 ```java package com.xx.Utils;

import javax.servlet.http.Cookie;

public class CookieUtils {

/**
 * Cookie工具类
 * */

public static Cookie findCookie(Cookie[] cookies,String name){
    if (cookies == null){
        return null;
    }else {
        for (Cookie cookie : cookies) {
            if (name.equals(cookie.getName())){
                return cookie;
            }
        }
        return null;
    }
}

}

<a name="hVSPF"></a>
#### 注意!!!

设置Cookie  Http:  Cookie值中存在无效字符
```xml
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />

Session

Session是服务器技术,利用这个技术,服务器在运行时为每一个用户的浏览器创建一个独享的Session对象,由于session为用户浏览器独享,所有用户在访问服务器的时候,可以把各自的数据放在各自的session中,当用户再次访问服务器中的web资源的时候,其他web资源再从各自的session中取出数据为用户服务。

  • 服务器端 利用唯一ID
  • Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到Session对象
  • Session 作为域对象的API
    • 向Session存入数据 setAttribute()
    • 从Session域中获取数据 getAttribute()
    • 从Session域中移除数据 removeAttribute()
  • Session作为域对象的作用范围

    • Session作为域对象,作用范围就是一次会话的范围。一次会话,指的是用户打开浏览器点击多个超链接,访问服务器资源,到最好关闭浏览器的过程。

      Cookie和Session区别

      Cookie局限性

    • Cookie保存的数据是有个数和大小的限制的

    • 数据是保存客户端浏览器上(相对不是很安全)

      Session

    • Session没有个数和大小的限制

    • 数据是保存在服务器上(相对比较安全)

      Servlet的数据范围

      请求范围(ServletRequests)

  • 何时创建和销毁的

    • 创建:当用户向服务器发送一次请求,服务器创建一个requset对象。
    • 销毁:当服务器对这次请求作出了响应,服务器就会销毁这个request对象。
  • 如何存取数据
    • 存数据:
      • void serAttribute(String name,Object value)
    • 取数据
      • Object getAttribute(String name)
  • 作用范围

    - 作用范围:一次请求。(转发就是一次请求)
    

    会话范围

  • 何时创建和销毁的

    • 创建:服务器端第一次调用getSession()方法的时候
    • 销毁:三种情况
      • Session过期,默认的过期时间 30分钟
      • 非正常关闭服务器(正常关闭服务器-Session会被序列化)
      • 手动调用 session.invalidate();
  • 如何存取数据
    • 存数据:
      • void serAttribute(String name,Object value)
    • 取数据
      • Object getAttribute(String name)
  • 作用范围

    • 作用范围:一次会话。(转发就是多次请求)

      应用范围

  • 何时创建和销毁的

    • 创建:启动服务器的时候创建,为每个Web项目创建一个单独的SerlvetContext对象。
    • 销毁:服务器关闭的时候,或者项目从服务器中移除的时候
  • 如何存取数据
    • 存数据:
      • void serAttribute(String name,Object value)
    • 取数据
      • Object getAttribute(String name)
  • 作用范围
    • 作用范围:整个应用

      Filter

  1. Filter过滤器
  2. Listener:监听器

    Filter过滤器

  • 概念
    • 生活中的过滤器:净水器,空气净化器,土匪
    • web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
    • 过滤器的作用:
      • 一般用于完成通用操作,如:登录验证,统一编码处理、敏感字符过滤...
  • 快速入门
    • 步骤:
      • 定义一个类,实现接口Filter
      • 复写方法
      • 配置拦截路径
        • web.xml
        • 注解
          ```java

@WebFilter(“/*”) //注解 配置拦截路径 public class DemoFilter implements Filter { public void destroy() { }

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    //对request进行增强

    //放行资源
    chain.doFilter(req, resp);

    //对response行增强
}

public void init(FilterConfig config) throws ServletException {

}

}


- 过滤器细节
   - web.xml配置
```xml
    <filter>
        <filter-name></filter-name>
        <filter-class></filter-class>
    </filter>
    <filter-mapping>
        <filter-name></filter-name>
        <url-pattern></url-pattern>
    </filter-mapping>
  • 过滤器执行流程 ``` //对request进行增强

//放行资源 chain.doFilter(req, resp);

//对response行增强


   - 过滤器生命周期方法
      - init:_在服务器启动后,会创建Filter,然后调用init方法,只执行一次_
      - destory:_在服务器关闭后,Filter对象被销毁,如果服务器是正常关闭,则会执行destroy方法_
      - _doFilter:每一次请求被拦截资源时,会执行多次_
   - 过滤器配置详解
      - 拦截路径配置:
         - 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
         - 拦截目录:  /user/*  访问/user下的所有资源时,过滤器都会被执行
         - 后缀名拦截: *.jsp 访问所有后缀名为jsp时,过滤器都会被执行
         -  拦截所有资源: /*  访问所有资源时,过滤器都会执行
      - 拦截方式配置:资源被访问的方式 
         - 注解配置 
            - 设置DispatcherType属性
               - REQUEST:默认值。浏览器直接请求
               - FORWARD:转发访问资源
               - INCLUDE:包含访问资源
               - ERROR:错误跳转资源
               - ASYNC:异步访问资源
```java
@WebFilter(value = "/*",dispatcherTypes = DispatcherType.FORWARD)//注解配置
     - web.xml配置
  • 过滤器链(配置多个过滤器)