JAVAWeb学习

知识大纲:

一、掌握Web应用服务器

二、发布部署Web项目

三、JSP的基础学习

四、JSP的应用

一、Web应用及服务器

1、Web应用前提

在之前的页面开发中,我们所有信息的直接放置在网页上,通过浏览器即可查看,这样的页面无法与数据库交互,我们称之为 “静态网页” ,如果需要将数据实时更新,那么需要在此基础上做动态应用程序,且通过浏览器或客户端访问服务器的应用,我们称之为 “web应用 ”

2、Web应用的架构

2.1 客户端与服务器架构 :Client/ Server 例如大型网络游戏 (下载客户端程序并安装) 、QQ 、PC 微信 等

2.2 浏览器与服务器架构 : Browser/Server 例如 百度 ,京东,CSDN 等企业门户网站

2.3 移动设备端 : App应用 百度App 淘宝App等

区别 C/S B/S( 重点)
客户端请求 需要按照客户端 不需要安装,浏览器即可
访问速度 相对较快 相对更多依赖网速 稳定性受影响
页面美化 cs特效更多 设计比较固化
维护成本 维护成本高 维护成本较低

无论使用哪一种架构都需要服务器支持,所以想要搭建一个系统,一定需要Web服务器的支持

3、Web服务器

3.1定义:

用于运行web应用程序的中间件 ,这里的中间件大多数是开源的

常用的Web服务器: WebLogic 、IIS 、Apache 、Apache Tomcat 、Nginx(服务器反向代理、静态资源服务器,分布式应用负载均衡)

初学者 建议使用 Apache Tomcat(简称Tomcat) 版本: Tomcat8, 9

来源: https://tomcat.apache.org/download-80.cgi Tomcat8.5.61 解压后目录

3.2 Tomcat目录结构

​ |- bin : 存放Tomcat启动、关闭等批处理文件, 启动服务 startup.bat 、startup.sh 关闭服务: shutdown.bat shutdown.sh catalina.bat 核心启动文件

​ |- conf: 存放配置文件

  • ​ server.xml (修改端口号) 默认端口号8080

       <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
  • ​ tomcat-user.xml 定义Tomcat的访问用户(角色和权限控制)

​ 将如下代码放入在 中

 <role rolename="manager-gui"/>
 <user username="zhangsan" password="123456" roles="manager-gui"/>
  • ​ web.xml : Tomcat 的核心配置文件

|- lib : 存放Tomcat需要的 jar包

|- logs: 服务器运行的日志包 (默认一天一个日志文件)

|-temp : 存放用户临时文件

|-webapps: 存放项目的文件夹 (你的项目放在这里 )

|-work: 项目在运行期间,存放系统临时生成的文件 或 jsp生成的java类缓存文件

3.3 启动服务器

​ 在启动之前需要确保已配置 JAVA_HOME 环境变量

​ %JAVA_HOME% C:\Program Files\Java\jdk1.8.0_144

​ 启动服务 : 在bin目录下 startup.bat

访问服务器: http://localhost:8080/

访问自己的项目: 首先要确保项目在webapps下已存在

项目地址 : http://localhost:8081/项目名/页面名

二、IDEA中发布并运行项目

参考文档: https://www.cnblogs.com/guchenglin/p/10568279.html

步骤1: 新建一个Web Project 是Empty Project, 你的项目作为一个模块

步骤2 : 新增模块 Module (你的模块名 ,模块属于项目的)

注意这里需要 再选择一个 Web Application ,添加Web基础组件 会自动生成 web.xml 文件

新建好的项目如下:

1607571218565

步骤3: 新建 classes文件夹 和 lib文件夹 ,其中classes用于存放java文件的类文件

​ lib用于存放项目的jar包

步骤4: 配置Tomcat服务器 并发布项目

server的基本配置:

步骤5:启动服务器

访问地址 : http://localhost:8081/JSP01/

能正常打开,说明 服务器部署完成。

对于服务器启动 信息控制乱码解决方案:

三、 JSP基础

1、JSP的定义

​ 在web项目中可以运行动态网页技术,JSP就是其中之一的动态网页技术

​ JSP 全称 Java Server Pages( Java 服务器端页面 ) ,用于开发动态网站

​ JSP 是 sun公司开发的基于 服务器端运行的 web技术 ,JSP的最终可生成对应的 Java类 ,

