JavaWeb

.jpeg.-jpg

JavaWeb基础

文章目录

  • JavaWeb基础
    • 1、jQuery
      • 1.1 概述
      • 1.2 好处
    • 3、jQuery选择器
      • 3.1 基本选择器
      • 3.2 层级选择器
      • 3.3 过滤选择器
        • 3.3.1 基本过滤器
        • 3.3.2 内容过滤器
        • 3.3.3 属性过滤器
        • **3.3.4 表单过滤器**
        • 3.3.5 表单对象属性过滤器
        • 3.3.6 元素筛选
    • 4、jQuery属性操作
    • 5、jQuery-css样式操作
    • 6、jQuery动画操作
    • 7、jQuery事件操作
    • 8、XML简介
      • 8.1 什么是XML
      • 8.2 XML语法
      • 8.3 XML 与 HTML 的主要差异
      • 8.4 什么是 XML 元素
    • 9、dom4j解析技术
    • 10、JavaWeb
      • 10.1 JavaWeb概述
      • 10.2 Web资源的分类
      • 10.3 常用的Web服务器
    • 11、Tomcat的使用
      • 11.1 目录介绍
      • 11.2 Tomcat部署项目
      • 11.3 手托html页面到浏览器和在浏览器中输入http://ip地址:端口号/工程名l访问的区别
      • 11.4 IDEA创建动态Web工程
    • 12、Servlet技术
      • 12.1 什么是Selvlet
      • 12.2 手动实现Servlet程序
      • 12.3 Servlet-url如何定位到Servlet程序去访问
      • 12.4 Servlet生命周期
      • 12.5 继承HttpServlet实现Servlet程序
      • 12.6 Servlet继承体系
      • 12.7 ServletConfig类
      • 12.8 ServletContext接口
    • 13、Http协议
      • **13.1 请求的Http协议格式**
        • **GET请求**
        • **POST请求**
        • **常用的请求头说明**
        • 哪些是GET请求,哪些是POST请求
      • 13.2 响应的Http协议格式
      • 13.3 常见的响应码说明
      • 13.4MIME类型说明
    • 14、HttpServletRequest类
      • **14.1 HttpServletRequest的作用**
      • 14.2HttpServletRequest类的常用方法
      • 14.3 请求转发
      • 14.4 base 标签的作用
      • 14.5 Web 中的相对路径和绝对路径
    • 18、HttpServletResponse 类
      • 18.1 HttpServletResponse类的作用
      • 18.2 两个输入流的说明
      • 18.3 如何往客户端回传数据
      • 18.4 请求重定向
    • 19、JavaEE项目的三层架构
    • 20、Jsp
      • 20.1 什么是jsp
      • 20.2 JSP的本质
      • 20.3 JSP的三种语法
        • 20.3.1 JSP的page指令
        • 20.3.2 JSP常用脚本
          • 声明脚本(极少使用)
          • 表达式脚本(常用)
          • 代码脚本
      • 20.4 JSP九大内置对象
      • 20.5 JSP四大域对象
      • 20.6 JSP中的out输出和response.getWriter输出的区别
      • 20.7 JSP的常用标签
        • 20.7.1 静态包含
        • 20.7.2 动态包含
        • 20.7.3 JSP标签-请求转发
      • 20.8 练习
      • 20.9 Listener监听器
        • 20.9.1 ServletContextListener监听器
      • 20.10 EL 表达式
        • 20.10.1 什么是EL表达式,EL表达式的作用
        • 20.10.2 EL表达式搜索域数据的顺序
        • 20.10.3 EL 表达式输出 Bean 的普通属性,数组属性。List 集 合属性,map 集合属性
        • 20.10.4 EL 表达式——运算
          • **关系运算**
          • 逻辑运算
          • **算数运算**
          • empty运算
          • 三元运算
          • ”.“点运算和 []中括号运算符
          • EL表达式的11个隐含对象
          • pageContext的使用
          • EL 表达式其他隐含对象的使用
      • 20.11 JSTL标签库
        • 20.11.1core 核心库使用
    • 21、文件的上传和下载
      • **21.1 文件上传**
      • 21.2 commons-fileupload.jar 常用 API
      • 21.3 文件下载
        • **附件中文名乱码问题解决方案:**
    • 22、数据的封装和抽取 BeanUtils 的使用
    • 22、MVC 概念
    • 23、Cookie 饼干
      • 23.1 如何创建Cookie
      • 23.2 **服务器如何获取Cookie**
      • 23.3 Cookie 值的修改
      • 23.4 Cookie的生命控制
      • 23.5 Cookie 有效路径 Path 的设置
      • 23.6 Cookie--练习免输入用户名
      • 23.7 Session会话
      • 23.8 创建Session和获取(id号,是否为新)
      • 23.9 Session域中存取数据
      • 23.10 Session的生命周期控制
      • 23.11 浏览器和Session之间关联的技术内幕
    • 24、Filter过滤器
      • 24.1 Filter示例:
      • 24.2 Filter 过滤器的使用步骤:
      • 24.3 Filter 生命周期
      • 24.4 FilterConfig 类
      • 24.5 FilterChain 过滤器链
      • 24.6 Filter 的拦截路径
    • 25、ThreadLocal
    • 26、Filter 和 ThreadLocal 组合管理事
    • 27、JSON
      • 27.1 JSON的定义
      • 27.2 JSON的访问
      • 27.3 JSON 的两个常用方法
      • 27.4 JSON 在 java 中的使用
        • 27.4.1 JavaBean和json的互转
        • 27.4.2 List和json的互转
        • 27.4.3 Map和json的互转
    • 28、AJAX请求
      • 28.1 什么是Ajax请求
      • **28.2 jQuery中的Ajax请求**
      • 27.4 JSON 在 java 中的使用
        • 27.4.1 JavaBean和json的互转
        • 27.4.2 List和json的互转
        • 27.4.3 Map和json的互转
    • 28、AJAX请求
      • 28.1 什么是Ajax请求
      • **28.2 jQuery中的Ajax请求**

1、jQuery

1.1 概述

​ jQuery,顾名思义,也就是JavaScript和查询(query),他就是辅助JavaScript开发的JS类库。

1.2 好处

​ 免费、开源、语法设计可以使开发更便捷,例如操作文档对象(DOM)、选择DOM元素、制作动画效果、事件处理、使用Ajax以及其他功能

3、jQuery选择器

3.1 基本选择器

选择器 描述
#ID 选择器:根据 id 查找标签对象
.class 选择器:根据 class 查找标签对象
element 选择器:根据标签名查找标签对象
* 选择器:表示任意的,所有的元素
selector1,selector2 组合选择器:合并选择器 1,选择器 2 的结果并返回

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        div, span, p {
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border: #000 1px solid;
            float: left;
            font-size: 17px;
            font-family: Verdana;
        }
        div.mini {
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }
        div.hide {
            display: none;
        }
    style>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script>
        $(function (){
            //1.选择 body 内的所有 div 元素
            $("#btn1").click(function () {
                $("body div").css("background-color","#bbffaa");
            })
            //2.在 body 内, 选择div子元素
            $("#btn2").click(function () {
                $("body > div").css("background-color","#bbffaa");
            })
            //3.选择 id 为 one 的下一个 div 元素
            $("#btn3").click(function (){
                $("#one + div").css("background-color","#bbffaa");
            })
            //4.选择 id 为 two 的元素后面的所有 div 兄弟元素
            $("#btn4").click(function () {
                $("#two ~ div").css("background-color","#bbffaa");
            })
        })
    script>
head>
<body>
<input type="button" value="选择 body 内的所有 div 元素" id="btn1" />
<input type="button" value="在 body 内, 选择div子元素" id="btn2" />
<input type="button" value="选择 id 为 one 的下一个 div 元素" id="btn3" />
<input type="button" value="选择 id 为 two 的元素后面的所有 div 兄弟元素" id="btn4" />
<br><br>
<div class="one" id="one">
    id 为 one,class 为 one 的div
    <div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
    id为two,class为one,title为test的div
    <div class="mini" title="other">class为mini,title为otherdiv>
    <div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">div>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
    包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<span id="span">^^span元素^^span>
body>
html>

3.2 层级选择器

选择器 描述
ancestor descendant 后代选择器 :在给定的祖先元素下匹配所有的后代元素
parent > child 子元素选择器:在给定的父元素下匹配所有的子元素
prev + next 相邻元素选择器:匹配所有紧接在 prev 元素后的 next 元
prev ~ sibings 之后的兄弟元素选择器:匹配 prev 元素之后的所有 siblings 元素

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        div, span, p {
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border: #000 1px solid;
            float: left;
            font-size: 17px;
            font-family: Verdana;
        }
        div.mini {
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }

        div.hide {
            display: none;
        }
    style>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script>
        $(function (){
            //1.选择 body 内的所有 div 元素
            $("#btn1").click(function () {
                $("body div").css("background-color","#bbffaa");
            })
            //2.在 body 内, 选择div子元素
            $("#btn2").click(function () {
                $("body > div").css("background-color","#bbffaa");
            })
            //3.选择 id 为 one 的下一个 div 元素
            $("#btn3").click(function (){
                $("#one + div").css("background-color","#bbffaa");
            })
            //4.选择 id 为 two 的元素后面的所有 div 兄弟元素
            $("#btn4").click(function () {
                $("#two ~ div").css("background-color","#bbffaa");
            })
        })
    script>
head>
<body>
<input type="button" value="选择 body 内的所有 div 元素" id="btn1" />
<input type="button" value="在 body 内, 选择div子元素" id="btn2" />
<input type="button" value="选择 id 为 one 的下一个 div 元素" id="btn3" />
<input type="button" value="选择 id 为 two 的元素后面的所有 div 兄弟元素" id="btn4" />
<br><br>
<div class="one" id="one">
    id 为 one,class 为 one 的div
    <div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
    id为two,class为one,title为test的div
    <div class="mini" title="other">class为mini,title为otherdiv>
    <div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">div>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
    包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<span id="span">^^span元素^^span>
body>
html>

3.3 过滤选择器

3.3.1 基本过滤器
选择器 描述
:first 获取第一个元素
:last 获取最后个元素
:not(selector) 去除所有与给定选择器匹配的元素
:even 匹配所有索引值为偶数的元素,从 0 开始计
:odd 匹配所有索引值为奇数的元素,从 0
:eq(index) 匹配一个给定索引值的元素
:gt(index) 匹配所有大于给定索引值的元素
:lt(index) 匹配所有小于给定索引值的元素
:header 匹配如 h1, h2, h3
:animated 匹配所有正在执行动画效果的元素

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        div, span, p {
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border: #000 1px solid;
            float: left;
            font-size: 17px;
            font-family: Verdana;
        }

        div.mini {
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }

        div.hide {
            display: none;
        }
    style>

    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script>
        $(document).ready(function(){
            function anmateIt(){
                $("#mover").slideToggle("slow", anmateIt);
            }
            anmateIt();
        });
        $(function () {
            //1.选择第一个 div 元素
            $("#btn1").click(function () {
                $("div:first").css("background-color","#bbffaa");
            })
            //2.选择最后一个 div 元素
            $("#btn2").click(function () {
                $("div:last").css("background-color","red");
            })
            //3.选择class不为 one 的所有 div 元素
            $("#btn3").click(function () {
                $("div:not(.one)").css("background-color","#bbffaa");
            })
            //4.选择索引值为偶数的 div 元素
            $("#btn4").click(function () {
                $("div:even").css("background-color","#bbffaa")
            })
            //5.选择索引值为奇数的 div 元素
            $("#btn5").click(function () {
                $("div:odd").css("background-color","#bbffaa")
            })
            //6.选择索引值为大于 3 的 div 元素
            $("#btn6").click(function () {
                $("div:gt(3)").css("background-color","#bbffaa")
            })
            //7.选择索引值为等于 3 的 div 元素
            $("#btn7").click(function () {
                $("div:eq(3)").css("background-color","#bbffaa")
            })
            //8.选择索引值为小于 3 的 div 元素
            $("#btn8").click(function () {
                $("div:lt(3)").css("background-color","#bbffaa")
            })
            //9.选择所有的标题元素
            $("#btn9").click(function () {
                $(":header").css("background-color","#bbffaa")
            })
            //10.选择当前正在执行动画的所有元素
            $("#btn10").click(function () {
                $("div:animated").css("background-color","#bbffaa")
            })
            //选择没有执行动画的最后一个div
            $("#btn11").click(function () {
                $("div:not(:animated):last").css("background-color","#bbffaa")
            })
        })
    script>
head>
<body>
    <input type="button" value="选择第一个div元素" id="btn1">
    <input type="button" value="选择最后一个div元素" id="btn2">
    <input type="button" value="选择class不为one的所有div元素" id="btn3">
    <input type="button" value="选择索引值为偶数的div元素" id="btn4">
    <input type="button" value="选择索引值为奇数的div元素" id="btn5">
    <input type="button" value="选择索引值大于3的div元素" id="btn6">
    <input type="button" value="选择索引值等于3的div元素" id="btn7">
    <input type="button" value="选择索引值小于3的div元素" id="btn8">
    <input type="button" value="选择所有的标题元素" id="btn9">
    <input type="button" value="选择当前正在执行动画的所有元素" id="btn10" />
    <input type="button" value="选择没有执行动画的最后一个div" id="btn11" />

    <h3>基本选择器h3>
    <br><br>
    <div class="one" id="one">
        id为one,class为one的div
        <div class="mini">class为mini的ivdiv>
    div>
    <div class="one" id="two" title="test">
        id为two,class为one,title为test的div
        <div class="mini" title="other">class为mini,title为otherdiv>
        <div class="mini" title="test">class为mini,title为testdiv>
    div>
    <div class="one">
        <div class="mini">class为minidiv>
        <div class="mini">class为minidiv>
        <div class="mini">class为minidiv>

        <div class="mini">div>
    div>
    <div class="one">
        <div class="mini">class为minidiv>
        <div class="mini">class为minidiv>
        <div class="mini">class为minidiv>
        <div class="mini" title="tesst">class为mini,title为tesstdiv>
    div>
    <div style="display:none;" class="none">style的display为"none"的divdiv>
    <div class="hide">class为"hide"的divdiv>
    <div>
        包含input的type为"hidden"的div<input type="hidden" size="8">
    div>
    <div id="mover">正在执行动画的div元素.div>
