• 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 FilesJavajdk1.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:Userswuyafeng.IntelliJIdea2018.2system omcatUnnamed_JavaWebProworkCatalinalocalhost 中 , 并执行 _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: 设置登录验证

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

    
    

    图书管理两张表

    用户表、图书表

  • 相关阅读:
    数据库镜像搭建
    关于开发人员数据库权限配置以及规范数据库升级流程
    带CheckBox列头的DataGridView
    查询整个数据库中某个特定值所在的表和字段的方法
    SQL Server 2008中获取数据库所有表及其字段名称、类型、长度的SQL
    关于已经上线项目的升级的启示
    SQL语句恢复数据库时一直显示“正在还原”
    带CheckBox列头的DataGridView(一)
    SQL Server中事务处理的注意事项
    group by 使用
  • 原文地址:https://www.cnblogs.com/z5452830/p/14243470.html
Copyright © 2020-2023  润新知