​ 以.jsp结尾的文件

2、 JSP的基础元素中包括如下

2.1 jsp表达式:

​ 以 <%= 开始 以%>结束, 可计算表达式的结果并输出

2.2 jsp小脚本 :

​ 以<% 开始 以%> 结尾,中间可以写任意java片段代码

    <%
         int  num1 =1;
         int num2 =2;
         System.out.println("两个数之和:"+(num1+num2));  //控制台输出
		out.print("页面输出:"+(num1+num2));  // 等价于  <%=num1+num2%>
    %>

2.3 jsp声明 :

以<%! 开头 以%>结尾; 声明主要用于定义变量和方法 ,不能直接写java片段

  <%! 
      //定义全局变量
      
      // 定义 方法
  %>

2.4 jsp注释

<%-- 注释内容--> 与网页注释 ,区别在于网页注释可直接在浏览器源代码中查看 ,而jsp注释是服务端注释

2.5 jsp指令:

语法 以<%@开头 以%>结尾 , 包括3个指令

​ a、<%@ page 属性名=属性值 .... %> jsp页面指令,用于定义jsp页面的基本属性

​ 常用属性: contentType = text/html;charset=UTF-8 设置页面编码格式和内容类型

​ pageEncoding :设置页面编码格式 (优先级高)

​ language="java" :设置脚本语言

​ import="java.util.*" :导入java的引入包和类 多个用逗号隔开,或者单独写多个import

​ errorPage=“error.jsp" 当页面异常,可跳转指定页面

					isErrorPage="false" :判断是否为错误页面 ,用于错误页面的 异常对象使用 
<%--  当 指令中的属性 isErrorPage = true 时,该exception才可用--%>
  <%--<%= exception.getMessage()%>--%>

​ b、 <%@ include file="url" %> 可以包含一个页面,可用于动态页面的嵌套。

   <%-- 引入页面头--%>
    <%@ include file="header.jsp"%>

​ 该支持称为jsp的静态包含,在页面运行之前将两个页面合二为一。 注意两个页面中不能定义相同变量和方法。

​ c、<%@ taglib 属性名 = 属性值 > : 导入jstl标签的指令 后续使用是再演示

2.6 jsp动作:

​ 动作格式 <jsp: 动作名 属性名= 属性值 />

​ 例如:<jsp:include page="header.jsp"/> 也可以 包含指定页面,向比jsp include指令,它是在运行中动态查找该页面,并加重 ,会header.jsp预先编译 。

面试题:

​ 面试题1: contentType与pageEncoding的区别?

​ pageEncoding : 表示页面的自身编码(UTF-8) ,contentType: 服务器响应给客户端时 发送的内容的编码格式(包括发送的内容格式)

练习: 定义一个jsp页面, 定义圆的半径,编写方法,计算圆的面积 和 周次,并在页面上输出

3、JSP的运行原理

​ JSP作为动态web页面,其自身在服务器生成一个对应的java文件

  • JSP源码分析得出结论

    1、jsp页面在访问时,会自动转成 java类,其类名 jsp名称_jsp.jar (例如 hello.jsp -> hello_jsp.java) , 再编译成 class文件 里面所有的网页标签都通过 out写出流 发送给客户端 ,并设置文件内容类型mine格式为 text/html ,客户端才可以通过浏览器直接打开

2、 jsp中的 小脚本代码 全部放在 _jspService方法中

3、jsp中的 声明 全部是全局方法 或全局变量

4、jsp中所有的表达式 都是 基于_jspService方法中的 输出 out.print

我们还看到了 _jspService 方法中 提供了很多很多的对象 可直接使用, request 、response 、 out等

这些就是jsp中的内置对象

  • JSP的运行原理

1、当客户端第一次发送请求时,由于请求的后缀.jsp , 服务器会自动将请求的jsp转义成java类并编译成class文件(第一访问较慢) ,存放在 C:\Users\wuyafeng.IntelliJIdea2018.2\system\tomcat\Unnamed_JavaWebPro\work\Catalina\localhost 中 , 并执行 _jspService方法,向请求数据 通过 out对象响应给客户端

public void _jspService(final HttpServletRequest request, final HttpServletResponse response)
   
    final PageContext pageContext;
    HttpSession session = null;
    final ServletContext application;
    final ServletConfig config;
    JspWriter out = null;
    final Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;
    .........

}