body>
html>
3.3.2 内容过滤器
选择器 描述
:contains(text) 匹配包含给定文本的元素
:empty 匹配所有不包含子元素或者文本的空元素
:parent 匹配含有子元素或者文本的元素
:has(selector) 匹配含有选择器所匹配的元素的元素

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        div, span, p {
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border: #000 1px solid;
            float: left;
            font-size: 17px;
            font-family: Verdana;
        }

        div.mini {
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }

        div.hide {
            display: none;
        }
    style>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script>
        /**
         :contains(text)
         :empty
         :has(selector)
         :parent
         */
        $(document).ready(function(){
            function anmateIt(){
                $("#mover").slideToggle("slow", anmateIt);
            }

            anmateIt();
        });
        $(function () {
            //1.选择 含有文本 'di' 的 div 元素
            $("#btn1").click(function () {
                $("div:contains('di')").css("background-color","#bbffaa")
            })
            //2.选择不包含子元素(或者文本元素) 的 div 空元素
            $("#btn2").click(function () {
                $("div:empty").css("background-color","#bbffaa");
            })
            //3.选择含有 class 为 mini 元素的 div 元素
            $("#btn3").click(function () {
                $("div:has(.mini)").css("background-color","#bbffaa")
            })
            //4.选择含有子元素(或者文本元素)的div元素
            $("#btn4").click(function () {
                $("div:parent").css("background-color","#bbffaa")
            })
        })
    script>
head>
<body>
<input type="button" value="选择 含有文本 'di' 的 div 元素" id="btn1" />
<input type="button" value="选择不包含子元素(或者文本元素) 的 div 空元素" id="btn2" />
<input type="button" value="选择含有 class 为 mini 元素的 div 元素" id="btn3" />
<input type="button" value="选择含有子元素(或者文本元素)的div元素" id="btn4" />

<br><br>
<div class="one" id="one">
    id 为 one,class 为 one 的div
    <div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
    id为two,class为one,title为test的div
    <div class="mini" title="other">class为mini,title为otherdiv>
    <div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">div>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
    包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<div id="mover">正在执行动画的div元素.div>
body>
html>
3.3.3 属性过滤器
选择器 描述
[attribute] 匹配包含给定属性的元素
[attribute=value] 匹配给定的属性是某个特定值的元素
[attribute!=value] 匹配所有不含有指定的属性,或者属性不等于特定值的元素。
[attribute^=value] 匹配给定的属性是以某些值开始的元素
[attribute$=value] 匹配给定的属性是以某些值结尾的元素
[attribute*=value] 匹配给定的属性是以包含某些值的元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BpBZmO6Z-1647142934498)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211218211913710.png)] 复合属性选择器,需要同时满足多个条件时使用。

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style type="text/css">
        div,span,p {
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border: #000 1px solid;
            float: left;
            font-size: 17px;
            font-family: Verdana;
        }

        div.mini {
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }

        div.hide {
            display: none;
        }
    style>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script>
        /**
         [attribute]
         [attribute=value]
         [attribute!=value]
         [attribute^=value]
         [attribute$=value]
         [attribute*=value]
         [attrSel1][attrSel2][attrSelN]


         */
        $(function () {
            //1.选取含有 属性title 的div元素
            $("#btn1").click(function() {
                $("div[title]").css("background", "#bbffaa");
            });
            //2.选取 属性title值等于'test'的div元素
            $("#btn2").click(function() {
                $("div[title = 'test']").css("background", "#bbffaa");
            });
            //3.选取 属性title值不等于'test'的div元素(*没有属性title的也将被选中)
            $("#btn8").click(function() {
                $("div[title != 'test']").css("background", "#bbffaa");
            });
            //4.选取 属性title值 以'te'开始 的div元素
            $("#btn4").click(function() {
                $("div[title ^= 'te']").css("background", "#bbffaa");
            });
            //5.选取 属性title值 以'est'结束 的div元素
            $("#btn5").click(function() {
                $("div[title $= 'est' ]").css("background", "#bbffaa");
            });
            //6.选取 属性title值 含有'es'的div元素
            $("#btn6").click(function() {
                $("div[title *= 'es']").css("background", "#bbffaa");
            });

            //7.首先选取有属性id的div元素,然后在结果中 选取属性title值 含有'es'的 div 元素
            $("#btn7").click(function() {
                $("div[id][title *= 'es']").css("background", "#bbffaa");
            });
            //8.选取 含有 title 属性值, 且title 属性值不等于 test 的 div 元素
            $("#btn8").click(function() {
                $("div[title][title != 'test']").css("background", "#bbffaa");
            });
        })

    script>
head>
<body>
<input type="button" value="选取含有 属性title 的div元素." id="btn1" style="display: none;"/>
<input type="button" value="选取 属性title值等于'test'的div元素." id="btn2" />
<input type="button"
       value="选取 属性title值不等于'test'的div元素(没有属性title的也将被选中)." id="btn3" />
<input type="button" value="选取 属性title值 以'te'开始 的div元素." id="btn4" />
<input type="button" value="选取 属性title值 以'est'结束 的div元素." id="btn5" />
<input type="button" value="选取 属性title值 含有'es'的div元素." id="btn6" />
<input type="button"
       value="组合属性选择器,首先选取有属性id的div元素,然后在结果中 选取属性title值 含有'es'的 div 元素."
       id="btn7" />
<input type="button"
       value="选取 含有 title 属性值, 且title 属性值不等于 test 的 div 元素." id="btn8" />
<br>
<br>
<div class="one" id="one">
    id 为 one,class 为 one 的div
    <div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
    id为two,class为one,title为test的div
    <div class="mini" title="other">class为mini,title为otherdiv>
    <div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">div>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display: none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
    包含input的type为"hidden"的div<input type="hidden" value="123456789"
                                    size="8">
div>
<div id="mover">正在执行动画的div元素.div>
body>
html>
3.3.4 表单过滤器
选择器 描述
:input 匹配所有 input, textarea, select 和 button 元素
:text 匹配所有 文本输入框
:password 匹配所有的密码输入框
:radio 匹配所有的单选框
:checkbox 匹配所有的复选框
:submit 匹配所有提交按钮
:image 匹配所有 img 标
:reset 匹配所有重置按钮
:button 匹配所有 input type=button 按
:file 匹配所有 input type=file 文件上传
:hidden 匹配所有不可见元素 display:none 或 input
3.3.5 表单对象属性过滤器
选择器 描述
:enabled 匹配所有可用元素
:disabled 匹配所有不可用元素
:checked 匹配所有选中的单选,复选,和下拉列表中选中的 option 标签对
:selected 匹配所有选中的 option

综合表单和属性过滤器示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script>
        $(function () {
            /**
             :input
             :text
             :password
             :radio
             :checkbox
             :submit
             :image
             :reset
             :button
             :file
             :hidden
             表单对象的属性
             :enabled
             :disabled
             :checked
             :selected
             */
            //1.对表单内 可用input 赋值操作
            //val()可以操作表单选项的value属性值
            //可以设置和获取
            $("#btn1").click(function () {
                $(":text:enabled").val("我叫张二狗")
            })
            //2.对表单内 不可用input 赋值操作
            $("#btn2").click(function (){
                $(":text:disabled").val("我叫狗蛋")
            })
            //3.获取多选框选中的个数  使用size()方法获取选取到的元素集合的元素个数
            $("#btn3").click(function () {
                alert($(":checkbox:checked").length)
            })
            //4.获取多选框,每个选中的value值
            $("#btn4").click(function () {
                //获取所有选中的复选框
                let $cehe = $(":checkbox:checked");
                //each方法是jQuery对象提供用来遍历元素的方法
                //在遍历的function函数中,有一个this对象,这个this对象,就是当前遍历到的dom对象
                $cehe.each(function () {
                    alert(this.value)
                });
            })
            //5.获取下拉框选中的内容
            $("#btn5").click(function () {
                //获取选中的option标签对象
                let opt = $("select option:selected");
                //遍历,获取option标签内容
                opt.each(function () {
                    alert(this.value);
                });
            })
        })
    script>
head>
<body>
<h3>表单对象属性过滤选择器h3>
<button id="btn1">对表单内 可用input 赋值操作.button>
<button id="btn2">对表单内 不可用input 赋值操作.button>
<br/><br/>
<button id="btn3">获取多选框选中的个数.button>
<button id="btn4">获取多选框选中的内容.button>
<br/><br/>
<button id="btn5">获取下拉框选中的内容.button>
<br/><br/>

<form id="form1" action="#">
    可用元素: <input name="add" value="可用文本框1"/><br>
    不可用元素: <input name="email" disabled="disabled" value="不可用文本框"/><br>
    可用元素: <input name="che" value="可用文本框2"/><br>
    不可用元素: <input name="name" disabled="disabled" value="不可用文本框"/><br>
    <br>

    多选框: <br>
    <input type="checkbox" name="newsletter" checked="checked" value="test1"/>test1
    <input type="checkbox" name="newsletter" value="test2"/>test2
    <input type="checkbox" name="newsletter" value="test3"/>test3
    <input type="checkbox" name="newsletter" checked="checked" value="test4"/>test4
    <input type="checkbox" name="newsletter" value="test5"/>test5

    <br><br>
    下拉列表1: <br>
    <select name="test" multiple="multiple" style="height: 100px" id="sele1">
        <option>浙江option>
        <option selected="selected">辽宁option>
        <option>北京option>
        <option selected="selected">天津option>
        <option>广州option>
        <option>湖北option>
    select>

    <br><br>
    下拉列表2: <br>
    <select name="test2">
        <option>浙江option>
        <option>辽宁option>
        <option selected="selected">北京option>
        <option>天津option>
        <option>广州option>
        <option>湖北option>
    select>
form>
body>
html>
3.3.6 元素筛选
选择器 描述
eq() 获取给定索引的元素
first() 获取第一个元素
last() 获取最后一个元素
filter(exp) 留下匹配的元素
is(exp) 判断是否匹配给定的选择器,只要有一个匹配就返回,true
has(exp) 返回包含有匹配选择器的元素的元素
not(exp) 删除匹配选择器的元素
children(exp) 返回匹配给定选择器的子元素
find(exp) 返回匹配给定选择器的后代元素
next() 返回当前元素的下一个兄弟元素
nextAll() 返回当前元素后面所有的兄弟元素
nextUntil() 返回当前元素到指定匹配的元素为止的后面元素
parent() 返回父元素
prev(exp) 返回当前元素的上一个兄弟元素
prevAll() 返回当前元素前面所有的兄弟元素
prevUnit(exp) 返回当前元素到指定匹配的元素为止的前面元素
siblings(exp) 返回所有兄弟元素
add() 把 add 匹配的选择器的元素添加到当前 jquery 对象

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        div, span, p {
            width: 140px;
            height: 140px;
            margin: 5px;
            background: #aaa;
            border: #000 1px solid;
            float: left;
            font-size: 17px;
            font-family: Verdana;
        }

        div.mini {
            width: 55px;
            height: 55px;
            background-color: #aaa;
            font-size: 12px;
        }

        div.hide {
            display: none;
        }
    style>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script !src="">
        $(function () {
            $(document).ready(function() {
                function animateIt() {
                    $("#mover").slideToggle("slow", animateIt);
                }

                animateIt();
            })

            //(1)eq()  选择索引值为等于 3 的 div 元素
            $("#btn1").click(function(){
                $("div").eq(3).css("background-color","#bfa");
            });
            //(2)first()选择第一个 div 元素
            $("#btn2").click(function(){
                //first()   选取第一个元素
                $("div").first().css("background-color","#bfa");
            });
            //(3)last()选择最后一个 div 元素
            $("#btn3").click(function(){
                //last()  选取最后一个元素
                $("div").last().css("background-color","#bfa");
            });
            //(4)filter()在div中选择索引为偶数的
            $("#btn4").click(function(){
                //filter()  过滤   传入的是选择器字符串
                $("div").filter(":even").css("background-color","#bfa");
            });
            //(5)is()判断#one是否为:empty或:parent
            //is用来检测jq对象是否符合指定的选择器
            $("#btn5").click(function(){
                alert($("#one").is("empty"));
            });

            //(6)has()选择div中包含.mini的
            $("#btn6").click(function(){
                //has(selector)  选择器字符串    是否包含selector
                $("div").has('.mini').css("background-color","#bfa");
            });
            //(7)not()选择div中class不为one的
            $("#btn7").click(function(){
                //not(selector)  选择不是selector的元素
                $("div").not(".one").css("background-color","#bfa");
            });
            //(8)children()在body中选择所有class为one的div子元素
            $("#btn8").click(function(){
                //children()  选出所有的子元素
                $("div").children().css("background-color","#bfa");
            });


            //(9)find()在body中选择所有class为mini的div元素
            $("#btn9").click(function(){
                //find()  选出所有的后代元素
                $("body").find(".mini").css("background-color","#bfa");
            });
            //(10)next() #one的下一个div
            $("#btn10").click(function(){
                //next()  选择下一个兄弟元素
                $("#one").next("div").css("background-color","#bfa");
            });
            //(11)nextAll() #one后面所有的span元素
            $("#btn11").click(function(){
                //nextAll()   选出后面所有的元素
                $("#one").nextAll("span").css("background-color","#bfa");
            });
            //(12)nextUntil() #one和span之间的元素
            $("#btn12").click(function(){
                //
                $("#one").nextUntil("span").css("background-color","#bfa")
            });
            //(13)parent() .mini的父元素
            $("#btn13").click(function(){
                $(".mini").parent().css("background-color","#bfa");
            });
            //(14)prev() #two的上一个div
            $("#btn14").click(function(){
                //prev()
                $("#two").prev().css("background-color","#bfa")
            });
            //(15)prevAll() span前面所有的div
            $("#btn15").click(function(){
                //prevAll()   选出前面所有的元素
                $("span").prevAll().css("background-color","#bfa")
            });
            //(16)prevUntil() span向前直到#one的元素
            $("#btn16").click(function(){
                //prevUntil(exp)   找到之前所有的兄弟元素直到找到exp停止
                $("span").prevUntil("#one").css("background-color","#bfa")
            });
            //(17)siblings() #two的所有兄弟元素
            $("#btn17").click(function(){
                //siblings()    找到所有的兄弟元素,包括前面的和后面的
                $("#two").siblings().css("background-color","#bfa")
            });


            //(18)add()选择所有的 span 元素和id为two的元素
            $("#btn18").click(function(){

                //   $("span,#two,.mini,#one")
                $("span").add("#two")
                    .add(".mini").add("#one").css("background-color","#bfa");

            });
        })
    script>
head>
<body>
<input type="button" value="eq()选择索引值为等于 3 的 div 元素" id="btn1" />
<input type="button" value="first()选择第一个 div 元素" id="btn2" />
<input type="button" value="last()选择最后一个 div 元素" id="btn3" />
<input type="button" value="filter()在div中选择索引为偶数的" id="btn4" />
<input type="button" value="is()判断#one是否为:empty或:parent" id="btn5" />
<input type="button" value="has()选择div中包含.mini的" id="btn6" />
<input type="button" value="not()选择div中class不为one的" id="btn7" />
<input type="button" value="children()在body中选择所有class为one的div子元素" id="btn8" />
<input type="button" value="find()在body中选择所有class为mini的div后代元素" id="btn9" />
<input type="button" value="next()#one的下一个div" id="btn10" />
<input type="button" value="nextAll()#one后面所有的span元素" id="btn11" />
<input type="button" value="nextUntil()#one和span之间的元素" id="btn12" />
<input type="button" value="parent().mini的父元素" id="btn13" />
<input type="button" value="prev()#two的上一个div" id="btn14" />
<input type="button" value="prevAll()span前面所有的div" id="btn15" />
<input type="button" value="prevUntil()span向前直到#one的元素" id="btn16" />
<input type="button" value="siblings()#two的所有兄弟元素" id="btn17" />
<input type="button" value="add()选择所有的 span 元素和id为two的元素" id="btn18" />