2、当客户端再次访问该请求(.jsp结尾),服务器先检查是否存在对应的 java类,如果存在则直接更新内容后返回给服务器,如果不存在就重写 创建java类

四、JSP的内置对象

内置对象 定义:

​ 在JSP中不需要 创建就可以直接使用的对象称为内置对象(隐式对象), 通过源码分析,JSP提供了9大内置对象

1、输入输出对象 : request 、 response 、 out

2、作用域通信对象: pageContext、 session 、 application (request既是输入输出对象也是通信对象 )

3、Servlet对象: config 、page (表示当前jsp页面对象 等于 this )

4、异常对象: exception

1、request 请求对象 ,response响应对象 :

​ 一个正常的web交互流程: 客户端发送请求, 服务器作出相应 , 服务器可以接收到客户端 的请求数据,该数据的来源从request对象中获取
对象来源: javax.servlet.http.HttpServletRequest request

案例一: 模拟用户注册功能

<%
    //设置请求编码格式
    request.setCharacterEncoding("UTF-8");

    // 获取客户端提交的数据   通过request内置对象
   String username =  request.getParameter("username");  //  通过请求参数的 name属性
    String password = request.getParameter("password");
    //获取重复密码
    String repassword = request.getParameter("repassword");
    //获取性别
    String sex = request.getParameter("sex");
    //获取
    String[] hobby = request.getParameterValues("hobby");
    //获取来源
    String source = request.getParameter("source");

    out.print("您注册的用户名:"+username);
    out.print(" 密码:"+password);
    out.print(" 重复密码:"+repassword);
    out.print("性别:"+sex);
    out.print("爱好:"+ Arrays.toString(hobby));
    out.print("信息来源:"+source);
%>

如果本次注册 两次密码不一致 ,提示 注册失败 如果正确,则提示注册成功

页面与页面之间的跳转流程 :

关于重定向和转发的区别 :

共同点: 它们都具有页面跳转的功能

1、重定向由response完成, 转发由request完成

​ 2、 重定向是一次新的请求,在客户端完成 有2次请求 (意味着不能获取表单初始提交的数据) , 转发是服务器内部的转发,只有一次请求,无论怎么跳转 都可以获取原始请求的参数

3、重定向可以跨域跳转,转发只能在服务内部访问资源

2、作用域通信对象

为什么会需要作用域通信对象?

由于浏览器与服务器之间是基于HTTP协议的交互 ,而HTTP是面向无连接协议(无状态)协议

所谓面向无连接就是浏览器发送请求,服务器响应完成,这个过程是独立的,等下一次再次发送请求时无服务无法知道该请求的状态,无法获取上一次的请求数据 ,如何服务器需要获取之前请求的数据,就迫切需要一个用于存储请求响应数据的“容器” ,这个“容器”存在服务器读书那 ,只要在指定范围类的操作,服务器就可以获取客户端的数据。

作用域通信对象根据使用的范围不同, 可分为 四类 :

作用域对象 作用范围

pageContext 存储的数据在当前页面中可以获取

​ request 一次请求

​ session 一次会话 (多次请求)

application 整个应用程序

这四个作用域都提供 setAttribute("key" ,Object) ; 设置 key -value

​ getAttribute("key") : 获取指定的key (一定满足对应的作用范围)

​ removeAttribute("key"); 删除容器中指定的 key

结论: 如果在页面跳转中 ,使用转发,那么你的作用域最少使用 request对象存 数据

​ 如果在页面跳转中,使用重定向,那么你的作用域最少使用session对象 ,不能使用request,

转发:

​ 存值: request.setAttribute(key,value)

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

重定向

存值 : session.setAttribute(key,value);

​ response.sendRedirect(url);

案例1:在线访问量

五、Servlet技术

1、Servlet定义

Servlet是由Java编写的用于处理客户端请求和响应的web服务器组件 ,Servlet是JavaWeb的基础组件

2、Servlet 特点

​ 2.1 Servlet本事由Web容器(简称Servlet容器)管理

​ 2.2 Servlet是比JSP更早的动态web网页技术

​ 2.3 Servlet不能单独运行,需要由Servlet引擎来控制启动和调度

​ 2.4 Servlet属于一个插件, 内部定制一些常用方法,例如 service ,init ,doGet ,doPost等

3、Servlet的使用

步骤一: 定义一个Java类 ,继承 HttpServlet类(抽象类,不能实例化)

步骤二: 重写该类的 doGet方法、doPost方法( 根据请求类型决定调用哪一个方法)

  /**
     *
     * @param req  请求对象
     * @param resp 响应对象   类似之前jsp的 request,response对象
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req,
                         HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应给客户端的编码格式
        resp.setContentType("text/html;charset=UTF-8");
        //获取输出对象
        PrintWriter out = resp.getWriter();
        out.print("<h2>这是我的第一个Servlet程序</h2>");

        out.close();

    }

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 由于不知道请求方式是 get 还是post 所以可以在两个方法中都执行相同的代码
        this.doGet(req,resp);
    }

步骤三: 在web.xml 中 配置Servlet的url请求 ,以便客户端可以直接方法

    <!-- 配置MyServlet请求-->
    <servlet>
        <servlet-name>myServlet</servlet-name>  <!--自定义名称,在整个项目中唯一  通常写类名首字母小写-->
        <servlet-class>com.softeem.web.MyServlet</servlet-class> <!--Servlet的类路径 -->
    </servlet>
    <servlet-mapping>
        <servlet-name>myServlet</servlet-name>  <!-- 指定的Servlet的name标签 -->
        <url-pattern>/my</url-pattern>     <!--一定以 / 开头,表示从当前项目下找Servlet  -->
    </servlet-mapping>

步骤四: 测试 请求

http://localhost:8081/Servlet01/my

Servlet的运行原理:

​ 所有servlet类都由Servlet容器统一管理,每一个Servlet类在整个容器中只创建一个实例,默认将web.xml中的 url-pattern 作为key ,其value是对应的servletclass的路径

​ 当客户端第一次请求路径是时/my ,Servlet容器会自动从已初始化的 key-value结构中 找 是否存在对应的key (/my) ,如果存在,则找到对应的servlet class类 ,并创建MyServlet实例,如果不存在返回404

​ 再判断 该请求是get请求还是post请求,并执行doGet或doPost方法 ,最后响应给客户端。

​ 当下一次请求该Servlet时,不需要再次创建对象,而直接执行doGet或doPost方法。

4、Servlet的生命周期

由于Servlet对象在整个Servlet容器中只有一个,我们需要研究Servlet从创建到销毁的整个过程,以便更深刻掌握Servlet组件, 这里 Servlet生命周期表示 它从创建到销毁的完整过程。

1、加载Servlet类 并实例化对象

2、初始化Servlet ,调用init方法

3、提供服务,调用service方法, 由service方法决定调用doGet 或doPost ,对于每一次请求都会执行service方法

4、销毁 ,调用destroy方法

//给该类添加Servlet配置 ,  urlPatterns指定访问路径,必须以/开头,如果有多个路径,可以指定数组形
    //urlPatterns ="/circleServlet"
    // loadOnStartup =正整数 ,表示容器启动就实例化和初始化     默认-1

@WebServlet(urlPatterns = {"/circleServlet","/circleServlet2"},loadOnStartup  =1)
public class CircleServlet extends HttpServlet {    
// 实例化
      public CircleServlet(){
          System.out.println(this.getClass().getName() +" =========");
      }

    @Override
    public void init() throws ServletException {
        System.out.println("Servlet正在初始化。。。。  init");
    }

    @Override
    protected void service(HttpServletRequest req,
                           HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet 正在提供服务。。。。。 service");

         resp.setContentType("text/html;charset=UTF-8");
         PrintWriter out = resp.getWriter();
         out.print("<h1>测试Servlet生命周期</h1>");

         out.close();
    }

    @Override
    public void destroy() {
        System.out.println("正在调用 销毁 方法。。。。 destroy");
    }

总结: 默认Servlet在第一次请求时,创建Servlet实例, 并执行init方法初始化信息 , 然后调用service方法 (内部调用doGet doPost方法)

​ 当再次请求servlet 时,直接执行service方法

​ ......

​ 最后容器销毁时,自动执行destory方法 。

案例一: 使用JSP+Servlet完成登录案例

定义login.jsp 表单提交到 LoginServlet ,处理完毕之后,登录成功跳转 success.jsp ,登录失败返回login.jsp

5、Servlet的关系分布图

所属的包 javax.servlet.*

6、 Servlet中的核心对象 :

1、请求对象:

核心接口: javax.servlet.http.HttpServletRequest

​ 实现类: javax.servlet.http.HttpServletRequestWrapper

​ 它的父接口: javax.servlet.http.ServletRequest

常用方法:

1.1 请求头相关方法

​ getContextPath() : 请求的上下文路径 (/项目名 或者 /)

​ getCookies() : 返回客户端请求中包含的所有Cookie数组

​ getHeader() : 返回请求头部信息

​ getHeaderNames() : 返回请求头的名称的 枚举类型

​ getHeaders (name) : 返回指定的头信息的枚举类型

​ getMethod() : 返回请求的类型 (get/post)

​ getQueryString() : 返回url中?后面的查询参数,以字符串形式返回

1.2 客户端信息 (id,端口,主机名)

​ getRemoteAddr() : 获取客户端的IP

​ getRemotePort():获取客户端的端口

​ getRemoteHost() : 获取客户端的主机名

1.3 获取服务器信息

​ getLocalName() : 获取服务器的主机名

​ getLocalPosr() : 获取服务器的端口号

1.4获取请求参数相关的:

​ getParameter(name) : 获取请求参数名的value

​ getParameterValues() :获取请求参数的values值 ,

​ getParameterMap() : 获取请求参数的所有key-value ,返回Map集合

​ getParameterNames() : 获取请求参数的 name属性。 返回枚举

1.5获取请求的输入流 (用于文件上传的 IO流)

​ getInputStream() : 获取请求的数据流

​ getContentLength (): 获取请求的内容的长度

1.6 编码格式相关:

​ setCharacterEncoding("") : 获取请求参数

​ getCharacterEncoding()

1.7 与数据存储相关的

​ setAttribute(key,value)

​ getAttribute(key)

​ getAttributeNames() : 获取所有存储的 key的值 ,(根据key可以获取value)、

​ removeAttribute(key) : 移除指定的key

1.8与url相关

	 **getRealPath**() :  过时 ,  获取当前请求servlet的 绝对路径 

​ getRequestURI() : 请求地址的 部分路径

​ getRequestURL() : 请求地址的完整路径

​ getServletPath() : 请求的Servlet的路径

2、响应对象

用于处理客户端响应对象

核心接口: javax.servlet.http.HttpServletResponse

实现类: javax.servlet.http.HttpServletResponseWrapper

父接口: javax.servlet.ServletResponse

响应状态码:

200: 请求成功

302:指示已经将资源暂时地移动到了另一个位置

404:请求找不到资源

405:请求方法不对,例如get请求 服务器使用doPost()处理或者 post请求时,服务却使用doGet()处理

500:服务器内部错误

502:坏的url链接 无响应

503:服务器过载错误

常用方法:

​ getWriter() : 获取字符输出流

​ getOutput Stream() :获取响应字节输出流(输出图片对象,pdf 等)

addCookie(Cookie) : 添加cookie对象给客户端

getContentType(): 获取内容类型

setContentType(): 设置输出内容的类型

getCharacterEncoding(): 获取响应编码格式

setCharacterEncoding() : 设置响应编码格式

案例一: 使用响应对象 完成验证码功能

7、HttpSession对象

​ 该对象表示服务器与客户端的会话对象 (session对象)

1、为什么需要会话对象?

​ 由于http请求是无状态无连接协议,当客户端第一次访问服务器时,服务器给予响应之后就不再由任何联系 ,但是实际web项目中,服务器是需要记录客户端的访问和存储用户数据的,服务器也需要识别该客户端之前是否访问过。 所以就需要针对 每一个访问的客户端在服务器端创建一个存储数据的空间,并记录该用户信息,这就可以使用会话机制实现。

2、如何创建会话以及会话机制的实现原理

​ 会话的实现原理:

​ 基于Cookie对象的jsessionid变量 ,当第一次访问服务器时,请求头中的jsessionid为空,服务器会创建新会话并通过响应头返回给客户端,并返回jsessionid。 这里可以存储用户数据

​ 当下一次访问是,客户端将请求头的jsessionid 访问服务器,服务器先判断该jsession是否过期,如果已过期,又重写创建会话对象并返回,如果服务器存在jseessionid的对象,则可直接获取该对象中用户存储的数据。

​ 这样可以保证客户端与服务器之间来回交互并识别该用户数据。

问题: Session的会话实现机制是依赖Cookie的吗? 如果客户端禁用Cookie还能使用Session吗?

回答:是依赖Cookie ,但是如果Cookie禁用也能正常使用Session ,可以将jsessionid 通过url传参的方法解决。 例如: url?jsession=6383CB7CF767B090DB6E0D78B75E1996

案例1、使用session完成7天免登录

3、Session过期时间修改的三种方式

​ Session的默认过期时间是30分钟, 可以修改该时间

方式1: 在当前类的代码中修改,作用范围只对访问当前类的会话生效

HttpSession session = req.getSession();
session.setMaxInactiveInterval(秒 )

方式2: 在当前项目的web.xml中配置 session的过期时间 ,作用范围对整个项目有效

   <!-- 修改当前项目的session时间-->
    <session-config>
        <!-- 单位是分钟-->
        <session-timeout>30</session-timeout> 
    </session-config>

方式3:在web服务器的核心配置文件中设置session过期时间 ,作用范围对当前服务器下的所有项目有效

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

8、Servlet的配置对象和Servlet的上下文对象

​ Servlet的配置对象用于配置当前servlet的参数,获取参数 ,作用范围只对当前Servlet有效

而Servlet的上下文对象用于配置所有Servlet的参数 ,获取参数,作用范围是针对当前项目的所有Servlet对象 ,。

Servlet配置对象来源: javax.servlet. ServletConfig -> 等价于 JSP的内置对象 config

<servlet>
        <servlet-name>testConfigServlet</servlet-name>
        <servlet-class>com.softeem.web.TestConfigServlet</servlet-class>
        <!-- 设置配置参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>zhangsan</param-value>
        </init-param>
    </servlet>
      // 获取当前Servlet的配置对象
        ServletConfig config =this.getServletConfig();
        // 获取当前Servlet存储的参数
        String username = config.getInitParameter("username");
        System.out.println("获取当前类配置信息  username :"+ username );

Servlet上下文对象来源: javax.servlet.ServletContext -> 等价于JSP的内置对象 application

案例: 初始化参数

<!--  配置上下文参数  配置在 servlet节点的外面 -->
    <context-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </context-param>
</web-app>
  // 2、获取上下文的配置对象.getContextPath()
        ServletContext context = this.getServletContext();
        //上下文对象用于 与 Servlet 容器通信,可存储公共的信息  和 获取公共信息
        String encoding = context.getInitParameter("encoding");
        System.out.println( "获取上下文配置信息 encoding:" + encoding);
        // 存储信息
        context.setAttribute("encode",encoding);

9、Cookie对象

​ Cookie是存储在浏览器端的一小段文本,当服务器响应给客户端时,服务器存储在浏览器端的数据保存在Cookie中, 用于服务器对浏览器的识别

​ Cookie的应用场景

​ 1、记住用户

​ 2、缓存用户浏览记录(url)

​ 3、免登录功能

Cookie的创建和使用

来自javax.servlet.http.Cookie对象 ,存储字符串信息

 Cookie  cookie = new Cookie(String name , String value);
 // 由响应对象返回给客户端 
 resp.addCookie(cookie);

常用方法: getName() 获取当前Cookie的 name

​ getValue() 获取当前Cookie的value

​ setMaxAge(秒) 设置Cookie的最大存活时间, 到达时间后自动销毁

​ 正数: 指定时间后Cookie过期

​ 负数或0 : 在浏览器端不写Cookie ,浏览器关闭Cookie消失

​ getMaxAge() :获取Cookie的最大存活时间

获取请求Cookie对象

Cookie []  cks =  req.getCookies() ;
// 由于浏览器中可存储多个Cookie 

案例 Cookie完成 “记住我” 功能

页面:

  // 登录 提交
      $("#btnLogin").click(function(){
          // 获取用户名
          // 密码
          // 记住我
          var uname = $("[name=username]").val();
          var password = $("[name=password]").val();
          var remember = $("[name=remember]").val();

            // 判断 是否选中  选中就是 yes  不选中 其他
          if($("[name=remember]").is(":checked")){
             remember='yes';
          }

          //发送ajax请求
          $.ajax({
             type:'post',
             url:'login2Servlet',
             data:"uname="+uname+"&password="+password+"&remember="+remember,
             success:function(res){
                 // 可以接收一个json对象
                if(res.status=='0'){
                    alert(res.msg);
                    location.href="success.jsp";
                }else{
                    alert(res.msg);
                }

             },
              dataType:"JSON"
          });

      });
     if("admin".equals(uname) && "123".equals(password)){
            // 记住我功能
            if("yes".equals(remember)){
                 //创建Cookie  将Cooki给 客户端
                Cookie ck1 = new Cookie("username",uname);
                        //设置ck的生命周期
                ck1.setMaxAge(5*60);;
                Cookie ck2 = new Cookie("remember","yes");
                ck2.setMaxAge(5*60);
                //响应给客户端
                resp.addCookie(ck1);
                resp.addCookie(ck2);
                // 这里也可以使用Cookie 完成免登录功能 (7天免登录 ) 设置Cookie的生命周期7天
            }else{

                Cookie ck2 = new Cookie("remember","no");
                ck2.setMaxAge(5*60);
                resp.addCookie(ck2);
            }
            // {"status":"0","msg":"登录成功"}
            out.print("{\"status\":\"0\",\"msg\":\"登录成功\"}");
        }else{
            //{"status":"1","msg":"用户名或密码错误"}
            out.print("{\"status\":\"1\",\"msg\":\"用户名或密码错误\"}");

        }

该代码可以写在 login页面的前置Servlet中

<% // 获取客户端请求的Cookie
        String username="";
        String remember ="";
      Cookie [] cks =  request.getCookies();
         if(cks !=null){
             for(Cookie ck : cks){
                  //获取所有的name  value
                 if(ck.getName().equals("username")
                 && !"".equals(ck.getValue())){
                     username = ck.getValue();
                 }
                 if(ck.getName().equals("remember")){
                     remember = ck.getValue();
                 }
                 // 如果免登录 直接跳转 success.jsp
             }
         }

         if("no".equals(remember)){
             username="";
         }

    %>

面试题:

Cookie和Session的区别

1、 Cookie存储在客户端, Session存在服务器端

2、Cookie只能存文本字符串 ,Session可以存对象

3、Session的实现机制是依赖Cookie, 如果Cookie被禁用,可以使用URL传参的方式启动Session

4、Cookie 不安全 用于存在不太重要的信息 ,Session 安全 存储重要信息,session会占用服务器资源

作业1 :完成 Cookie的7天免登录功能

六、过滤器

1、过滤器的定义

​ 在Javaweb的请求响应中,提供一种功能可以在请求到达之前和 响应客户端之后 执行某些任务 , 可通过过滤器组件定制

​ 过滤器用于对web请求进行拦截并处理任务 ,对响应进行拦截处理

​ 过滤器的应用场景:

​ 1、统一设置请求、响应的字符编码格式

​ 2、身份验证,对请求用户拦截并验证是否登录

​ 3、敏感字符过滤 (用户提交数据时,过滤广告,敏感字符等)

​ 4、免登录(以前写在jsp的页面上,可以写在过滤器中)

2、如何实现过滤器

步骤1:创建一个过滤器类 实现接口 (javax.servlet.Filter)

步骤2: 重写doFilter方法

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        // 过滤器一旦拦截到该请求 则直接doFilter方法,
        System.out.println("正在执行拦截任务。。。。 ");

        //将请求转递给下一个过滤器 ,如果没有下一个过滤器 就到达目标方法servlet中
        filterChain.doFilter(servletRequest,servletResponse);
    }

步骤3:配置拦截的请求

@WebFilter(urlPatterns = "/login2Servlet")    // 只是拦截请求是 login2Servlet
public class MyFilter implements Filter {
 

案例1: 设置请求编码和响应编码

package com.softeem.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * ClassName: EncodingFilter
 * Description:
 * date: 2020/12/16 16:42
 *
 * @author wuyafeng
 * @version 1.0   softeem.com
 */
@WebFilter("/*") // //  /* 表示过滤所有请求,这里包括.jsp 和servlet 和静态资源
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        //设置编码格式
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        HttpServletRequest req = (HttpServletRequest)servletRequest;
        System.out.println("正在设置请求响应编码"+ req.getRequestURI());
        // 将请求传递给下一个过滤器,没有下一个到达目标servlet
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

案例2: 设置登录验证

将图书管理系统 增加用户验证功能 如果没有登录则不能到达管理页面


图书管理两张表

用户表、图书表

posted @ 2021-01-06 21:15  落雨♡̶初晴  阅读(156)  评论(0编辑  收藏  举报