<h3>基本选择器.h3>
<br /><br />
文本框<input type="text" name="account" disabled="disabled" />
<br><br>
<div class="one" id="one">
    id 为 one,class 为 one 的div
    <div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
    id为two,class为one,title为test的div
    <div class="mini" title="other"><b>class为mini,title为otherb>div>
    <div class="mini" title="test">class为mini,title为testdiv>
div>

<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">div>
div>
<div class="one">
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini">class为minidiv>
    <div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<span id="span1">^^span元素 111^^span>
<div>
    包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<span id="span2">^^span元素 222^^span>
<div id="mover">正在执行动画的div元素.div>
body>
html>

4、jQuery属性操作

方法 描述
html() 它可以设置和获取起始标签到结束标签中的内容(和DOM innerHtml方法一样)
text() 它可以设置和获取起始标签到结束标签中的文本(和DOM innerText方法一样)
val() 它可以设置和获取获取表单项的value属性值(和DOM value一样)
attr() 可以设置和获取属性的值,不推荐操作checked、readOnly、selected、disabled等等
prop() 可以设置和获取属性的值,只推荐操作checked、readOnly、selected、disabled等等
appendTo() 在被选元素的结尾(仍然在内部)插入指定内容
prependTo() 在被选元素的开头(仍然在内部)插入指定内容
insertAfter() 在被选元素之后插入 HTML 标记或已有的元素
insertBefore() 在您指定的已有子节点之前插入新的子节点
replaceWith() 指定的 HTML 内容或元素替换被选元素
replaceAll() 指定的 HTML 内容或元素替换被选元素(replaceAll() 与 [replaceWith()]作用相同。差异在于语法:内容和选择器的位置,以及replaceWith() 能够使用函数进行替换。)
remove() 删除元素
empty() 删除元素的内容

5、jQuery-css样式操作

方法 描述
addClass() 向被选元素添加一个或多个类
removeClass() 从被选元素删除一个或多个类
toggleClass() 检查每个元素中指定的类。如果不存在则添加类,如果已设置则删除之
offset() 返回或设置匹配元素相对于文档的偏移(位置)

示例:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style>
        div{
            width:100px;
            height:260px;
        }

        div.whiteborder{
            border: 2px white solid;
        }

        div.redDiv{
            background-color: red;
        }

        div.blueBorder{
            border: 5px blue solid;
        }
    style>
    <script src="../node_modules/jquery/dist/jquery.js">script>
    <script >
        $(function () {
            let $div = $("div:first");
            $("#btn01").click(function () {
                //向被选元素添加一个或多个类
                $div.addClass('redDiv blueBorder')
            })

            $("#btn02").click(function () {
                //从被选元素删除一个或多个类
                $div.removeClass();
            })

            $("#btn03").click(function () {
                //对被选元素进行添加/删除类的切换操作 
                $div.toggleClass('redDiv blueBorder')
            })

            $("#btn04").click(function () {
                //console.log($div.offset());
                //返回或设置匹配元素相对于文档的偏移(位置)
                $div.offset({
                    top:50,
                    left:100
                })
            })
        })
    script>
head>
<body>
<table>
    <tr>
        <td>
            <div class="border">
            div>
        td>

        <td>
            <div class="btn">
                <input type="button" value="addClass()" id="btn01"/>
                <input type="button" value="removeClass()" id="btn02"/>
                <input type="button" value="toggleClass()" id="btn03"/>
                <input type="button" value="offset()" id="btn04"/>
            div>
        td>
    tr>
table>
<br /> <br />
<br /> <br />
body>
html>

6、jQuery动画操作

方法 描述
show() 如果被选元素已被隐藏,则显示这些元素
hide() 如果被选的元素已被显示,则隐藏该元素
toggle() 如果被选元素可见,则隐藏这些元素,如果被选元素隐藏,则显示这些元素
fadeln() 方法使用淡入效果来显示被选元素,假如该元素是隐藏的。
fadeOut() 使用淡出效果来隐藏被选元素,假如该元素是隐藏的
fadeTo() 将被选元素的不透明度逐渐地改变为指定的值
fadeToggle() 如果被选元素可见,则淡出这些元素,如果被选元素隐藏,则淡入这些元素

以上动画方法都可以添加参数。
1、第一个参数是动画执行的时长,以毫秒为单位
2、第二个参数是动画的回调函数(动画完成后自动调用的函崴)

7、jQuery事件操作

事件 描述
click() 它可以绑定单击事件,以及触发单击事件
mouseenter() 鼠标移入事件
mouseout() 鼠标移出事件
bind() 可以给元素一次性绑定一个或多个事件。
one() 使用上跟bind一样。但是one方法绑定的事件只会响应一次。
unbind() 跟bind 方法相反的操作,解除事件的绑定
live() 也是用来绑定事件。它可以用来绑定选择器匹配的所有元素的事件。哪怕这个元素是后面动态创建出来的也有效

8、XML简介

8.1 什么是XML

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签
  • XML 被设计为具有自我描述性
  • XML 是 W3C 的推荐标准

8.2 XML语法

  • 1.文档声明。

  • 2.元素(标签)

  • 3.xml 属性

  • 4.xml注释

  • 5.文本区域(CDATA区)

8.3 XML 与 HTML 的主要差异

XML 不是 HTML 的替代。

XML 和 HTML 为不同的目的而设计:

XML 被设计为传输和存储数据,其焦点是数据的内容。

HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。

8.4 什么是 XML 元素

XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。

元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。

<bookstore>
<book category="CHILDREN">
  <title>Harry Pottertitle> 
  <author>J K. Rowlingauthor> 
  <year>2005year> 
  <price>29.99price> 
book>
<book category="WEB">
  <title>Learning XMLtitle> 
  <author>Erik T. Rayauthor> 
  <year>2003year> 
  <price>39.95price> 
book>
bookstore> 

在上例中, 和 都拥有元素内容,因为它们包含了其他元素。 只有文本内容,因为它仅包含文本。

在上例中,只有 元素拥有属性 (category=“CHILDREN”)。

9、dom4j解析技术

示例:

book类

package com.atguigu.pojo;

import java.math.BigDecimal;

public class Book {
    private String sn;
    private String name;
    private BigDecimal price;
    private String author;

    public Book() {

    }

    public Book(String sn, String name, BigDecimal price, String author) {
        this.sn = sn;
        this.name = name;
        this.price = price;
        this.author = author;
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "sn='" + sn + '\'' +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", author='" + author + '\'' +
                '}';
    }
}

books.xml文件



<books>
    <book sn="SN1000001">
        <name>荒野大镖客Ⅱname>
        <price>399price>
        <author>R星author>
    book>
    <book sn="SN1000002">
        <name>刺客信条起源name>
        <price>299price>
        <author>育碧author>
    book>
books>

dom4j解析xml文件

package com.atguigu.pojo;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.math.BigDecimal;
import java.util.List;

public class Dom4jTest {
    @Test
    public void test1(){
        //创建一个SAXReader输入流,去读取xml配置文件,生成Document对象
        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read("src/books.xml");
            System.out.println(document);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    /**
     * 读取books.xml文件生成Book类
     */
    @Test
    public void Test2() throws DocumentException {
        //1.读取books.xml文件
        SAXReader saxReader = new SAXReader();
        //2.通过Document对象获取根元素
        Document document = saxReader.read("src/books.xml");
        //3.通过根元素获取book标签对象
        Element rootElement = document.getRootElement();
        //4.遍历,处理每个book标签转换为Book类
        List books = rootElement.elements("book");
        for (Element book : books){
            //asXML();把标签对象,转换为标签字符串
            Element nameElement = book.element("name");
            //getText();可以获取标签的文本内容
            String nameText = nameElement.getText();
            //elementText();直接获取指定标签的文本内容
            String priceText = book.elementText("price");
            String authorTest = book.elementText("author");
            String snValue = book.attributeValue("sn");
            System.out.println(new Book(snValue,nameText,new BigDecimal(priceText),authorTest));
        }
    }
}

10、JavaWeb

10.1 JavaWeb概述

Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web[服务端]和web[客户端]两部分。Java在客户端的应用有Java Applet,不过[使用]得很少,Java在[服务器端]的应用非常的丰富,比如[Servlet],[JSP]、第三方[框架]等等。Java技术对Web领域的发展注入了强大的动力。

JavaWeb是指,所有通过Java语言编写可以通过浏览器访问的程序的总称,叫JavaWeb

JavaWeb是基于请求和响应来开发的。

  • 什么是请求
    • 请求是指客户端给服务器发送数据,叫请求Request
  • 什么是响应
    • 响应是指服务器给客户端回传数据,叫响应Response
  • 请求与响应的关系
    • 请求和响应是成对出现的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrMYFnYX-1647142931683)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211220164233838.png)]

10.2 Web资源的分类

**静态资源:**html、css、JavaScript、txt、mp4、jpg 等

**动态资源:**JSP、Servlet程序

10.3 常用的Web服务器

  • Tomcat:由Apache组织提供的一种web服务器,提供对 jsp和servlet的支持。它是一种轻量级的javaweb容器(服务器),也是当前应用最广的JavaWeb服务器〈免费〉。

  • Jboss:是一个遵从JavaEE规范的、开放源代码的、纯Java的EJ服务器,它支持所有的JavaEE规范(免费〉。

  • GlassFish: 由Oracle公司开发的一款JavaWeb服务器,是一款强健的商业服务器,达到产品级质量〈(应用很少)

  • Resin:是cAUCHO公司的产品,是一个非常流行的服务器,对servlet和JSP提供了良好的支持,性能也比较优良,resin自身采用JAVA语言开发(收费,应用比较多)。

  • webLogic:是oracle公司的产品,是目前应用最广泛的Web服务器,支持JavaEE规范,而且不断的完善以适应新的开发要求,适合大型项目(收费,用的不多,适合大公司)。

11、Tomcat的使用

11.1 目录介绍

  • bin
    • 专门用来存放Tomcat服务器的可执行程序
  • conf
    • 专门用来存放Tocmat服务器的配置文件
  • lib
    • 专门用来存放Tomcat服务器的jar包logs专门用来存放Tomcat服务器运行时输出的日记信息
  • temp
    • 专门用来存放Tomcdat运行时产生的临时数据
  • webapps
    • 专门用来存放部署的web工程,每一个文件夹代表一个项目
  • work
    • 是Tomcat工作时的目录,用来存放Tomcat运行时jsp翻译为servlet的源码,和session钝化的目录

11.2 Tomcat部署项目

  • 方式一:

​ 只需要把Web工程的目录拷贝到Tomcat的webapps目录即可

​ 1.在webapps目录下创建项目工程文件夹

​ 2.将文件拷贝到目录下即可

访问方式http://ip地址:端口号/路径/文件名.xxx

  • 方式二:

​ 找到在 tomcat 下的\conf\Catalina\localhost 下新建一个.xml配置文件

.xml配置文件书写格式:


<Context path="/abc" docBase="I:\Wed\crm"/>

访问方式http://ip地址:端口号/工程名/路径/文件名.xxx

11.3 手托html页面到浏览器和在浏览器中输入http://ip地址:端口号/工程名l访问的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFyf71Dc-1647142931684)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211220183631266.png)]

11.4 IDEA创建动态Web工程

idea2021.3创建web项目步骤:https://www.jianshu.com/p/696211853dbe

Web动态工程目录介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CZ6kr2E2-1647142931685)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211221124150170.png)]

12、Servlet技术

12.1 什么是Selvlet

  • 1、Selrvlet是JavaEE规范之一,规范就是接口
  • 2、Servlet就是Java Web三大组件之一,三大组件分别是Servlet程序、filter过滤器、Listener监听器
  • 3、Servlet是运行在服务器上的一个Java小程序,它可以接收客户端发送过来的请求,并相应数据给客户端

12.2 手动实现Servlet程序

1、编写一个类去实现Servlet接口

2、实现service方法,处理请求,并响应数据

3、到web.xml中去配置servlet程序的访问地址

实现类:

package com.atguigu.servlet;

import javax.servlet.*;
import java.io.IOException;

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * service方法是专门用来处理请求和响应的
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello servlet 已被访问!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

访问地址配置:


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    
    <servlet>
        
        <servlet-name>HelloServletservlet-name>
        
        <servlet-class>com.atguigu.servlet.HelloServletservlet-class>
    servlet>

    
    <servlet-mapping>
        
        <servlet-name>HelloServletservlet-name>
        
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
web-app>

12.3 Servlet-url如何定位到Servlet程序去访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YA5HYssl-1647142931685)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211221144442023.png)]

12.4 Servlet生命周期

1、执行Servlet构造方法

2、执行init初始化方法

第一,第二步:是在第一次访问的时候创建Servlet程序会调用

3、执行service方法

第三步:每次访问都会调用

4、执行destroy销毁方法

第四步:Web工程停止的时候调用

12.5 继承HttpServlet实现Servlet程序

一般实际项目开发中,都是继承HttpServlet类的方式去实现Servlet程序

1、编写一个类继承 HttpServlet类

2、根据业务需求重写doGet、doPost方法

3、到web.xml配置Servlet的访问地址

12.6 Servlet继承体系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YyTYiT5u-1647142931686)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211221175900607.png)]

12.7 ServletConfig类

ServletConfig类是Servlet程序的配置信息类

Servlet程序和ServletConfig对象是由Tomcat负责创建,我们负责使用

Servlet程序默认是第一次访问的时候创建,ServletConfig是每个程序创建时,就创建一个对应的ServleyConfig对象

ServletConfig类的三大作用

  • 1.可以获取Servlet的别名servlet-name的值
  • 2.获取初始化参数init-param
  • 3.获取ServletContext对象

ServletConfig示例:

package com.atguigu.servlet;

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

public class HelloServlet implements Servlet {

    public HelloServlet() {
        System.out.println("1.构造函数");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2.初始化方法");
//        - 1.可以获取Servlet的别名servlet-name的值
        System.out.println("HelloServlet程序的别名" + servletConfig.getServletName());
//        - 2.获取初始化参数init-param
        System.out.println("初始化参数username的值" + servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值" + servletConfig.getInitParameter("url"));
//        - 3.获取ServletContext对象
        System.out.println(servletConfig.getServletContext());


    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * service方法是专门用来处理请求和响应的
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //类型转换(因为servletRequest有getMethod()方法)
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        //获取请求的方式
        String method = httpServletRequest.getMethod();
        if (method.equals("POST")){
            doPost();
        }else {
            doGet();
        }
    }

    /**
     * 做get请求的操作
     */
    public void doGet(){
       System.out.println("3.get 请求 service == hello servlet 已被访问!");
    }
    /**
     * 做post请求的操作
     */
    public void doPost(){
        System.out.println("3.post 请求 service == hello servlet 已被访问!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("4.destroy销毁方法");
    }
}

web.xml配置文件


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    
    <servlet>
        
        <servlet-name>HelloServletservlet-name>
        
        <servlet-class>com.atguigu.servlet.HelloServletservlet-class>
        
        <init-param>
            
            <param-name>usernameparam-name>
            
            <param-value>rootparam-value>
        init-param>
        
        <init-param>
            
            <param-name>urlparam-name>
            
            <param-value>jdbc:mysql//127.0.0.1:3306/bjpowernodeparam-value>
        init-param>
    servlet>

    
    <servlet-mapping>
        
        <servlet-name>HelloServletservlet-name>
        
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
    
    <servlet>
        <servlet-name>HelloServlet2servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet2servlet-class>
    servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet2servlet-name>
        <url-pattern>/hello2url-pattern>
    servlet-mapping>

    <servlet>
        <servlet-name>HelloServlet3servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet3servlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet3servlet-name>
        <url-pattern>/hello3url-pattern>
    servlet-mapping>
web-app>

12.8 ServletContext接口

1、ServletContext是一个接口,它表示上下文对象

2、一个Web工程,只有一个ServletContext对象实例

3、ServletContext对象是一个域对象

4、ServletContext是在web工程启动的时候创建,在web工程停止的时候销毁

什么是域对象?

域对象,是可以像Map一样存储数据的对象,叫域对象。

这里的域指的是存储数据的操作范围

			存数据				取数据				删除数据
-----------------------------------------------------------------
Map			put()			  get()				remove()
-----------------------------------------------------------------
域对象		  setAttrlbute()	getAttrlbute()	  removeAttrlbute()

ServletContext类的四个作用

1、获取web.xml中配置的上下文参数 context-paran

2、获取当前工程的路径,格式:/工程路径

3、获取工程部署在服务器硬盘上的绝对路径

4、像Map一样存储数据

示例:

package com.atguigu.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取web.xml中配置的上下文参数	context-paran
        ServletContext context = getServletConfig().getServletContext();
        String username = context.getInitParameter("username");
        System.out.println("username的值是" + username);

        String password = context.getInitParameter("password");
        System.out.println("password的值是" + password);
        //2、获取当前工程的路径,格式:/工程路径
        String contextPath = context.getContextPath();
        System.out.println("获取当前工程路径" + contextPath);
        //3、获取工程部署在服务器硬盘上的绝对路径
        /**
         * /斜杠被服务器解析的地址为:http://ip:port/工程名/    映射到IDEA代码的web目录
         */
        String realPath = context.getRealPath("/");
        System.out.println("获取当前工程部署的路径" + realPath);
        System.out.println("获取当前工程部署的css目录的绝对路径" + context.getRealPath("/css"));
        System.out.println("获取当前工程部署的yun.jpg的绝对路径" + context.getRealPath("/images/yun.jpg"));
    }

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

    }
}

web.xml配置文件


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <context-param>
        <param-name>usernameparam-name>
        <param-value>adminparam-value>
    context-param>
    
    <context-param>
        <param-name>passwordparam-name>
        <param-value>rootparam-value>
    context-param>

    
    <servlet>
        
        <servlet-name>HelloServletservlet-name>
        
        <servlet-class>com.atguigu.servlet.HelloServletservlet-class>
        
        <init-param>
            
            <param-name>usernameparam-name>
            
            <param-value>rootparam-value>
        init-param>
        
        <init-param>
            
            <param-name>urlparam-name>
            
            <param-value>jdbc:mysql//127.0.0.1:3306/bjpowernodeparam-value>
        init-param>
    servlet>

    
    <servlet-mapping>
        
        <servlet-name>HelloServletservlet-name>
        
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
    
    <servlet>
        <servlet-name>HelloServlet2servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet2servlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet2servlet-name>
        <url-pattern>/hello2url-pattern>
    servlet-mapping>

    <servlet>
        <servlet-name>HelloServlet3servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet3servlet-class>
    servlet>
   
    <servlet-mapping>
        <servlet-name>HelloServlet3servlet-name>
        <url-pattern>/hello3url-pattern>
    servlet-mapping>
    <servlet>
        <servlet-name>ContextServletservlet-name>
        <servlet-class>com.atguigu.servlet.ContextServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>ContextServletservlet-name>
        <url-pattern>/ContextServleturl-pattern>
    servlet-mapping>
web-app>

13、Http协议

什么是Http协议

协议是指双方,或多方相互约定,大家需要遵守的规则,叫协议。

所谓Http协议,就是指,客户端与服务器之间通信时,发送的数据,需要遵守的规则,叫Http协议。

Http协议中的数据又叫报文

13.1 请求的Http协议格式

客户端给服务器发送数据叫请求

服务器给客户端回传数据叫响应

GET请求
  • 1.请求行
    • (1)请求的方式 GET
    • (2)请求的资源路径[+?请求参数]
    • 请求的协议版本号 Http/1.1
  • 2.请求头
    • key:value 组成 不同的键值,表示不同含义。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SF6HTrLz-1647142931686)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224122946413.png)]

POST请求
  • 1.请求行
    • (1)请求的方式 GET
    • (2)请求的资源路径[+?请求参数]
    • 请求的协议版本号 Http/1.1
  • 2.请求头
    • key:value 组成 不同的键值,表示不同含义。
    • 空行
  • 3.请求体
    • 就是发送给服务器的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cf5hU2Qh-1647142931687)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224124228227.png)]

常用的请求头说明

**Accept:**表示客户端可以接收的数据类型

**Accept-Language:**表示客户端可以接收的语言类型

**Host:**表示请求时的服务器IP和端口号

哪些是GET请求,哪些是POST请求

GET请求有哪些

1、form标签 method = get

2、a标签

3、link标签引入css样式

4、script标签引入js文件

5、img标签引入图片

6、iframe引入html页面

7、在浏览器地址栏输入地址后敲回车

POST请求有哪些

1、form标签 method = post

13.2 响应的Http协议格式

  • 1.响应行
    • 响应的协议版和本号
    • 响应状态码
    • 响应状态描述符
  • 2.响应头
    • key:value 不同的响应头,有其含义不同
    • 空行
  • 3.响应体
    • 回传数据给客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2N5GDJ2q-1647142931687)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224150629730.png)]

13.3 常见的响应码说明

200 表示请求成功

302 表示请求重定向

404 表示请求服务器已收到,但你要的数据不存在(请求地址错误)

500 表示服务器已收到请求,但是服务器内部错误(代码错误)

13.4MIME类型说明

MIME是HTTP协议中数据类型。
MIME的英文全称是"Mutipurpose Internet Mail Extensions”多功能Internet邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LmvqjpyO-1647142931688)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224230352017.png)]

14、HttpServletRequest类

14.1 HttpServletRequest的作用

每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的Http协议信息解析好封装到Request对象中。然后传递到service方法(doGet和doPost)中给我们使用,我们可以通过HttpServletRequest对象,获取到所有请求的信息。

14.2HttpServletRequest类的常用方法

方法 描述
getRequestURI() 获取请求资源路径
getRequestURL() 获取请求的统一资源定位符(绝对路径)
getRemoteHost() 获取客户端的IP地址
getHeader() 获取请求头
getMethod() 获取请求的方式GET或POST
getParameter() 获取请求的参数
getParameterValues() 获取请求的参数(获取多个值的时候使用)
setCharacterEncoding() 设置请求体的字符集(从而解决post请求的中文乱码问题)

14.3 请求转发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K9QK83Hu-1647142931688)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211225185052078.png)]

请求转发的特点:

  1. 浏览器地址栏没有发生变化
  2. 它们是一次请求
  3. 可以转发到WEB-INF目录下
  4. 不可以访问工程以外的资源

示例:

Servlet1

package com.atguigu.servlet;

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

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数(办事的材料)查看
        String username = req.getParameter("username");
        System.out.println("在Servlet1(柜台1)中查看参数(材料):" + username);
        //给材料盖一个章,并传递到Servlet2去(柜台2)
        req.setAttribute("key","柜台1的章");
        //问路Servlet怎么走
        /**
         * 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/资源名 , 映射到IDEA代码的web目录
*/ RequestDispatcher requestDispatcher = req.getRequestDispatcher("/Servlet2"); //访问WEB-INF目录下的form.html文件 // RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/form.html"); //走向柜台2 requestDispatcher.forward(req,resp); } }

Servlet2

package com.atguigu.servlet;

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

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数(办事的材料)查看
        String username = req.getParameter("username");
        System.out.println("在Servlet2(柜台2)中查看参数(材料):" + username);
        //查看柜台1是否有盖章
        Object key = req.getAttribute("key");
        System.out.println("柜台1是否有章:" + key);
        System.out.println("Servlet2处理自己的业务");
    }
}

14.4 base 标签的作用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cBdtXuNE-1647142931688)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211228164231746.png)]


<html lang="zh_CN">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    
    <base href="http://localhost:8080/07_servlet/a/b/">
head>
<body>
    这是 a 下的 b 下的 c.html 页面<br/>
    <a href="../../index.html">跳回首页a><br/>
body>
html>

14.5 Web 中的相对路径和绝对路径

在 javaWeb 中,路径分为相对路径和绝对路径两种:

相对路径是:

  • . 表示当前目录
  • … 表示上一级目录
  • 资源名 表示当前目录/资源名

绝对路径: http://ip:port/工程路径/资源路径

在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。

1、绝对路径

2、base+相对

14.6 web 中 / 斜杠的不同意义

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

18、HttpServletResponse 类

18.1 HttpServletResponse类的作用

HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传 递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息, 我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse 对象来进行设置

18.2 两个输入流的说明

字节流 getOutputStream(); 常用于下载(传递二进制数据)

字符流 getWriter(); 常用于回传字符串(常用)

注意:

两个流只能使用一个。

使用了字节流,就不能使用字符流,反之亦然,否则报错

18.3 如何往客户端回传数据

示例:

package com.atguigu.servlet;

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

public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //-------------方法一
        //设置服务器字符集UTF-8
        resp.setCharacterEncoding("UTF-8");
        //通过响应头 设置浏览器字符集UTF-8
        resp.setHeader("content-Type","text/html;charset=UTF-8");
        
        //-------------方法二
        // 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
        // 此方法一定要在获取流对象之前调用才有效
        resp.setContentType("text/html;charset=UTF-8");
        
        //往客户端回传 字符串 数据
        PrintWriter writer = resp.getWriter();
        writer.write("张二狗");
    }
}

18.4 请求重定向

请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说,我给你一些地址,你去访问新的地址,叫请求重定向(因为之前的地址可能已经废弃)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PIG47CNO-1647142931689)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211229180235416.png)]

//请求重定向的第一种方案: 

// 设置响应状态码 302 ,表示重定向,(已搬迁) 

resp.setStatus(302);

 // 设置响应头,说明 新的地址在哪里 

resp.setHeader("Location", "http://localhost:8080");

//请求重定向的第二种方案(推荐使用): 

resp.sendRedirect("http://localhost:8080");


19、JavaEE项目的三层架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-njPZ1Uo8-1647142931689)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211229191216462.png)]

20、Jsp

20.1 什么是jsp

JSP的全称是 (Java Server Pages) Java的服务器页面

JSP的主要作用是代替Servlet程序回传html页面的数据

因为Servlet程序回传html页面数据是极其繁琐的事情,开发和维护成本极高

20.2 JSP的本质

jsp的本质上是一个Servlet程序

当我们第一次访问jsp页面的时候,tomcat服务器会帮我们把jsp页面翻译成为一个Java源文件,并且对它进行编译成为.class字节码文件程序。打开Java源文件不难发现其里面的内容是:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T5Z64QLW-1647142931690)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220101153953673.png)]

跟踪源码发现,HttpJspBase类,它直接继承了HttpServlet类,也就是说,jsp翻译出来的类,它简介继承HttpServlet类,也就是说,翻译出来的是一个Servlet程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WfvPee6U-1647142931690)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220101155407543.png)]

总结:通过翻译的 java 源代码我们就可以得到结果:jsp 就是 Servlet 程序。 可以去观察翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传 给客户端

20.3 JSP的三种语法

20.3.1 JSP的page指令

jsp的page指令可以修改jsp页面中一些重要的属性,或者行为。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%--language 属性							表示jsp翻译后是什么语言文件,暂时只支持Java--%> 
<%--contentType 属性						表示jsp返回的数据类型是什么,也是源码中的中 response.setContentType()参数值--%>
<%--pageEnconding 属性					表示当前jsp页面文件本身的字符集--%>
<%--import 属性							跟Java源代码一样,用于导包,导类--%>
<%--=================================================两个属性是给out输出流使用===================================================--%>
<%--autoFlush 属性						设置当out输出流缓冲区满了之后,是否自动刷新冲级区。默认值是true--%>
<%--buffer 属性							设置out缓冲区的大小,默认是8kb--%>
<%--========================================================================================================================--%>
<%--errorPage 属性						设置jsp页面运行出错时,自动跳转去的错误页面路径--%>
<%-- isErrorPage 属性 					设置当前 jsp 页面是否是错误信息页面。默认是 false。如果是 true 可以获取异常信息--%>
<%--session 属性 							设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true。--%>
<%--extends 属性 							设置 jsp 翻译出来的 java 类默认继承谁--%>
20.3.2 JSP常用脚本
声明脚本(极少使用)

声明脚本的格式:<%! 声明Java代码 %>

作用:可以给jsp翻译出来Java类定义的属性和方法甚至是静态代码块,内部类等。

示例:

<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/1
  Time: 14:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

这是html页面!!!

<%-- 声明类属性 --%> <%! private Integer id; private String name; private static Mapmap; %> <%-- 声明静态代码块 --%> <%! static { map = new HashMap<>(); map.put("猿1","val1"); map.put("猿2","val2"); map.put("猿3","val3"); } %> <%-- 声明类方法 --%> <%! public int add(){ return 1; } %> <%-- 声明内部类 --%> <%! public static class A{ private int id = 12; private String name = "张二狗"; } %>

jsp运行生成的Java源码文件

        private Integer id;
        private String name;
        private static Map<String, Object>map;
    

        static {
            map = new HashMap<>();
            map.put("猿1","val1");
            map.put("猿2","val2");
            map.put("猿3","val3");
        }
    

        public int add(){
            return 1;
        }
    

        public static class A{
            private int id = 12;
            private String name = "张二狗";
        }
表达式脚本(常用)

表达式脚本格式:<%= 表达式 %>

表达式脚本的作用:在jsp页面上输出数据。

表达式脚本的特点:

  • 所有的表达式脚本都会翻译到_jspService()方法中
  • 表达式脚本会翻译成out.print()输出到页面中
  • 由于表达式脚本翻译的内容都在_jspService() 方法中,所以_jspService()方法中的对象都可以直接使用
  • 表达式脚本中的表达式不能以分号结束

示例:

<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/1
  Time: 14:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

这是html页面!!!

<%-- 声明类属性 --%> <%! private Integer id = 12; private String name = "hello"; private static Mapmap; %> <%-- 声明静态代码块 --%> <%! static { map = new HashMap<>(); map.put("猿1","val1"); map.put("猿2","val2"); map.put("猿3","val3"); } %> <%-- 声明类方法 --%> <%! public int add(){ return 1; } %> <%-- 声明内部类 --%> <%! public static class A{ private int id = 12; private String name = "张二狗"; } %> <%-- 1. 输出整型 2. 输出浮点型 3. 输出字符串 4. 输出对像 --%> <%=12%>
<%=12.21%>
<%="张二狗"%>
<%=map%>
<%=id%> <%=name%>
代码脚本

脚本格式:<% Java语句 %>

代码脚本的作用是:可以在jsp页面中,编写我们自己需要的功能(写的是Java语句)

代码脚本的特点:

  1. 代码脚本翻译之后都在_jspService方法中
  2. 代码脚本由于翻译到_jspService方法中,所以在 _jspService方法中的现有对象都可以以直接调用
  3. 还可以有多个代码脚本块组合完成一个完整的Java语句。
  4. 代码脚本还可以和表达式脚本一起组合使用,在jsp页面输出数据

示例:

<%@ page import="java.util.HashMap" %>
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/1
  Time: 14:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


        <%--2.代码脚本----for 循环语句--%>
    <%
        for (int i = 1 ; i < 10 ; i++){
    %>
        

<%=i%> <% } %> <%--3.翻译后java文件中_jspService方法内的代码都可以写--%> <% String username = request.getParameter("username"); System.out.printf(username); %>

20.4 JSP九大内置对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3FwhpSRI-1647142931690)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220102163237447.png)]

request						请求对象
response					响应对象
pageContext					jsp的上下文对象
session						会话对象
application					ServletContext对象
config						ServletConfig对象
out							jsp输出流对象
page						指向当前的jsp对象
exception					异常对象

20.5 JSP四大域对象

pageContext (PageContextImol类)						当前jsp页面范围内有效
request		(HttpServletRequest类)					一次请求内有效
session		(HttpSessino类)							一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)
application	(ServletContext类)						整个web工程范围内有效(只要web工程不停止,数据还在)

20.6 JSP中的out输出和response.getWriter输出的区别

response中表示响应,我们经常用于设置返回客户端的内容(输出)

out也是给用户做输出使用的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b65dC411-1647142931691)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220103182545735.png)]

由于jsp翻译之后,底层源码都是使用out来进行输出,所以一般情况下,我们在jsp页面中统一使用out来进行输出,避免打乱页面输出的内容的顺序

out.write()输出字符串没有问题

out.print()输出任意数据都没有问题(都会转换成字符串后调用的write输出)

深入源码,浅出结论:在jsp页面中,可以统一使用out.print()来进行输出

20.7 JSP的常用标签

20.7.1 静态包含
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/3
  Time: 18:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%--
        <%@ include file="" %> 就是静态包含
            file 属性指定你要包含的jsp页面的路径
            地址中的第一个斜杠 / 表示:http://ip:prot/工程路径/映射到代码的web目录
        静态包含特点:
            1.静态包含不会翻译被包含的jsp页面
            2.静态包含其实是把被包含的jsp页面的jsp页面的代码拷贝到包含的位置执行输出
    --%>
    头部
主体
<%@ include file="/include/footer.jsp" %>
20.7.2 动态包含
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/3
  Time: 18:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%--
         
              page 属性指定你要包含的jsp页面的路径
              地址中的第一个斜杠 / 表示:http://ip:prot/工程路径/映射到代码的web目录
         动态包含特点:
              1.动态包含会把包含的jsp页面也翻译成Java代码
              2.动态包含底层代码使用如下代码去调用被包含的jsp页面执行输出。
                JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false)
              3.动态包含,还可以传递参数
    --%>
    头部
主体

动态包含的底层实现原理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hDVHrJre-1647142931691)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220103192828863.png)]

20.7.3 JSP标签-请求转发
<%--
     是请求转发标签,它的功能就是请求转发
        page 属性设置请求转发的路径
--%>

20.8 练习

乘法口诀示例一:

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/3
  Time: 20:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title
    






    <%
        for (int i = 1; i <= 9; i++) {%>
    
        <%
            for (int j = 1; j <= i; j++) {


        %>
        
        <%
            }
        %>
    
    <%
        }
    %>

<%= j + "x" + i + "=" + (i * j)%>

输出一个表格,里面有 10 个学生信息示例二:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ez9w8ZeJ-1647142931692)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220109163331550.png)]

student类

package com.chan;

public class Student {

    private int id;
    private String name;
    private int age;
    private int phone;

  //省略get、set、构造函数、toString方法 
}

SearchStudentServlet类

package com.chan.servlet;

import com.chan.Student;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class SearchStudentServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求的参数
        // 发 sql 语句查询学生的信息
        // 使用 for 循环生成查询到的数据做模拟
        List<Student> studentList = new ArrayList<>();
        for (int i = 0 ; i < 10 ; i++){
            int t = i + 1;
            studentList.add(new Student(t,"name"+ t,10+t,185774565+t));
        }
        // 保存查询到的结果(学生信息)到 request 域中
        req.setAttribute("studentList",studentList);
        // 请求转发到 showStudent.jsp 页
        req.getRequestDispatcher("/Test/showStudent.jsp").forward(req,resp);
    }
}

showStudent.jsp页面

<%@ page import="java.util.List" %>
<%@ page import="com.chan.Student" %>
<%@ page import="java.util.ArrayList" %><%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/3
  Time: 21:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title
    


<%--获取保存在域中的数据--%>
<%
    List studentList = (List)request.getAttribute("studentList");
%>

    <%
        for (Student student : studentList) {
    %>
    
    <%
        }
    %>
学号 名字 年龄 联系方式 操作
<%=student.getId()%> <%=student.getName()%> <%=student.getAge()%> <%=student.getPhone()%> 删除 修改

20.9 Listener监听器

  1. Listener监听器它是JavaWeb三大组件之一,JavaWeb的三大组件分别是:Servlet,Filter过滤器,Listener监听器
  2. Listener它是JavaEE的规范,就是接口
  3. 监听器的作用是,监听某事务的变化,然后通过回调函数,反馈给客户(程序)去做一些相应的处理
20.9.1 ServletContextListener监听器

ServletContextListener它可以监听ServletContext对象的创建和销毁

ServletContext对象在web工程启动的时候创建,在web工程停止时销毁

监听到创建和销毁之后都会分别调用ServletContextListener监听器的方法进行反馈。

两个方法分别是:

package javax.servlet;

import java.util.EventListener;

public interface ServletContextListener extends EventListener {
	/*
	 *在ServletContext对象创建之后马上调用,做初始化
	 */
    void contextInitialized(ServletContextEvent var1);
	/*
	 *在ServletContext对象销毁之后马上调用
	 */
    void contextDestroyed(ServletContextEvent var1);
}

如何使用ServletContextListener监听器监听ServletContext对象

使用步骤如下:

编写一个类实现ServletContextLisetener => 实现两个回调函数 => web.xml中配置监听器

实现类MyServletContextListenerImpl

package com.chan.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListenerImpl implements ServletContextListener {
    //实现两个回调函数
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.printf("ServletContext对象被创建了------------------------------>>>");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.printf("ServletContext对象被销毁了------------------------------>>>");
    }
}

web.xml中配置监听器


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.chan.listener.MyServletContextListenerImpllistener-class>
    listener>
web-app>

20.10 EL 表达式

20.10.1 什么是EL表达式,EL表达式的作用

EL表达式的全称是:Experssion Language,是表达式语言

EL表达式的作用:EL表达式作用主要代替jsp页面中的表达式脚本在jsp页面中进行数据的输出

因为EL表达式在输出数据的时候,要比jsp的表达式脚本要简洁

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/9
  Time: 17:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%
    request.setAttribute("key1","");
    %>
    <%=request.getAttribute("key") == null ? "" : request.getAttribute("key1")%>
    
${key}

EL 表达式的格式是:${表达式}

EL 表达式在输出 null 值的时候,输出的是空串。jsp 表达式脚本输出 null 值的时候,输出的是 null 字符串

20.10.2 EL表达式搜索域数据的顺序

EL表达式主要是是在jsp页面输出数据

主要输出的是域对象中的数据

当四个域中都相同的key的数据的时候,EL表达式会按照从小到大的顺序去进行搜索,找打就输出

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/9
  Time: 18:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


<%--  往四个域中保存相同的key数据  --%>
<%
    request.setAttribute("key","request");
    session.setAttribute("key","session");
    application.setAttribute("key","application");
    pageContext.setAttribute("key","pageContext");
%>

    ${key}


20.10.3 EL 表达式输出 Bean 的普通属性,数组属性。List 集 合属性,map 集合属性

需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性

package com.chan;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class Person {

    private String name;
    private String[] phones;
    private List cities;
    private Map map;
    private int age = 100;

    //省略get、set、构造函数、toString方法 
}

3.jsp输出的代码:

<%@ page import="com.chan.Person" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/9
  Time: 18:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%
        Person person = new Person();
        person.setName("张二狗");
        person.setPhones(new String[]{"1857745874","184655412545","48216485184"});
        List stringList = new ArrayList<>();
        stringList.add("南宁");
        stringList.add("广州");
        stringList.add("上海");
        person.setCities(stringList);

        Map map = new HashMap<>();
        map.put("key1",12341);
        map.put("key2",12342);
        map.put("key3",12343);
        map.put("key4",12344);
        person.setMap(map);
        pageContext.setAttribute("p",person);
    %>

    输出person:${p}
输出person的name属性:${p.name}
输出person的phones数组属性:${p.phones[0]}
输出 Person 的 cities 集合中的元素值:${p.cities}
输出 Person 的 List 集合中个别元素值:${p.cities[0]}
输出 Person 的 Map 集合: ${p.map}
输出 Person 的 Map 集合中某个 key 的值: ${p.map.key2}
输出 Person 的 age 属性:${p.age}
20.10.4 EL 表达式——运算

语法:${运算表达式},EL表达式支持如下运算符:

关系运算
关系运算符 说明
== 或 eq 等于
!= 或 ne 不等于
< 或 lt 小于
> 或 gt 大于
<= 或 le 小于等于
>= 或 ge 大于等于
逻辑运算
逻辑运算符 说明
&& 或 and
|| 或 or
! 或 not 取反
算数运算
算数运算符 说明
+ 加法
- 减法
* 乘法
/ 或 div 除法
% 或 mod 取模

示例:

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/9
  Time: 19:26
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    关系运算:
${12 == 12} 或 ${12 eq 12}
${12 != 12} 或 ${12 ne 12}
${12 < 12} 或 ${12 lt 12}
${12 > 12} 或 ${12 gt 12}
${12 <= 12} 或 ${12 le 12}
${12 >= 12} 或 ${12 ge 12}
逻辑运算:
${12 == 12 && 12 == 12} 或 ${12 == 12 and 12 == 12}
${12 != 12 || 12 > 12} 或 ${12 != 12 || 12 > 12}
${!true} 或 ${not true}
算数运算:
${12 + 12}
${12 - 12}
${12 * 12}
${12 / 12} 或 ${12 div 12}
${15 % 12} 或 ${15 mod 12}
empty运算

empty运算可以判断一个数据是否为空,如果为空,则输出true,不为空则输出false

以下几种情况为空:

  1. 值为null值的时候,为空
  2. 值为空串的时候,为空
  3. 值为Object类型数组,长度为零的时候
  4. list集合,元素个数为零
  5. map集合,元素个数为零
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/9
  Time: 19:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%
        //值为null值的时候,为空
        request.setAttribute("emptyNull",null);
        //值为空串的时候,为空
        request.setAttribute("emptyStr","");
        //值是 Object 类型数组,长度为零的时候
        request.setAttribute("emptyArr",new Object[]{});
        //list 集合,元素个数为零
        List list = new ArrayList<>();
        request.setAttribute("emptyList",list);
        //map 集合,元素个数为零
        Map map = new HashMap<>();
        request.setAttribute("emptyMap",map);
    %>

    ${empty emptyNull}
    ${empty emptyStr}
    ${empty emptyArr}
    ${empty emptyList}
    ${empty emptyMap}


三元运算

表达式一 ? 表达式二 : 表达式三

如果表达式 1 的值为真,返回表达式 2 的值,如果表达式 1 的值为假,返回表达式 3 的值

${12 == 12 ? "对的" : "假的"}
”.“点运算和 []中括号运算符

.运算,可以输出Bean对象中某个属性的值

[]中括号运算,可以输出有序集合中某个元素的值

并且中括号运算,还可以输出map集合中key里含有特殊字符的key的值

EL表达式的11个隐含对象

EL表达式中11个隐含对象,是EL表达式中自己定义的,可以直接使用

变量 类型 作用
pageContext PageContextimpl 它可以获取jsp中的九大内置对象
pageScope Map 它可以获取pageContext域中的数据
requestScope Map 它可以获取Request域中的数据
sessionScope Map 它可以获取Session域中的数据
applicationScope Map 它可以获取ServletContext域中的数据
param Map 它可以获取请求参数的值
paramValues Map 它可以获取请求参数的值,获取多个值的时候使用
header Map 它可以获取请求头的信息
headerValues Map 它可以获取请求头的信息,获取多个请求头的时候使用
cookie Map 它可以获取当前请求的Cookie信息
initParam Map 它可以获取在web.xml中配置的上下文参数

获取四大域对象示例:

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/10
  Time: 16:21
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%
        pageContext.setAttribute("key1","pageContext");
        pageContext.setAttribute("key2","pageContext");
        request.setAttribute("key2","request");
        session.setAttribute("key2","session");
        application.setAttribute("key2","application");
    %>

    ${applicationScope.key2}


pageContext的使用
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/10
  Time: 16:27
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%--
        request.getScheme();        获取请求的协议
        request.getServerName();    获取服务器的IP或域名
        request.getServerProt();    获取服务器的请求端口号
        request.getContextpath();   获取当前的工程路径
        request.getMethod();        获取请求方式
        request.getRemoteHost();    获取客户端的IP地址
        session.getID();            获取会话的唯一标识
    --%>

    <%
        pageContext.setAttribute("req",request);
    %>

    <%=request.getServerPort()%>
1.协议:${req.scheme}
2.服务器IP:${req.serverName}
3.服务器端口号:${req.serverPort}
4.工程路径:${req.contextPath}
5.请求方式:${req.method}
6.客户端ip:${req.remoteHost}
7.会话唯一标识:${req.session.id}
EL 表达式其他隐含对象的使用
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/10
  Time: 17:26
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


输出请求参数username的值:${param.username}
输出请求参数password的值:${param.password}
输出请求参数username的值:${paramValues.username[0]}
输出请求参数hobby的值:${paramValues.hobby[0]}
输出请求参数hobby的值:${paramValues.hobby[1]}

输出请求头【User-Agent】的值:${header['User-Agent']}
输出请求头【Connection】的值:${header.Connection}
输出请求头【User-Agent】的值:${headerValues['User-Agent'][0]}

获取Cookie的名称:${cookie.JSESSIONID.name}
获取Cookie的值:${cookie.JSESSIONID.value}

输出<Context-param>username的值:${initParam.username}
输出<Context-param>url的值:${initParam.password}

20.11 JSTL标签库

JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP 标 签库。

EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面 变得更佳简洁

JSTL由五个不同功能的标签库组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-deoLhjPM-1647142931692)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220110175121020.png)]

在 jsp 标签库中使用 taglib 指令引入标签库

CORE 标签库

<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

XML 标签库

<%@ taglib prefix=“x” uri=“http://java.sun.com/jsp/jstl/xml” %>

FMT 标签库

<%@ taglib prefix=“fmt” uri=“http://java.sun.com/jsp/jstl/fmt” %>

SQL 标签库 <%@ taglib prefix=“sql” uri=“http://java.sun.com/jsp/jstl/sql” %>

FUNCTIONS 标签库

<%@ taglib prefix=“fn” uri=“http://java.sun.com/jsp/jstl/functions” %>

JSTL 标签库的使用步骤

1、先导入 jstl 标签库的 jar 包。 taglibs-standard-impl.jar taglibs-standard-spe.jar

2、第二步,使用 taglib 指令引入标签库。 <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

20.11.1core 核心库使用

示例:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="C" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/10
  Time: 18:01
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title



<%-------------------------------------------------------------------------------------------------------%>
    <%--
        
        作用:set标签可以往域中保存数据
        域对象.setAttribute(key,value)
        scope 属性设置保存到那个域
            page表示pageContext域(默认值)
            request表示Request域
            session表示Session域
            application表示ServletContext域
        var属性设置key的值
        value属性设置value的值
     --%>
    保存前:${sessionScope.abc}

保存后:${sessionScope.abc}
<%-------------------------------------------------------------------------------------------------------%> <%-- if标签用来做if判断 test属性表示判断的条件(使用EL表达式输出) --%>

12等于12

12不等于12

<%-- 作用多路判断,跟switch...case...default非常接近 choose标签开始选择判断 when标签表示每一种的判断条件 otherwise标签表示when之外的条件 注意: 1.标签内不能使用html注释,要使用jsp注释 2.when标签的父标签一定要是choose标签 --%> <%request.setAttribute("key",171);%> 身高:${requestScope.key}

一般

还行

正常

平均水平

forEach示例:

<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="com.chan.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/12
  Time: 23:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title
    


    <%--
        遍历1到10,输出
        begin属性设置开始的索引
        end 属性设置结束的索引
        var 属性表示循环的变量(也是当前正在遍历到的数据)
        for (int i = 1; i < 10; i++)
    --%>


    
                
${i}
<%-- 遍历Object数组 for (Object item: arr) items 表示遍历的数据源(遍历的集合) var 表示当前遍历到的数据 --%> <%request.setAttribute("arr",new String[]{"18610541354","18688886666","18699998888"});%> ${item}

<% Map map = new HashMap<>(); map.put("map1",1234561); map.put("map2",1234562); map.put("map3",1234563); map.put("map4",1234564); request.setAttribute("map",map); %>

${maps}

${maps.key} --------- ${maps.value}
<%-- 遍历List集合---list中存放 Student类,有属性:编号,用户名,密码,年龄,电话信息 --%> <% List studentList = new ArrayList<>(); for (int i = 1 ; i <= 10 ; i++ ){ studentList.add(new Student(00+i,"name" + i, 18 + i ,1857745497+i)); } request.setAttribute("students",studentList); %> <%-- items 表示遍历的集合 var 表示遍历到的数据 begin表示遍历的开始索引值 end 表示结束的索引值 step 属性表示遍历的步长值 varStatus 属性表示当前遍历到的数据的状态 for(int i = 1; i < 10; i+=2) --%>
编号 名字 年龄 电话 操作
${student.id} ${student.name} ${student.age} ${student.phone} 编辑 删除

21、文件的上传和下载

文件的上传和下载,是非常常见的功能。很多的系统中,或者软件中都经常使用文件的上传和下载。 比如:QQ 头像,就使用了上传。 邮箱中也有附件的上传和下载功能。 OA 系统中审批有附件材料的上传

21.1 文件上传

  1. 要有一个form标签,method="post"请求
  2. form标签的encType属性值必须为multipart/form-data值
  3. 在form标签使用input type=“file” 添加上传的文件
  4. 编写服务器代码(Servlet程序)接收,处理上传的数据

encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N5BjTNWw-1647142931692)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220114182312182.png)]

21.2 commons-fileupload.jar 常用 API

commons-fileupload.jar 需要依赖 commons-io.jar 这个包,所以两个包我们都要引入

commons-fileupload.jar 和 commons-io.jar 包中,我们常用的类有哪些

fileupload和io类 描述
ServletFileUpload类 用于解析上传的数据
FileItem类 表示每一个表单项
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request) 判断当前上传的数据格式是否是多段的格式
public List parseRequest(HttpServletRequest request) 解析上传的数据
boolean FileItem.isFormField() 判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。 true 表示普通类型的表单项 false 表示上传的文件类型
String FileItem.getFieldName() 获取表单项的 name 属性值
String FileItem.getString() 获取当前表单项的值。
String FileItem.getName() 获取上传的文件名
void FileItem.write( file ) 将上传的文件写到 参数 file 所指向硬盘位置

文件上传示例:

servlet处理程序

package com.chan.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class UploadServlet extends HttpServlet {

    /**
     * 用来处理上传的数据
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.先判断上传的数据是否是多段数据(只有多段数据才是文件上传)
        if (ServletFileUpload.isMultipartContent(req)){
            //创建FileItemFactory工厂实现类
            FileItemFactory fileItemFactory = new DiskFileItemFactory();
            //创建用于解析上传数据的工具类ServletUpload类
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

            try {
                //解析上传的数据,得到每一个表单项FileItem , FileItem 表示每一个表单项
                List list = servletFileUpload.parseRequest(req);
                // 循环判断,每一个表单项,是普通类型,还是上传的文件
                for (FileItem fileItem : list){
                    if (fileItem.isFormField()){
                        //普通表单项
                        System.out.println("表单项的name属性值:" + fileItem.getFieldName());
                        //参数UTF-8,解决乱码问题
                        System.out.println("表单项的value值:" + fileItem.getString("UTF-8"));
                    }else {
                        //上传的文件
                        System.out.println("表单项的name属性值:" + fileItem.getFieldName());
                        System.out.println("上传的文件名:" + fileItem.getName());
                        //将上传的文件写入硬盘
                        fileItem.write(new File("i:\\" + fileItem.getName()));
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

jsp上传文件数据

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/14
  Time: 17:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    
用户名: 头像:

21.3 文件下载

下载的常用 API 说明:

response.getOutputStream();

servletContext.getResourceAsStream();

servletContext.getMimeType();

response.setContentType();

response.setHeader(“Content-Disposition”, “attachment; fileName=1.jpg”); 这个响应头告诉浏览器。这是需要下载的。而 attachment 表示附件,也就是下载的一个文件。fileName=后面, 表示下载的文件名。 完成上面的两个步骤,下载文件是没问题了。但是如果我们要下载的文件是中文名的话。你会发现,下载无法正确 显示出正确的中文名。 原因是在响应头中,不能包含有中文字符,只能包含 ASCII

附件中文名乱码问题解决方案:

方案一:URLEncoder 解决 IE 和谷歌浏览器的 附件中 文名问题。

如果客户端浏览器是 IE 浏览器 或者 是谷歌浏览器。我们需要使用 URLEncoder 类先对中文名进行 UTF-8 的编码 操作。 因为 IE 浏览器和谷歌浏览器收到含有编码后的字符串后会以 UTF-8 字符集进行解码显示。

 // 把中文名进行 UTF-8 编码操作。

 String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");

 // 然后把编码后的字符串设置到响应头中

 response.setHeader("Content-Disposition", str);

方案二:BASE64 编解码 解决 火狐浏览器的附件中文名问题

如果客户端浏览器是火狐浏览器。 那么我们需要对中文名进行 BASE64 的编码操作。

这时候需要把请求头 Content-Disposition: attachment; filename=中文名

编码成为:Content-Disposition: attachment; filename==?charset?B?xxxxx?=

=?charset?B?xxxxx?= 现在我们对这段内容进行一下说明。

=?

charset

B

xxxx

?=

BASE64 编解码操作:

因为火狐使用的是 BASE64 的编解码方式还原响应中的汉字。

所以需要使用 BASE64Encoder 类进行编码操作。

// 使用下面的格式进行 BASE64 编码后 
String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";

 // 设置到响应头中 

response.setHeader("Content-Disposition", str)

文件下载示例:

package com.chan.servlet;

import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

public class Download extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取要下载的文件名
        String downloadFileName = "1.jpg";
        //读取要下载的文件内容(通过ServletContext对象可以读取)
        ServletContext servletContext = getServletContext();
        //获取要下载的文件类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        System.out.println("下载的文件类型" + mimeType);
        //在回传前,通过响应头告诉客户端返回的数据类型
       resp.setContentType(mimeType);
        //告诉客户端收到的数据是用于下载使用(通过响应头)
        //Content-Disposition 响应头,表示收到的数据怎么处理
        //attachment 表示附件,表示下载使用
        // fileName= 表示指定的下载名
        //url编码是把汉字转换成为%xx%xx的格式
        if (req.getHeader("User-Agent").contains("Firefox")){
            //如果是火狐浏览器使用Base64编码
            resp.setHeader("Content-Disposition","attachment; fileName==?utf-8?B?" + new BASE64Encoder().encode("风铃.jpg".getBytes("UTF-8")));
        }else {
            //IE或谷歌使用URL编码操作
            resp.setHeader("Content-Disposition","attachment; fileName=" + URLEncoder.encode("风铃.jpg","UTF-8"));
        }
        InputStream inputStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
        //设置响应的输出流
        OutputStream outputStream = resp.getOutputStream();
        //把下载的文件内容回传给客户端
        //读取输入流中的全部数据,复制给输出流,输出给客户端
        IOUtils.copy(inputStream,outputStream);
    }
}

22、数据的封装和抽取 BeanUtils 的使用

BeanUtils 工具类,它可以一次性的把所有请求的参数注入到 JavaBean 中。

BeanUtils 工具类,经常用于把 Map 中的值注入到 JavaBean 中,或者是对象属性值的拷贝操作。

BeanUtils 它不是 Jdk 的类。

而是第三方的工具类。

所以需要导包。

1、导入需要的 jar 包: commons-beanutils.jar commons-logging.jar

2、编写 WebUtils 工具类使用:

示例:

package com.atguigu.utils;

import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

public class WebUtils {

    /**
     * 把 Map 中的值注入到对应的JavaBean属性中
     * @param value
     * @param bean
     * @param 
     * @return  请求参数
     */
    public static  T copyParamToBean(Map value , T bean){

        try {

            System.out.println("注入前:" + bean);
            //把所有的请求参数都注入user对象中
            BeanUtils.populate(bean,value);
            System.out.println("注入后:" + bean);

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return bean;
    }
}

22、MVC 概念

MVC 全称:Model 模型、 View 视图、 Controller 控制器。

MVC 最早出现在 JavaEE 三层中的 Web 层,它可以有效的指导 Web 层的代码如何有效分离,单独工作。

**View 视图:**只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员和美工的分工合作—— JSP/HTML。

**Controller 控制器:**只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色——Servlet。 转到某个页面。或者是重定向到某个页面。

**Model 模型:**将与业务逻辑相关的数据封装为具体的 JavaBean 类,其中不掺杂任何与数据处理相关的代码—— JavaBean/domain/entity/pojo。

MVC 是一种思想 MVC 的理念是将软件代码拆分成为组件,单独开发,组合使用(目的还是为了降低耦合度)。

23、Cookie 饼干

  1. 什么是Cookie?
    1. Cookie翻译过来是饼干的意思
    2. Cookie是服务器通知客户端保存键值对的一种技术
    3. 客户端有了Cookie后,每次请求都会发送给服务器
    4. 每个Cookie的大小不能超过4kb

23.1 如何创建Cookie

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1j2KYjtZ-1647142931693)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220122183913234.png)]

Servlet程序

package com.chan.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CookieServlet extends BaseServlet{
	
    /**
     * 创建Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //创建Cookie对象
        Cookie cookie = new Cookie("key1","value1");
        //通知客户端保存Cookie
        resp.addCookie(cookie);

        resp.getWriter().write("Cookie已创建!!!");
    }

}

23.2 服务器如何获取Cookie

​ 服务器获取客户端的 Cookie 只需要一行代码:req.getCookies():Cookie[]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iRZJ5mW8-1647142931693)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220122190046532.png)]

  1. Cookie的工具类
package com.chan.Utils;

import javax.servlet.http.Cookie;

public class CookieUtils {

    /**
     * 查询指定名称的Cookie对象
     * @param name
     * @param cookies
     * @return
     */
    public static Cookie findCookie(String name , Cookie[] cookies){

        if (name == null || cookies == null || cookies.length == 0){
            return null;
        }

        for (Cookie cookie : cookies){
            if (name.equals(cookie.getName())){
                return cookie;
            }
        }

        return null;
    }
}

Servlet程序

package com.chan.servlet;

import com.chan.Utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

public class CookieServlet extends BaseServlet{
	
     /**
     * 服务器获取Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            // getName 方法返回 Cookie 的 key(名)
            // getValue 方法返回 Cookie 的 value
            resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
"
); } Cookie iWantCookie = CookieUtils.findCookie("key1",cookies); // 如果不等于 null,说明赋过值,也就是找到了需要的 Cooki if (iWantCookie != null){ resp.getWriter().write("找到所需key"); } } protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建Cookie对象 Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8")); Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8")); Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8")); //通知客户端保存Cookie resp.addCookie(cookie); resp.addCookie(cookie2); resp.addCookie(cookie3); resp.getWriter().write("Cookie已创建!!!"); } }

23.3 Cookie 值的修改

方案一:

  1. 先创建一个要修改的同名(指的是key)的Cookie对象
  2. 在构造器,同时赋新的Cookie值
  3. 调用resp.addCookie(cookie);
package com.chan.servlet;

import com.chan.Utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

public class CookieServlet extends BaseServlet{

    /**
     * 修改Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void upDateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
    //1. 先创建一个要修改的同名(指的是key)的Cookie对象

    //2. 在构造器,同时赋新的Cookie值
        Cookie cookie = new Cookie("key1","newValue");
    //3. 调用resp.addCookie(cookie);
        resp.addCookie(cookie);
        resp.getWriter().write("已修改");
    }
    /**
     * 服务器获取Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            // getName 方法返回 Cookie 的 key(名)
            // getValue 方法返回 Cookie 的 value
            resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
"
); } Cookie iWantCookie = CookieUtils.findCookie("key1",cookies); // 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie if (iWantCookie != null){ resp.getWriter().write("找到所需key"); } } /** * 创建Cookie * @param req * @param resp * @throws ServletException * @throws IOException */ protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建Cookie对象 Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8")); Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8")); Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8")); //通知客户端保存Cookie resp.addCookie(cookie); resp.addCookie(cookie2); resp.addCookie(cookie3); resp.getWriter().write("Cookie已创建!!!"); } }

方案二:

  1. 先查找到需要修改的 Cookie 对象
  2. 调用 setValue()方法赋于新的 Cookie 值
  3. 调用 response.addCookie()通知客户端保存修改
package com.chan.servlet;

import com.chan.Utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

public class CookieServlet extends BaseServlet{

    /**
     * 修改Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void upDataCookie2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        //方案二:
        //1. 先查找到需要修改的 Cookie 对象
        Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
        if (cookie != null){
            //2. 调用 setValue()方法赋于新的 Cookie 值
            cookie.setValue("newValue2");
            //3. 调用 response.addCookie()通知客户端保存修改
            resp.addCookie(cookie);
        }
    }
    /**
     * 修改Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void upDateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{

        //方案一
        //1. 先创建一个要修改的同名(指的是key)的Cookie对象
        //2. 在构造器,同时赋新的Cookie值
        Cookie cookie = new Cookie("key1","newValue");
        //3. 调用resp.addCookie(cookie);
        resp.addCookie(cookie);
        resp.getWriter().write("已修改");
    }
    /**
     * 服务器获取Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            // getName 方法返回 Cookie 的 key(名)
            // getValue 方法返回 Cookie 的 value
            resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
"
); } Cookie iWantCookie = CookieUtils.findCookie("key1",cookies); // 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie if (iWantCookie != null){ resp.getWriter().write("找到所需key"); } } /** * 创建Cookie * @param req * @param resp * @throws ServletException * @throws IOException */ protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建Cookie对象 Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8")); Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8")); Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8")); //通知客户端保存Cookie resp.addCookie(cookie); resp.addCookie(cookie2); resp.addCookie(cookie3); resp.getWriter().write("Cookie已创建!!!"); } }

23.4 Cookie的生命控制

Cookie的生命控制指的是如何管理Cookie什么时候被销毁(删除)

setMaxAge()

  • 正数:表示指定的数秒后过期
  • 负数:表示浏览器一关,Cookie就会被删除(默认值是-1)
  • 零:表示马上删除Cookie
package com.chan.servlet;

import com.chan.Utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

public class CookieServlet extends BaseServlet{

    /**
     * 设置存活一小时的Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("life3600","life3600");
        cookie.setMaxAge(3600);
        resp.addCookie(cookie);
        resp.getWriter().write("存活一小时的Cookie已创建");
    }
    /**
     * Cookie的生命控制 立即删除
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void deleteImmediately(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        Cookie cookie = CookieUtils.findCookie("key1",req.getCookies());
        cookie.setMaxAge(0);
        resp.addCookie(cookie);
    }

    /**
     * Cookie的生命控制 默认的会话级别
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        Cookie cookie = new Cookie("defaultLife","defaultLife");
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);
    }
    /**
     * 修改Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void upDataCookie2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        //方案二:
        //1. 先查找到需要修改的 Cookie 对象
        Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
        if (cookie != null){
            //2. 调用 setValue()方法赋于新的 Cookie 值
            cookie.setValue("newValue2");
            //3. 调用 response.addCookie()通知客户端保存修改
            resp.addCookie(cookie);
        }
    }
    /**
     * 修改Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void upDateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{

        //方案一
        //1. 先创建一个要修改的同名(指的是key)的Cookie对象
        //2. 在构造器,同时赋新的Cookie值
        Cookie cookie = new Cookie("key1","newValue");
        //3. 调用resp.addCookie(cookie);
        resp.addCookie(cookie);
        resp.getWriter().write("已修改");
    }
    /**
     * 服务器获取Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            // getName 方法返回 Cookie 的 key(名)
            // getValue 方法返回 Cookie 的 value
            resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
"
); } Cookie iWantCookie = CookieUtils.findCookie("key1",cookies); // 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie if (iWantCookie != null){ resp.getWriter().write("找到所需key"); } } /** * 创建Cookie * @param req * @param resp * @throws ServletException * @throws IOException */ protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建Cookie对象 Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8")); Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8")); Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8")); //通知客户端保存Cookie resp.addCookie(cookie); resp.addCookie(cookie2); resp.addCookie(cookie3); resp.getWriter().write("Cookie已创建!!!"); } }

23.5 Cookie 有效路径 Path 的设置

Cookie的Path属性可以有效的过滤哪些Cookie 可以发送给服务器,哪些不发

Path属性是通过请求的地址来进行有效的过滤

示例:

CookieA path=/工程路径

CookieB path=/工程路径/abc

请求地址:

http://ip:port/工程路径/a.html

​ CookieA发送

​ CookieB不发送

http://ip:port/工程路径/abc/a.html

​ CookieA发送

​ CookieB发送

package com.chan.servlet;

import com.chan.Utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

public class CookieServlet extends BaseServlet{

    /**
     * Cookie 有效路径 Path 的设置
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void textPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("path1","path1");
        cookie.setPath(req.getContextPath() + "/abc");      // == /工程路径/abc
        resp.addCookie(cookie);
        resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");
    }
}

23.6 Cookie–练习免输入用户名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYFdrvrI-1647142931694)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220123191650798.png)]

login.jsp

<%--
  Created by IntelliJ IDEA.
  User: 鬼
  Date: 2022/1/23
  Time: 19:18
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


用户名:
密码:

LoginServlet程序

package com.chan.servlet;

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

public class LoginServlet extends HttpServlet {

    /**
     * 面用户名登录模拟
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //将用户名存入Cookie
        Cookie cookie = new Cookie("username",username);

        if ("admin".equals(username) && "password".equals(password)){
            System.out.println("登陆成功");
            //登陆成功通知浏览器保存信息
            resp.addCookie(cookie);
        }else {
            System.out.println("登陆失败");
        }
    }
}

23.7 Session会话

  1. Session就一个接口(HttpSession)
  2. Session就是会话,它是用来维护一个客户端和服务器之间关联的一种技术
  3. 每个客户端都有自己的一个Session会话
  4. Session会话中,我们经常用来保存用登录之后的信息

23.8 创建Session和获取(id号,是否为新)

如何创建和获取Session,它们的API是一样的 request.getSession()

​ 第一次调用是:Session会话创建的时候

​ 之后调用的都是:获取前面创建好的Session会话对象

isNew(); 判断是否是新创建出来的

​ true:表示新创建

​ false:表示获取之前的

每个会话都有一个身份证号,也就是id值,而这个id值是唯一的

getId(); 得到Session的会话id值

示例:

package com.chan.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet extends BaseServlet{

    protected void getSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Session会话对象
        HttpSession session = req.getSession();
        //判断当前Session会话,是否是新创建出来的
        boolean aNew = session.isNew();
        //获取Session会话的唯一标识符
        String id = session.getId();

        resp.getWriter().write("得到Session的id是:" + id + "
"); resp.getWriter().write("Session是否新创建的" + aNew ); } }

23.9 Session域中存取数据

package com.chan.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet extends BaseServlet{
	
     /**
     * 往Session中存储数据
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void setAttributes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().setAttribute("key1","value");
        resp.getWriter().write("已经在Session中保存了数据");
    }

     /**
     * 获取Session中的数据
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getAttributes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object key1 = req.getSession().getAttribute("key1");
        resp.getWriter().write("从Session中获取key1的数据是:" + key1);
    }
}

23.10 Session的生命周期控制

public void setMaxInactiveInterval(int interval) 设置Session的超时时间(以秒为单位),指定超时的时长,Session就会被销毁

​ 值为正数的时候,设定Session的超时时长

​ 负数表示永不超时(极少使用)

public int getMaxInactiveInterval()获取 Session 的超时时长

public void invalidate() 让当前 Session 会话马上超时无效

Session的默认时长是多少

Session的默认时长是30分钟

因为Tomcat服务器的配置文件web.xml中默认有以下配置,它就是表示配置当前Tomcat服务器下所有的Session超时时长为30分钟

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

如果说。你希望你的 web 工程,默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做 以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长。


<session-config>
	<session-timeout>20session-timeout>
session-config>

如果你只想修改某个Session的时长,就可以使用上面的API,setMaxInactiveInterval(int interval) 来进行单独的设置

​ session.setMaxInactiveInterval(int interval)单独设置超时时长

Session的超时概念介绍:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSoyMU3P-1647142931694)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220124112135867.png)]

package com.chan.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet extends BaseServlet{

    /**
     * Session马上超时
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Session对象
        HttpSession session = req.getSession();
        //设置Session马上超时时长
        session.invalidate();
        resp.getWriter().write("当前Session马上销毁");
    }

    /**
     * Session三秒后超时
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Session对象
        HttpSession session = req.getSession();
        //设置Session三秒超时时长
        session.setMaxInactiveInterval(3);
        resp.getWriter().write("当前Session三秒后销毁");
    }

    /**
     *  Session的默认时长
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getDefaultDuration(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        int maxInactiveInterval = session.getMaxInactiveInterval();

        resp.getWriter().write("Session的默认时长:" + maxInactiveInterval + "秒");
    }
}

23.11 浏览器和Session之间关联的技术内幕

Session 技术,底层实现其实是基于Cookie技术来实现的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCs7apyN-1647142931694)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220124113504686.png)]

24、Filter过滤器

  1. Filter 过滤器是 Java Web三大组件之一,三大组件分别是Servlet程序、Listener监听器、Filter过滤器

  2. Filter 过滤器是 JavaEE 的规范,也是接口

  3. Filter 过滤器 它的作用是:拦截请求,过滤响应

    拦截请求常见的应用场景:

    1. 权限检查

    2. 日记操作

    3. 事务管理

      等等…

24.1 Filter示例:

在 web 工程下,有一个 Filter 目录。这个 Filter 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必 须是用户登录之后才允许访问。

用户登录之后都会把用户登录的信息保存到 Session 域中。所以要检查用户是否 登录,可以判断 Session 中否包含有用户登录的信息即可!!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HwHtQKQD-1647142931695)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220214145904509.png)]

Filter 的代码:

package com.chan.servlet;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class FilterServletTest implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * doFilter 方法,专门用于拦截请求。可以做权限检查
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        HttpSession session = httpServletRequest.getSession();

        Object user = session.getAttribute("user");

        //判断用户是否登录
        if (user == null){
            //没有登录跳转登录页
            servletRequest.getRequestDispatcher("/Filter/login.jsp").forward(servletRequest,servletResponse);
            return;
        }else {
            //让程序继续访问用户的目标资源
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

web.xml 中的配置:


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    
    <filter>
        
        <filter-name>FilterServletTestfilter-name>
        
        <filter-class>com.chan.servlet.FilterServletTestfilter-class>
    filter>

    
    <filter-mapping>
        <filter-name>FilterServletTestfilter-name>
        
        <url-pattern>/Filter/a.htmlurl-pattern>
    filter-mapping>
    
web-app>

24.2 Filter 过滤器的使用步骤:

1、编写一个类去实现 Filter 接口

2、实现过滤方法 doFilter()

3、到 web.xml 中去配置 Filter 的拦截路径

24.3 Filter 生命周期

Filter 的生命周期包含几个方法

  1. 构造器方法

  2. init初始化方法

    第1,2不,在web工程启动的时候执行(Filter已经创建)

  3. doFilter 过滤方法

    第3不,,每次拦截到请求,就会执行

  4. destroy 销毁

    第4不,停止web工程的时候,就会执行(停止web工程,也就会销毁Filter过滤器)

24.4 FilterConfig 类

FilterConfig 类见名知意,它是Filter 过滤器的配置文件类

Tomcat每次创建Filter的时候,也会创建一个FilterConfig类,这里包含Filter配置文件的配置信息

FilterConfig类的作用是获取filter过滤器的配置内容

  1. 获取Filter的名称filter-name的内容
  2. 获取在Filter中配置的init-param初始化参数
  3. 获取ServletContext对象

Java代码

package com.chan.servlet;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class FilterServletTest implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        //1、获取 Filter 的名称 filter-name 的内容
        System.out.println("filter-name的值" + filterConfig.getFilterName());
        //2、获取在 web.xml 中配置的 init-param 初始化参数
        System.out.println("初始化username的值是:" + filterConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是:" + filterConfig.getInitParameter("url"));
        //3、获取 ServletContext 对像
        System.out.println(filterConfig.getServletContext());
    }

    /**
     * doFilter 方法,专门用于拦截请求。可以做权限检查
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }

}

web.xml配置文件


<filter>
    
    <filter-name>FilterServletTestfilter-name>
    
    <filter-class>com.chan.servlet.FilterServletTestfilter-class>
    
    <init-param>
        <param-name>usernameparam-name>
        <param-value>rootparam-value>
    init-param>
    <init-param>
        <param-name>urlparam-name>
        <param-value>jdbc://127.0.1.1/3306param-value>
    init-param>
filter>


<filter-mapping>
    <filter-name>FilterServletTestfilter-name>
    
    <url-pattern>/Filter/a.htmlurl-pattern>
filter-mapping>

24.5 FilterChain 过滤器链

Filter 过滤器

Chain 链,链条

FilterChain就是过滤器链(多个过滤器协同工作)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8W1e3EM-1647142931695)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220214181942570.png)]

24.6 Filter 的拦截路径

精确匹配

/target.jsp

以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/target.jsp

目录匹配

/admin/*

以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/admin/*

后缀名匹配

*.html

以上配置的路径,表示请求地址必须以.html 结尾才会拦截到

*.do

以上配置的路径,表示请求地址必须以.do 结尾才会拦截到

*.action

以上配置的路径,表示请求地址必须以.action 结尾才会拦截到

Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!

25、ThreadLocal

ThreadLocal的作用,它可以解决线程的数据安全问题

ThreadLocal它可以给当前线程关联一个数据(可以是普通变量、数组、集合)

ThreadLocal的特点:

  1. ThreadLocal可以为当前线程关联一个数据(它可以像Map一样存储数据,key为当前线程)
  2. 每个ThreadLocal对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据就需要使用多个ThreadLocal对象实例
  3. 每个ThreadLocal对象定义的时候,一般都是static类型
  4. ThreadLocal中保存数据,在线程销毁后,会由JVM虚拟自动释放

测试类:

package com.chan.threadlocal;

import java.util.Hashtable;
import java.util.Map;
import java.util.Random;

public class ThreadLocalText {

    //public static Map data = new Hashtable();
    public static ThreadLocal threadLocal = new ThreadLocal<>();
    private static Random random = new Random();

    public static class Task implements Runnable{

        @Override
        public void run() {
            // 获取当前线程名
            String name = Thread.currentThread().getName();
            // 在Run方法中,随机生成一个变量(线程要关联的数据),然后以当前线程名为key保存到map中
            int i = random.nextInt(1000);
            System.out.println("线程["+name+"]生成的随机数是:" + i);
            //data.put(name,i)
            threadLocal.set(i);

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 在Run方法结束之前,以当前线程名获取出数据并打印。查看是否可以取出操作
            new OrderService().createOrder();
            //Object o = data.get(name);
            Object o = threadLocal.get();
            System.out.println("在线程["+name+"]快结束时取出关联的数据是:" + o);
        }
    }

    public static void main(String[] args) {
        for (int i = 0 ; i < 3 ; i++){
            new Thread(new Task()).start();
        }
    }
}


26、Filter 和 ThreadLocal 组合管理事

使用 ThreadLocal 来确保所有 dao 操作都在同一个 Connection 连接对象中完成

原理图分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tBVcfoRj-1647142931695)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220216170921101.png)]

Jdbc工具类的修改

package com.atchan.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtils {

    private static DruidDataSource dataSource;
    private static ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();
    static {
        try {
            Properties properties = new Properties();
            // 读取 jdbc.properties属性配置文件
            InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("resources/jdbc.properties");
            // 从流中加载数据
            properties.load(inputStream);
            // 创建 数据库连接 池
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取数据库连接池中的连接
     * @return 如果返回null,说明获取连接失败 / 有值就是获取连接成功
     */
    public static Connection getConnection(){

        Connection conn = connectionThreadLocal.get();

        if (conn == null){
            try {
                //从数据库连接池中获取连接
                conn = dataSource.getConnection();
                //保存到ThreadLocal对象中,供后面的jdbc操作使用
                connectionThreadLocal.set(conn);
                //设置为手动提交事务
                conn.setAutoCommit(false);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return conn;
    }

    /**
     * 提交事务,并关闭释放连接
     */
    public static void commitAndCols(){
        Connection connection = connectionThreadLocal.get();
        //如果不等于null,说明使用过连接,操作过数据库
        if (connection != null){
            try {
                //提交事务
                connection.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    //关闭连接,释放资源
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //一定要执行remove操作,否则会出错 (因为Tomcat服务器底层使用了线程池技术)
        connectionThreadLocal.remove();
    }

    /**
     * 回滚事务事务,并关闭释放连接
     */
    public static void rollbackAndClose(){
        Connection connection = connectionThreadLocal.get();
        //如果不等于null,说明使用过连接,操作过数据库
        if (connection != null){
            try {
                //回滚事务
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    //关闭连接,释放资源
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //一定要执行remove操作,否则会出错 (因为Tomcat服务器底层使用了线程池技术)
        connectionThreadLocal.remove();
    }


    /**
     * 关闭连接,放回数据库连接池
     * @param conn
     */
    /*
    public static void close(Connection conn){
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
     */
}

27、JSON

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON 采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C, C++, C#, Java, JavaScript, Perl, Python 等)。 这样就使得 JSON 成为理想的数据交换格式

  1. json 是一种轻量级的数据交换格式
  2. 轻量级指的是跟 xml 做比较
  3. 数据交换指的是客户端和服务器之间业务数据的传递格式

27.1 JSON的定义


<html>
	<head>
		<meta http-equiv="pragma" content="no-cache" />
		<meta http-equiv="cache-control" content="no-cache" />
		<meta http-equiv="Expires" content="0" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title heretitle>
		<script type="text/javascript">
			// json的定义
			let jsonObj = {
				"key1" : 12,
				"key2" : "abc",
				"key3" : true,
				"key4" : [11, true, "arr"],
				"key5" : {
					"key5_1" : 551,
					"key5_2" : "key5_2Value"
				},
				"key6" : [{
						"key6_1_1":6611,
						"key6_1_2":"key6_1_2_value"
					},{
						"key6_2_1":6621,
						"key6_2_2":"key6_2_2_value"
				}]
			};

			// json的访问
			// json对象转字符串
			// json字符串转json对象
		script>
	head>
	<body>
		
	body>
html>

27.2 JSON的访问

JSON本身就是一个对象

JSON中的key我们可以理解为是对象的一个属性

JSON中的key访问就跟访问对象中的属性一样:json对象.key

JSON访问示例:


<html>
   <head>
      <meta http-equiv="pragma" content="no-cache" />
      <meta http-equiv="cache-control" content="no-cache" />
      <meta http-equiv="Expires" content="0" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title heretitle>
      <script type="text/javascript">
         // json的定义
         let jsonObj = {
            "key1" : 12,
            "key2" : "abc",
            "key3" : true,
            "key4" : [11, true, "arr"],
            "key5" : {
               "key5_1" : 551,
               "key5_2" : "key5_2Value"
            },
            "key6" : [{
                  "key6_1_1":6611,
                  "key6_1_2":"key6_1_2_value"
               },{
                  "key6_2_1":6621,
                  "key6_2_2":"key6_2_2_value"
            }]
         };

         // json的访问
         let key1 = jsonObj.key1;
         console.log(key1)  //12
         console.log(jsonObj.key2)	//abc
         console.log(jsonObj.key3)	//true
          //遍历json中的数组
         for (let i = 0 ; i < jsonObj.key4.length ; i++){
            let key4Element = jsonObj.key4[i];
            console.log(key4Element)
         }
         let key51 = jsonObj.key5.key5_2;	//"key5_2Value"
         console.log(key51)
         let key6Element
         for (let i = 0 ; i < jsonObj.key6.length ; i++){
            key6Element = jsonObj.key6[i];
            console.log(key6Element.key6_2_1)
         }
         // json对象转字符串
         
         // json字符串转json对象
      script>
   head>
   <body>
      
   body>
html>

27.3 JSON 的两个常用方法

json存在的两种形式

  • 一种是:对象的形式存在,我们叫它json对象
  • 一种是:字符串的形式存在,我们叫它json字符串
  • 一般我们要操作json中的数据的时候,需要json对象的格式
  • 一般我们要在客户端和服务器之间进行数据交换的时候,使用json字符串

JSON.stringify() 把json对象转字符串

JSON.parse() json字符串转json对象

示例代码:


<html>
	<head>
		<meta http-equiv="pragma" content="no-cache" />
		<meta http-equiv="cache-control" content="no-cache" />
		<meta http-equiv="Expires" content="0" />
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title heretitle>
		<script type="text/javascript">
			// json的定义
			let jsonObj = {
				"key1" : 12,
				"key2" : "abc",
				"key3" : true,
				"key4" : [11, true, "arr"],
				"key5" : {
					"key5_1" : 551,
					"key5_2" : "key5_2Value"
				},
				"key6" : [{
						"key6_1_1":6611,
						"key6_1_2":"key6_1_2_value"
					},{
						"key6_2_1":6621,
						"key6_2_2":"key6_2_2_value"
				}]
			};
			
			// json对象转字符串
			let stringify = JSON.stringify(jsonObj);
			console.log(stringify)
			// json字符串转json对象
			let parse = JSON.parse(stringify);
			console.log(parse)
		script>
	head>
	<body>
		
	body>
html>

27.4 JSON 在 java 中的使用

27.4.1 JavaBean和json的互转
package JSONTest;

import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaBeanJsonTest {

    @Test
    public void test1(){
        Student student = new Student(1,"张三",18,15487894);
        Gson gson = new Gson();
        String toJson = gson.toJson(student);
        System.out.println(toJson);

        Object fromJson = gson.fromJson(toJson, Student.class);
        System.out.println(fromJson);
    }
}
27.4.2 List和json的互转
package JSONTest;

import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaBeanJsonTest {

    @Test
    public void Test2(){
        List studentList = new ArrayList<>();
        studentList.add(new Student(1,"张三",18,1564564));
        studentList.add(new Student(2,"李四",19,45645646));

        Gson gson = new Gson();
        String toJson = gson.toJson(studentList);
        System.out.println(toJson);

        Object o = gson.fromJson(toJson, new TypeToken>() {
        }.getType());
        System.out.println(o);
    }
}
27.4.3 Map和json的互转
package JSONTest;

import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaBeanJsonTest {
    @Test
    public void Test3(){
        Map<Integer, Student> studentMap = new HashMap<>();
        studentMap.put(1, new Student(1,"张三",18,1564564));
        studentMap.put(2, new Student(2,"李四",19,45645646));

        Gson gson = new Gson();

        String toJson = gson.toJson(studentMap);
        System.out.println(toJson);

        gson.fromJson(toJson , Map.class);
    }
}

28、AJAX请求

28.1 什么是Ajax请求

AJAX即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互网页应用的网页开发技术

Ajax是一种浏览器通过js异步发起请求,局部页面的更新技术

Ajax请求的局部更新,浏览器地址栏地址不会发送改变 局部更新不会舍弃原来页面的内容

原生Ajax请求示例:


<html>
   <head>
      <meta http-equiv="pragma" content="no-cache" />
      <meta http-equiv="cache-control" content="no-cache" />
      <meta http-equiv="Expires" content="0" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title heretitle>
      <script>
         // 在这里使用javaScript语言发起Ajax请求,访问服务器AjaxServlet中javaScriptAjax
         function ajaxRequest() {
            //1.首先创建xmlHttpRequest
            let xmlHttpRequest = new XMLHttpRequest();
            //2.调用open方法设置参数
            xmlHttpRequest.open("GET","http://localhost:8888/Java_Web_Jsp/ajaxServlet?action=JavaScriptAjax",true);
            //4.在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作
            xmlHttpRequest.onreadystatechange = function () {
               if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
                  let responseText = JSON.parse(xmlHttpRequest.responseText);
                  //把响应的数据响应在页面上
                  document.getElementById("div01").innerHTML = "编号:" + responseText.id + "姓名:" + responseText.name;
               }
            }
            //3.调用send方法发送请求
            xmlHttpRequest.send();

         }
      script>
   head>
   <body>
      <button onclick="ajaxRequest()">ajax requestbutton>
      <div id="div01">
      div>
   body>
html>

Servlet程序

package com.chan.servlet;

import com.chan.Student;
import com.google.gson.Gson;

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

public class AjaxServlet extends BaseServlet{

    protected void JavaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.printf("ajax请求");

        Student student = new Student(1,"韦天才",18,17823123);
        Gson gson = new Gson();
        String toJson = gson.toJson(student);
        resp.getWriter().write(toJson);
    }
}

28.2 jQuery中的Ajax请求

$.ajax方法
	url			表示请求的地址
	type		表示请求的类型GET或POST请求
	data		表示发送给服务器的数据
			格式有两种:
						1.name=value&name=value
						2.{key:value}
	success		请求成功,响应的回调函数
	dataType	响应的数据类型
					常用的数据类型有:
									text	表示纯文本
									xml		表示xml数据
									json	b
		"key5_2" : "key5_2Value"
			},
			"key6" : [{
					"key6_1_1":6611,
					"key6_1_2":"key6_1_2_value"
				},{
					"key6_2_1":6621,
					"key6_2_2":"key6_2_2_value"
			}]
		};
		
		// json对象转字符串
		let stringify = JSON.stringify(jsonObj);
		console.log(stringify)
		// json字符串转json对象
		let parse = JSON.parse(stringify);
		console.log(parse)
	


	

```

27.4 JSON 在 java 中的使用

27.4.1 JavaBean和json的互转
package JSONTest;

import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaBeanJsonTest {

    @Test
    public void test1(){
        Student student = new Student(1,"张三",18,15487894);
        Gson gson = new Gson();
        String toJson = gson.toJson(student);
        System.out.println(toJson);

        Object fromJson = gson.fromJson(toJson, Student.class);
        System.out.println(fromJson);
    }
}
27.4.2 List和json的互转
package JSONTest;

import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaBeanJsonTest {

    @Test
    public void Test2(){
        List studentList = new ArrayList<>();
        studentList.add(new Student(1,"张三",18,1564564));
        studentList.add(new Student(2,"李四",19,45645646));

        Gson gson = new Gson();
        String toJson = gson.toJson(studentList);
        System.out.println(toJson);

        Object o = gson.fromJson(toJson, new TypeToken>() {
        }.getType());
        System.out.println(o);
    }
}
27.4.3 Map和json的互转
package JSONTest;

import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaBeanJsonTest {
    @Test
    public void Test3(){
        Map<Integer, Student> studentMap = new HashMap<>();
        studentMap.put(1, new Student(1,"张三",18,1564564));
        studentMap.put(2, new Student(2,"李四",19,45645646));

        Gson gson = new Gson();

        String toJson = gson.toJson(studentMap);
        System.out.println(toJson);

        gson.fromJson(toJson , Map.class);
    }
}

28、AJAX请求

28.1 什么是Ajax请求

AJAX即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互网页应用的网页开发技术

Ajax是一种浏览器通过js异步发起请求,局部页面的更新技术

Ajax请求的局部更新,浏览器地址栏地址不会发送改变 局部更新不会舍弃原来页面的内容

原生Ajax请求示例:


<html>
   <head>
      <meta http-equiv="pragma" content="no-cache" />
      <meta http-equiv="cache-control" content="no-cache" />
      <meta http-equiv="Expires" content="0" />
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title heretitle>
      <script>
         // 在这里使用javaScript语言发起Ajax请求,访问服务器AjaxServlet中javaScriptAjax
         function ajaxRequest() {
            //1.首先创建xmlHttpRequest
            let xmlHttpRequest = new XMLHttpRequest();
            //2.调用open方法设置参数
            xmlHttpRequest.open("GET","http://localhost:8888/Java_Web_Jsp/ajaxServlet?action=JavaScriptAjax",true);
            //4.在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作
            xmlHttpRequest.onreadystatechange = function () {
               if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
                  let responseText = JSON.parse(xmlHttpRequest.responseText);
                  //把响应的数据响应在页面上
                  document.getElementById("div01").innerHTML = "编号:" + responseText.id + "姓名:" + responseText.name;
               }
            }
            //3.调用send方法发送请求
            xmlHttpRequest.send();

         }
      script>
   head>
   <body>
      <button onclick="ajaxRequest()">ajax requestbutton>
      <div id="div01">
      div>
   body>
html>

Servlet程序

package com.chan.servlet;

import com.chan.Student;
import com.google.gson.Gson;

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

public class AjaxServlet extends BaseServlet{

    protected void JavaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.printf("ajax请求");

        Student student = new Student(1,"韦天才",18,17823123);
        Gson gson = new Gson();
        String toJson = gson.toJson(student);
        resp.getWriter().write(toJson);
    }
}

28.2 jQuery中的Ajax请求

$.ajax方法
	url			表示请求的地址
	type		表示请求的类型GET或POST请求
	data		表示发送给服务器的数据
			格式有两种:
						1.name=value&name=value
						2.{key:value}
	success		请求成功,响应的回调函数
	dataType	响应的数据类型
					常用的数据类型有:
									text	表示纯文本
									xml		表示xml数据
									json	b

你可能感兴趣的:(tomcat,web)