javaweb阶段

Html和CSS

HTML + CSS + JavaScript

结构 + 表现 + 行为层

CSS:界面的样式

Html:界面的内容

![image-20211018213044996](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211018213044996.png)

HTML

Hyper Text Markup Language(超文本标记语言

超文本包括 : 文字、图片、音频、视频、动画等

HTML5,提供了一些新的元素和一些有趣的新特性,同时也建立了一些新的规则。

这些元素、特性和规则的建立,提供了许多新的网页功能,

如使用网页实现动态渲染图形、图表、图像和动画,以及不需要安装任何插件直接使用网页播放视频等。

W3C

![image-20211018214241064](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211018214241064.png)

HTML写法

<!-- DOCTYPE:告诉浏览器,我们要使用什么规范 -->
<!DOCTYPE html>
<!-- head标签代表网页头部 -->
<head>
    <!-- meta描述性标签,它用来描述我们网站的一些信息 -->
    <!-- meta一般用来做SEO -->
    <meta charset="UTF-8">
    
    <!-- title标签代表网页标题 -->
    <title></title>
</head>

<!-- body标签代表网页主体 -->
<body>
    <!-- 标题标签 -->
    <h1>
        一级标签
    </h1>
    <h2>
        二级标签
    </h2>
    <h3>
        三级标签,以此类推
    </h3>
    
    <!-- 段落标签 -->
    <p>
        跑得快    跑得快
    </p>
    
    <!-- 换行标签 -->
    一段话完了就可以换行<br/>
    
    <!-- 水平线标签 -->
    <hr/>用来隔开的
    
    <!-- 字体样式标签 -->
    <!-- 粗体,斜体 -->
    <strong>粗体</strong>
    <em>斜体</em>
    
    <!-- 注释和特殊符号 -->
    空格: &nbsp;代表一个格
    大于号: &gt;
    小于号: &lt;
    版权符号: &copy;
</body>
<!-- 这是注释的方法 -->
<body>、 </body>等成对的标签,分别叫开放标签和闭合标签

单独呈现的标签(空元素),如


;意为用/来关闭空元素

< meta>是自闭和标签,有一对的是闭合标签

标签

图像

![image-20211018221903828](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211018221903828.png)

<!-- img学习 
  src :图片地址(必填)
     相对地址(推荐使用),绝对地址
        ../   --上一级目录
  alt :图片名字(必填)
-->

链接

![image-20211018222748228](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211018222748228.png)

<!-- 使用name作为标记 -->
<a name="top">顶部</a>

<!--a标签
href: 必填,表示要跳转到那个页面
target:表示窗口在哪里打开
     _blank 在新标签中打开
     _self  在自己的网页中打开
-->
<a href="https://www.baidu.com" target="_self">点击我跳转到百度</a>

<!-- 锚链接
1.需要一个锚标记
2.跳转到标记
3.#标记名字
-->
<a href="#top">回到顶部</a>

<!--功能性链接
邮件链接: mailto
QQ链接
-->
<a href="mailto:1260307752@qq.com">点击联系我</a>

元素块

![image-20211018225048098](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211018225048098.png)

行内元素可以包在块元素里面,但块元素不能包在行内元素里

span标签也是行内元素,div,列表是块元素

列表

![image-20211020174554065](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211020174554065.png)

<!-- 有序列表
应用范围 : 试卷 ,问答。。。
-->
<ol>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ol>

<!-- 无序列表
应用范围 : 导航 ,侧边栏...
-->
<ul>
  <li>1</li>
  <li>3</li>
  <li>2</li>
</ul>

<!-- 自定义列表
dl : 标签
dt : 列表名称
dd : 列表内容

应用范围 : 公司网站底部
-->
<dl>
  <dt>学科</dt>
  
  <dd>1</dd>
  <dd>2</dd>
  <dd>3</dd>
</dl>

表格标签

<!-- 表格table
行 tr rows
列 td
边框 border
跨列 colspan
跨行 rowspan
-->
<table border="1px">
  <tr>
    <td colspan="4">1-1</td>
    <td rowspan="2">1-2</td>
    <td>1-3</td>
  </tr>
</table>

媒体标签

<!-- 音频和视频
src 资源路径
controls 控制视频
autoplay 自动播放
 -->
<video src="../src/.." controls autoplay></video>
<audio src="../src/.." controls autoplay></audio>

页面结构分析

![image-20211020180517751](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211020180517751.png)

<header>
    <h2>网页头部</h2>
</header>

<section>
    <h2>网页主体</h2>
</section>

<footer>
    <h2>网页脚部</h2>
</footer>

内联框架iframe

![image-20211020181843292](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211020181843292.png)

<!-- iframe内联框架
src : 地址
w-h : 宽度高度
-->
<iframe src="https://www.baidu.com" frameborder="0" width="1000px" height="800px">
</iframe>
<iframe src="//player.bilibili.com/player.html?aid=55631961&bvid=BV1x4411V75C&cid=97257967&page=11" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true">
</iframe>

表单

<h1>注册</h1>
<!-- 表单
formaction : 表单提交的位置 , 可以是网站 , 也可以是一个请求处理地
method : post , get 提交方式   
get方式提交 : 我们可以在url中看到我们提交的信息,不安全,高效.   
post : 比较安全 , 传输大文件.
-->
<form action="1.html" method="get">    
    <!-- 文本输入框 : input type="text-->
    <p>名字: <input type="text" name="username"></p>
    <!-- 密码框 : input type="password-->
    <p>名字: <input type="password" name="pwd"></p>
    <!-- submit : 提交 reset : 重置 -->
    <p><input type="submit"><input type="reset"> </p>
</form>

表单格式

![image-20211020183609960](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211020183609960.png)

<h1>注册</h1>
<!-- 表单form
action : 表单提交的位置 , 可以是网站,也可以是一个请求处理地址
method : post , get 提交方式
   get方式提交 : 我们可以在url中看到我们提交的信息,不安全,高效.
   post : 比较安全 , 传输大文件.
-->
<form action="1.html" method="get">
    <!-- 文本输入框 : input type="text
         默认初始值 : value="马云龙好帅"
         最长能写几个字符 : maxlength="8"
         文本框长度 : size="30"
    -->
    <p>名字: <input type="text" name="username"></p>

    <!-- 密码框 : input type="password-->
    <p>名字: <input type="password" name="pwd"></p>

    <!-- 单选框标签
    input type="radio"
          value : 单选框的值
          name : 表示组
    -->
    <p>性别:
        <input type="radio" value="boy" name="sex"/>男
        <input type="radio" value="girl" name="sex"/>女
    </p>

    <!-- 多选框
    input type="checkbox"
    checked : 默认选中
    -->
    <p>爱好
        <input type="checkbox" value="sleep" name="hobby" checked>睡觉
        <input type="checkbox" value="eat" name="hobby">吃饭
        <input type="checkbox" value="sleep" name="hobby">睡觉
        <input type="checkbox" value="sleep" name="hobby">睡觉
    </p>

    <!-- 按钮
    input type="button"普通按钮
    input type="image"图像按钮
    -->
    <p>
        <input type="button" name="btnl" value="点击变长">
        <input type="image" src="../">
    </p>
    <p>
        <!-- submit : 提交
             reset : 重置
         -->
        <input type="submit">
        <input type="reset">
    </p>
    
    <!-- 下拉框 , 列表框
    selected : 默认选中 
    -->
    <p>下拉框:
        <select name="列表名称">
            <option value="选项的值" selected>中国</option>
            <option value="选项的值">美国</option>
            <option value="选项的值">日本</option>
        </select>
    </p>
    
    <!-- 文本域
    cols : 列
    rows : 行
    -->
    <p>反馈:
        <textarea name="textarea" cols="10" rows="50">文本内容</textarea>
    </p>

    <!-- 文件域
    -->
    <p>
       <input type="file" name="files">
       <input type="button" value="上传" name="upload">
    </p>

    <!--邮件验证-->
    <p>邮箱:
        <input type="email" name="email">
    </p>
    <!--URL-->
    <p>URL:
        <input type="url" name="url">
    </p>

    <!--数字
    min : 最小值
    max : 最大值
    step : 每次修改的大小
    -->
    <p>商品数量:
        <input type="number" name="num" max="100" min="0" step="1">
    </p>

    <!--滑块-->
    <p>音量:
        <input type="range" name="voice" min="0" max="100" step="1">
    </p>

    <!--搜索框-->
    <p>搜索:
        <input type="search" name="search">
    </p>
</form>
<!-- readonly 只读     hidden 隐藏     disabled 禁用--><input type="text" readonly hidden disabled><!-- 增加鼠标可用性点对应的就会跳到相应的框--><label for="mark">点他</label><input type="search" name="search">

表单的初级验证

<!-- placeholder 提示信息     required  非空判断     pattern 正则表达式--><p>名字:     <input type="text" name="username" placeholder="请输入用户名" required></p><p>自定义邮箱:   <input type="text" name="diyemail" pattern="..."></p>

CSS

Cascading Style Sheet 层叠级联样式表

CSS : 表现(美化网页)

字体,颜色,边距,高度,宽度,背景图片,网页定位,网页浮动....

![image-20211023171631188](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211023171631188.png)

发展史

CSS1.0

CSS2.0 DIV(块) + CSS,HTML 与CSS结构分离的思想,网页变得简单,SEO

CSS2.1 浮动,定位

CSS3.0 圆角,阴影,动画.... 涉及到浏览器兼容性问题

HTML与CSS没有分离所用的方法<!-- 规范 : <style> 可以编写CSS的代码 , 每一个声明,最好使用分号结尾  语法:      选择器 {          声明1;          声明2;          声明3;      }  -->  <style>    h1{      color: red;    }  </style></head><body><h1>选中的</h1></body></html>
<!DOCTYPE html><head>    <meta charset="UTF-8">    <title>CSS与HTML分离</title>        <!--分离所用连接的方法,href是css代码的路径-->  <link rel="stylesheet" href="style.css">    </head><body><h1>选中的</h1></body></html><!-- style.css中的代码 -->h1{    color: red;}

CSS的优势

  1. 内容和表现分离

  2. 网页结构表现统一,可以实现复用

  3. 样式十分的丰富

  4. 建议使用独立于html的css文件、利用SEO,容易被搜索引擎收录!

    (Vue不容易被搜索引擎收录)

CSS的三种导入方式

html代码<head>    <!-- 内部样式 -->    <style>        h1{            color: green;        }    </style>      <link rel="stylesheet" href="style.css"></head><body><!-- 行内样式: 在标签元素中,编写一个style属性,编写样式即可不建议使用 当网站很庞大时,可以偷个懒--><h1 style="color: red">我是行内样式</h1></body>
style.css代码/*外部样式-->*/h1{    /*这是CSS的注释*/    /*caret-color: aliceblue;*/    color: yellow;}

优先级:行内样式优先级最高,内部样式和外部样式优先级一样并尊崇覆盖原则(代码:内部在外部上面,就是外部样式。外部在内部上面,就是内部样式)

【自上而下,取决于你的引用顺序,这里若将外部样式放入内部样式之前,则使用内部样式】

拓展 : 外部样式的两种写法

  • 链接式:

    html标签

     <!--外部样式--> <link rel="stylesheet" href="style.css">
    
  • 导入式:

    CSS2.1特有

    <!--导入式-->    <style>        h1{            @import url("style.css");        }    </style>
    

选择器

作用:选择页面上的某一个或者某一类元素

基本选择器

  1. 标签选择器:选择一类标签

    <head>    <meta charset="UTF-8">    <title>Title</title>    <style>        /* 标签选择器,会选择这个页面上的所有这个标签的元素        弊端:当想一个标签改变,其他不改就做不到了*/        h1{            color: #922020;            background: aliceblue;            border-radius: 24px;        }        p{            font-size: 80px;        }    </style></head><body><h1>学习</h1><h1>学java</h1><p>马</p></body>
    
  2. 类 选择器 class:选择所有class属性一致的标签,跨标签

    <head>    <style>        /* 类选择器的格式  .class的名称{}        好处,可以多个标签归类,是同一个class,可以复用        */        .ma{            color: red;        }        .ss{            color: aqua;        }    </style></head><body><h1 class="ma">学习</h1><h1 class="ss">学java</h1><p class="ma">马</p></body>
    
  3. id 选择器:全局唯一

    <head>    <style>        /* id选择器 : id必须保证全局唯一!           #id名称{}        */        #ma{            color: red;        }    </style></head><body><h1 id="ma" >学习</h1></body>
    

优先级:id选择器 > 类选择器 > 标签选择器

不遵循就近原则,固定的

层级选择器

  1. 后代选择器:在某个元素的后面 爷爷-->爸爸-->你

    <style>    /*后代选择器*/    body p{        /* body后面的p全变色 */        background: red;    }</style>
    
  2. 子选择器 一代,儿子

    <style>    /*子选择器*/    body>p{        /*只改变body下面的p,ul标签下的p不改*/        background: aqua;    }</style><body><p>p1</p><p>p2</p><p>p3</p><ul>    <li>        <p>p4</p>    </li>    <li>        <p>p5</p>    </li>    <li>        <p>p6</p>    </li></ul></body>
    
  3. 相邻兄弟选择器 同辈

    只选择类选择器下面的一个标签,对它操作(不对它自身操作)

    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            /*相邻弟选择器 : 只有一个,相邻(向下)*/
            .active + p{
                background: red;
            }
        </style>
    </head>
    <body>
    <p class="active">p1</p>
    <p>p2</p>
    <p>p3</p>
    <ul>
        <li>
            <p>p4</p>
        </li>
        <li>
            <p>p5</p>
        </li>
        <li>
            <p>p6</p>
        </li>
    </ul>
    </body>
    
  4. 通用兄弟选择器

    选择类选择器下面的所有同级标签,对它操作(不对它自身操作)

    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            /*通用兄弟选择器,当前选中元素的向下的所有兄弟元素*/
            .active~p{
                background: red;
            }
        </style>
    </head>
    <body>
    <p class="active">p1</p>
    <p>p2</p>
    <p>p3</p>
    <ul>
        <li>
            <p>p4</p>
        </li>
        <li>
            <p>p5</p>
        </li>
        <li>
            <p>p6</p>
        </li>
    </ul>
    </body>
    

结构 伪类选择器

<head>    <meta charset="UTF-8">    <title>Title</title>    <style>        /* ul的第一个子元素li */        ul li:first-child{            background: red;        }        /* ul的最后一子元素li */        ul li:last-child{            background: #ff4832;        }        /*选中 p1 :定位到父元素,选择当前的第一个元素        选择当前p元素的父级元素,选中父级元素的第一个,并且是当前元素才生效!        定位到该层级下的第一个元素,换数字就定位到对应数字的元素        */        p:nth-child(1){            background: #2700ff;        }        /*选中父元素下的p元素的第一个,p类型*/        p:nth-of-type(1){            background: yellow;        }                a:hover{            background: aqua;        }    </style></head><body><a href="">a1</a><h1>h1</h1><p>p1</p><p>p2</p><p>p3</p><ul>    <li>l1</li>    <li>l2</li>    <li>l3</li></ul></body>

属性选择器(常用)

id+class的结合

<head>    <meta charset="UTF-8">    <title>Title</title>    <style>        .demo a{            /*放的位置*/            float: left;            /*变成块级元素,none是没有*/            display: block;            /*高和宽*/            height: 50px;            width: 50px;            /*圆角边框*/            border-radius: 10px;            background: aqua;            /*对齐方式*/            text-align: center;            color: yellow;            /*下划线*/            text-decoration: none;            /*外边框偏移*/            margin-right: 5px;            /*行高*/            line-height: 50px;        }        /*属性名,属性名=属性值(正则)        =绝对等于        *=包含这个元素        ^=以这个开头        $=以这个结尾        */        /* 存在id属性的元素 */        a[id]{            background: yellow;        }        /* id=first的元素 */        a[id=first]{            background: #63ff23;        }        /* class中有inks的元素 */        a[class*=links]{            background: yellow;        }        /* 选中href中以http开头的元素 */        a[href^=http]{            background: yellow;        }        a[href$=pdf]{            background: aqua;        }    </style></head><body><p class="demo">    <a href="http://www.baidu.com" class="links item first" id="first">1</a>    <a href="" class="links item active" target="_blank" title="test">2</a>    <a href="images/123.html" class="links item">3</a>    <a href="images/123.png" class="links item" >4</a>    <a href="images/123.jpg" class="links item">5</a>    <a href="abc" class="links item">6</a>    <a href="/a.pdf" class="links item">7</a>    <a href=" /abc.pdf" class="links item">8</a>    <a href="abc.doc" class="links item">9</a>    <a href="abcd.doc" class="links item last">10</a></p></body>

美化网页元素

1、有效的传递页面信息
2、美化网页,页面漂亮,才能吸引用户

3、凸显页面的主题
4、提高用户的体验

span标签:重点要突出的字,使用span套起来

<!DOCTYPE html><html lang="en">    <head>        <meta charset="UTF-8">        <title>Title</title>                <style>            #title1{                font-size: 50px;            }        </style>    </head>    <body>        欢迎学习<span id="title1">Java</span>    </body></html>

字体样式

<!--font-family : 字体font-size : 字体大小font-weight : 字体粗细color : 字体颜色--><style>    body{        font-family : "Arial B1ack",楷体;        color: #a13d30;    }    h1{        font-size: 50px;    }    .p1{        font-weight: bolder;    }</style>

文本样式

  1. 颜色 color rgb rgba
  2. 文本对齐的方式 text-align = center
  3. 首行缩进 text-indent: 2em
  4. 行高 line-height: 单行文字上下居中! line-height = height
  5. 装饰 text-decoration:
<!--颜色:   单词   RGB O~F   RGBA A:0~1(透明度)text-align: 排版,居中(center)text-indent: 2em;段落首行缩进height: 300px;line-height: 300px;行高,和块的高度一致,就可以上下居中--><style>    h1{        color: rgba(0,255,255,0.9);        text-align: center;    }    .p1{        text-indent: 2em;    }    .p3{        background: #2700ff;        height: 300px;        line-height: 300px;    }    /*下划线*/    .l1{        text-decoration: underline;    }    /*中划线*/    .l2{        text-decoration: line-through;    }    /*上划线*/    .l3{        text-decoration: overline;    }    /*超链接去下划线*/    .a{        text-decoration: none;    }</style>
  1. 文本图片水平对齐 : vertical-align: middle
<!--水平对齐~参照物,a , b让图片和文字能够平行--><style>    img,span{        vertica1-align: middle;    }</style>

超链接伪类

<style>/*默认的状态*/    a{        text-decoration: none;        color: #000;    }    /*鼠标悬浮的状态(只需要记住:hover)*/    a : hover{        color : orange;        font-size: 50px;    }    /*鼠标按住未释放的状态*/    a : active{        color: green;    }    /*鼠标激活时的状态*/    a : visited{        color:#ff008a;    }    /*text-shadow:阴影颜色,水平偏移,垂直偏移,阴影半径*/    #price{        text-shadow : #3cc7f5 10px -10px 2px;    }</style>

列表

/*ul li*//*list-styLe:     none去掉原点     circle空心圆     decimal数字     square正方形*/ul{    background: #a0aeae;}ul li{    height: 30px;    list-style: none;    text-indent: 1em;}

背景

<style>    div{        width : 1000px;        height: 700px;        /*边框:边框粗细,样式,颜色*/        border: 1px solid red;        /*默认是全部平铺的 repeat*/        background-image: url("images/tx.jpg");        /*背景加url就可以放图片,并且设置图片的位置和样式*/        background: red ur1("../images/d.gif") 200px 10px no-repeat;        /*图片位置*/        background-position: 236px.2px;    }    .div1{        /*水平平铺*/        background-repeat: repeat-x;    }    .div2{        /*竖直平铺*/        background-repeat: repeat-y;    }    .div3{        /*不平铺,就是一张图片*/        background-repeat: no-repeat;    }</style>

渐变

<!--径向渐变,圆形渐变--><style>    body{        /*background-coLor: #21D4FD;*/        background-image: linear-gradient(19deg,#21D4FD 0%,#B721FF 100%);        }</style>

盒子模型

![image-20211022192316352](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211022192316352.png)

margin : 外边距
padding : 内边距
border : 边框

边框

<style>
    /*body总有一个默认的外边距margin: 0,常见操作*/
    h1,ul,li,a,body{
        margin: 0;
        padding: 0;
        text-decoration: none;
    }
    /*border:粗细,样式,颜色
    样式:solid 是实线
    dashed是虚线
    */
    #box{
        width: 300px;
        border: 1px solid red;
    }
    h2{
        font-size: 16px;
        background-color: #3cbda6;
        line-height: 30px;
    }
    
    form{
        background: #3cbda6;
    }
    div: nth-of-type(1) input{
        border: 3px solid black;
    }
    div:nth-of-type(2) input{
        border: 3px dashed #4dBb8c;
    }
    div:nth-of-type(2) input{
        border: 2px dashed #008c27;
    }
</style>

<body>
    <div id="box">
        <h2>会员登录</h2>
        <form action="#">
            <div>
                <span>用户名:</span>
                <input type="text">
            </div>
            <div>
                <span>密码:</span>
                <input type="text">
            </div>
            <div>
                <span>邮箱:</span>
                <input type="text">
            </div>
        </form>
    </div>
</body>

盒子模型的边框,内边距,外边距的顺序都是上右下左

例如:margin:当为一个值时,表示全部位置;当为两个值时,表示上下 和 左右;当为四个值时,就是上右下左

外边距的妙用:居中元素 margin: 0 auto;

盒子模型的计算方式:外边距+内边距+边框+实际内容 = 最终大小

圆角边框

<!DOCTYPE html><html lang="en">    <head>        <meta charset="UTF-8">        <title>Title</title>        <!--左上 右上 右下 左下,顺时针方向-->        <!-- 圆圈: 圆角 = 半径+边框! -->        <style>            div{                width: 100px;                height : 100px;                border: 10px solid red;                border-radius: 100px;            }        </style>    </head>    <body>        <div></div>    </body></html>

只需要更改border-radius中的值就可以得到某些图形,比如扇形圆形等。要与长度高度结合做更改。包括图片的边框

盒子阴影

<!DOCTYPE html><html lang="en">    <head>        <meta charset="UTF-8">        <title>Title</title>        <!-- margin: 0 auto;居中        要求:块元素,块元素有固定的宽度        -->        <style>            img{                border-radius: 5epx;                box-shadow: 10px 10px 100px yellow;        </style>    </head>    <body>        <div style="width: 50epx;display: block">            <div style="margin: e auto">                <img src="images/tx.jpg" alt="">            </div>        </div>    </body></html>

box-shadow改变某些值就可以让图片产生发亮的效果

浮动

标准文档流

![image-20211023142235533](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211023142235533.png)

display

<!--block  块元素    必须新开一行inline 行内元素  一行内可以占用inline-block   是块元素,但是可以内联,在一行! 既可以是块元素,也是行内元素none   没有--><style>    div{        width: 100px;        height: 100px;        border: 1px solid red;        display: none;    }    span{        width: 100px;        height: 100px;        border: 1px solid red;        display: inline-block;    }</style>

这个也是一种实现行内元素排列的方式,但是我们很多情况都是用float

float

div{    margin: 10px;    padding : 5px;}#father{    border : 1px #000 solid;}.layer01{    border: 1px #F00 dashed;    display: inline-block;    float: left;  /*元素向左浮动*/}.layer02{    border: 1px #06F dashed;    display: inline-block;    float: right;  /*元素向右浮动*/}.layere3{    border: 1px #060 dashed;    display: inline-block;    float: right;}.layer04{    border: 1px #666 dashed;    font-size : 12px;    line-height : 23px;    display: inline-block;    float: right;    claer: both; /*清除一行浮动的效果,使他独占一行并且不会改动*/}

对比folat和display

  • display

    方向不可以控制

  • float
    浮动起来的话会脱离标准文档流,所以要解决父级边框塌陷的问题

父级边框塌陷的问题

clear

/*clear: right; 右侧不允许有浮动元素clear: left;  左侧不允许有浮动元素clear: both;  两侧不允许有浮动元素c1ear: none;  可以浮动*/

解决方案

  1. 增加父级元素的高度

    #father {    border : 1px #000 solid;    height: 800px;}
    
  2. 增加一个空的div标签,清除浮动

    <div class="clear"></div>
    
    .clear{
        clear: both;
        margin : 0;
        padding: 0;
    }
    
  3. overflow

    在父级元素中增加一个
    overflow: hidden;  /*隐藏多余这个块级元素的部分*/
    overflow: scroll;  /*变成下拉框的形式*/
    
  4. 父类添加一个伪类:after

    #father:after{
        content: '';
        display : block;
        clear: both;
    }
    

小结:

  1. 浮动元素后面增加空div

    简单,代码中尽量避免空div

  2. 设置父元素的高度
    简单,元素假设有了固定的高度,就会被限制

  3. overflow
    简单,下拉的一些场景避免使用

  4. 父类添加一个伪类:after (推荐)
    写法稍微复杂一点,但是没有副作用,推荐使用!

定位

相对定位

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>相对定位</title>
    <!--相对定位
    相对于自己原来的位置进行偏移~
    -->
    <style>
        body {
            padding: 20px;
        }
        div {
            margin: 10px;
            padding: 5px;
            font-size: 12px;
            line-height: 25px;
        }
        #father {
            border: 1px solid #666;
            padding: 0;
        }
        #first {
            background-color: #a13d30;
            border: 1px dashed #b27530;
            position: relative; /*相对定位:上下左右*/
            top: -20px;
            left: 20px;
        }
        #second {
            background-color: #255099;
            border: 1px dashed #255066;
        }
        #third {
            background-color: #1c6699;
            border: 1px dashed #1c6615;
            position: relative;
            bottom: -10px;
            right: 20px;
        }
    </style>
</head>
<body>
<div id="father">
    <div id="first">第一个盒子</div>
    <div id="second">第二个盒子</div>
    <div id="third">第三个盒子</div>
</div>
</body>
</html>

相对定位: position: relative;
相对于原来的位置,进行指定的偏移,相对定位的话,它任然在标准文档流中!原来的位置会被保留

每个元素都要与之前的位置作比较,-20px指往上偏移,相对于原来的位置是要下去20px。以此类推其他的位置都是一样的

top : -20px;left: 20px;bottom : -10px;right: 20px;

绝对定位与固定定位

绝对定位:如果div没有设置定位元素,但div里的元素有绝对定位,那么就是相对于浏览器定位;div设置了定位元素,就相对于div定位

定位:基于xxx定位,上下左右
1、没有父级元素定位的前提下,相对于浏览器定位
2、假设父级元素存在定位,我们通常会相对于父级元素进行偏移
相对于父级或浏览器的位置,进行指定的偏移,绝对定位的话,它不在在标准文档流中,原来的位置不会被保留

固定定位:永远不会改变的定位

<style>    body{        height: 1000px;    }    div: nth-of-type(1){  /*绝对定位:相对于浏览器*/        width: 100px;        height: 100px;        background: red;        position:absolute;        right: 0;        bottom: 0;    }    div : nth-of-type(2){ /*fixed,固定定位*/        width: 50px;        height: 50px;        background: yellow;        position: fixed;        right: 0;        bottom: 0;    }</style><body>    <div>div1</div>    <div>div2</div></body>

z-index

类似于图层理解,默认是0,数值越大就是越往上

content{
    width: 380px;
    padding:2px;
    margin: 0px;
    overflow : hidden;
    font-size: 12px;
    line-height: 25px;
    border: 1px #000 solid;
}
ul,li{
    padding: 0px;
    margin: 0px;
    list-style: none;
}
/*父级元素相对定位*/
#content ul{
    position: relative;
}
.tipText,.tipBg{
    position: absolute;
    width: 380px;
    height: 25px;
    top: 216px;
}
.tipText{
    color: white;
    z-index: 0;
}
.tipBg{
    background: #000;
    opacity: 0.5;/*背景透明度*/
    filter: Alpha(opacity=50);
}

JavaScript

概述

JavaScript是一门世界上最流行的脚本语言
一个合格的后端人员,必须要精通JavaScript

历史

https://blog.csdn.net/kese7952/article/details/79357868ECMAScript

它可以理解为是JavaScript的一个标准
最新版本已经到ES6版本,但是大部分浏览器还只停留在支持ES5代码上!
开发环境---线上环境,版本不一致

写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript</title>

  <!--script标签内,写javascript代码-->
  <script>
    //alert 弹窗j
    alert('hello,world!');
  </script>

  <!--外部引入-->
  <!--注意: script标签必须成对出现-->
  <script src="js/js.js"></script>

  <!--不用显示定义type,也默认就是javascript-->
  <script type="text/javascript">

  </script>
</head>
<body>

<!--这里也可以放-->
<script>
  alert('hello,world!');
</script>
</body>
</html>
alert('hello,world!');

语法

<!--JavaScript严格区分大小写-->
<script>
    //1.定义变量 变量类型变量名=变量值;
    // 变量定义的类型都用var来定义,注意: 变量名不能为数字,其他都可以
    var num = 1;
    alert(num);
    //2.条件控制
    if(2>1){
        alert(num);
    }
    // console.log(变量)在浏览器的控制台打印变量!
    // 相当于System.out.println()
</script>

数据类型

number

js不区分小数和整数,Number

123  //整数123
123.1  //浮点数123.1
1.123e3 //科学计数法
-99  //负数
NaN   //not a number
Infinity //表示无限大

字符串

'avx' , "abc"

  1. 正常字符串我们使用单引号,或者双引号包裹

  2. **注意转义字符 **\

    \'    打印出点
    \n    换行
    \t    z
    \u4e2d    \u####      unicode字符
    \x41  Ascll字符
    
  3. 多行字符串编写

    //tab 上面 esc键下面
    var msg =
        `he11o
         world
         你好ya
         你好`
    
  4. 模板字符串

    //tab 上面esc键下面
    let name = "qinjiang";
    let age = 3;
    
    let msg =`你好呀,${name}``
    
  5. 字符串长度

    str.length

  6. 字符串的可读性,不可变性

    ![image-20211024220937336](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211024220937336.png)

  7. 大小写转换

    //注意,这里是方法,不是属性了
    student.toUppercase()  //转成大写
    student.toLowercase()  //转成小写
    
  8. indexof('t') 查看字符的位置

  9. substring

[)截断字符串
student.substring(1) //从第一个字符串截取到最后一个字符串
student.substring(1,3)  //[1,3) 从第一个截到第三个

布尔值

true false

逻辑运算

&&  两个都为真,结果为真

||  一个为真,结果为真
 
!   真即假,假即真

比较运算符

=    赋值
==   等于(类型不一样,值一样,也会判断为true)
===  绝对等于(类型一样,值一样,结果true)

这是一个JS的缺陷,坚持不要使用 == 比较

须知:

  • NaN===NaN,这个与所有的数值都不相等,包括自己
  • 只能通过 isNaN(NaN) 来判断这个数是否是 NaN

浮点数问题:

console.1og((1/3) === (1-2/3))   //返回false

尽量避免使用浮点数进行运算,存在精度问题!

Math.abs(1/3-(1-2/3))<0. 00000001  //返回true

null 和 undefined

  • null 空
  • undefined 未定义

数组

Java的数值必须是相同类型的对象,JS中不需要这样!

Array可以包含任意的数据类型

//保证代码的可读性,尽量使用[]
var arr = [1,2,3,4,5,'hello',null,true];
arr[0]  //通过下标取值
arr[0] = 1  ////通过下标赋值
new Array(1,12,3,4,4,5, 'hello');

取数组下标 : 如果越界了,就会

undefined

1、长度

arr.length

注意:假如给arr.length赋值,数组大小就会发生变化,如果同值过小,元索就会丢失

假设长度是5,给arr.length赋值10,那么长度为10,里面的内容大于5的都是为空,检索是undefined。给arr.length赋值2,那么长度为2,里面的内容大于2的都丢失。

2、indexOf,通过元素获得下标索引

var arr = [1,2,3,4,5];
arr.indexof(2) //查某一个值在哪
1

字符串的“1”和数字1是不同的

3、slice ()截取Array的一部分,返回一个新数组,类似于String中的substring

4、push(),pop()尾部压入值

arr.push("a","b")
push: 压入到尾部
arr.pop()
pop:  弹出尾部的一个元素

5、unshift(),shift()头部压入值

arr.unshift("a","b")
unshift:  压入到头部
arr.shift()
shift:    弹出头部的一个元素

6、排序sort()

arr = ["B","c","A"]
arr.sort()
["A","B","c"]

7、元素反转reverse()

arr = ["A","B","C"]
arr.reverse()
["C","B","A"]

8、concat()

arr = ["C","B","A"]
arr.concat([1,2,3])
["C","B","A",1,2,3]
arr
["C","B","A"]

注意: concat ()并没有修改数组,只是会返回一个新的数组

9、连接符 join

打印拼接数组,使用特定的字符串连接

arr = ["C","B","A"]
arr.join('-')
"C-B-A"

10、多维数组

arr = [[1,2],[3,4],["5","6"]];
arr[1][1]
4

对象

对象是大括号,数组是中括号

每个属性之间使用逗号隔开,最后一个不需要添加

var 对象名 = {
    属性名: 属性值,
    属性名: 属性值,
    属性名: 属性值
}

// Person person = new Person(1,2,3,4,5);
var person = {
    name: "qinjiang",
    age: 3,
    tags: ['js','java','web','...']
}

取对象的值

person.name
> "qinjiang"
person.age
> 3

1、对象赋值

person.name = "qinjiang"
"qinjiang"
person.name
"qiniiang"

2、使用一个不存在的对象属性,不会报错!undefined

person.haha
undefined

3、动态的删减属性,通过delete删除对象的属性

delete person.name
true
person //删除了name属性,其他的还在

4、动态的添加,直接给新的属性添加值即可

person.haha = "haha"
"haha"
person

5、判断属性值是否在这个对象中! xxx in xxx

'age' in person
true
//继承
'tostring' in person
true

6、判断一个属性是否是这个对象自身拥有的hasOwnProperty()

person.hasownProperty('tostring')
false
person.hasownProperty('age')
true

Map和Set

ES6的新特性

Map:

//ES6 Map
// 学生的成绩,学生的名字
// var names = ["tom","jack","haha"];
// var scores = [100,90,80];
var map = new Map([['tom',100],['jack',90],['haha',80]]);
var name = map.get('tom'); //通过key获得value
map.set('admin',123456);  //新增或修改
console.log(name);
map.delete("tom");   //删除

Set:无序不重复的集合

var set = new set([3,1,1,1,1]); //set可以去重
set.add(2);//添加
set.delete(l);//删除
console.log(set.has(3)); //是否包含某个元素!

iterator

ES6新特性

遍历数组

//通过for of 来遍历元素/ for in 遍历下标
var arr = [3,4,5]
// arr. name = "213"; 早期的漏洞
for (let x in arr){
    console.log(x)  //这样会把name给输出出来
}

for (var x of arr){
    console.log(x)
}

遍历map

var map = new Map([["tom" ,100],["jack",90],["haha",80]]);
for (let x of map){
    console.log(x)
}

遍历set

var set = new set([5.6,7]);
for (let x of set) {
    console.log(x)
}

严格检查模式

<!--
   前提:IEDA需要设置支持ES6语法
   'use strict';严格检查模式,预防JavaScript的随意性导致产生的一些问题      必须写在Javascript的第一行!
    局部变量建议都使用let去定义
-->
<script>
   'use strict';
   //全局变量
   let i = 1;
   //ES6用let定义变量,不用var
</script>

流程控制

if判断

var age = 3;
if (age>3){//第一个判断
    alert("haha");
}else if(age<5){//第二个判断
    alert("kuwa~");
}else { //否则..
    alert("kuwa~");
}

while循环,避免程序死循环

while(age<100){
    age = age + 1;
    console.log(age)
}

do{
    age = age + 1;
    console.log(age)
}while(age<100);

//死循环
while(ture){
    alert(123);
}

for循环

for (let i = 0; i < 100 ; i++) {
    console.log(i)
}

forEach循环

var age = [12,3,12,3,12,3,12,31,23,123];
//函数
age.forEach(function (value) {
    console.log(value)
})

for...in

//for(var index in object){}
for(var num in age){
    if (age.hasownProperty(num)){
        console.log("存在")
        console.log(age[num])
    }
}

函数及面向对象

函数定义

可以把函数理解成java中的方法

定义一个绝对值函数:

function abs(x){
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}

一旦执行到return代表函数结束,返回结果!

如果没有执行return ,函数执行完也会返回结果,结果就是NaN(undefined)

定义方式二:

var abs = function(x){
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}

function(x){....}这是一个匿名函数。但是可以把结果赋值给abs,通过abs 就可以调用函数!

方式一和方式二等价!

调用函数:

abs(10)   //10
abs(-10)  //10

参数问题: javaScript可以传任意个参数,也可以不传递参数

参数进来是否存在的问题? 参数存在

假设不存在参数,如何规避?

var abs = function(x){
    //手动抛出异常来判断
    if(typeof x!== "number") {
        throw "Not a Number";
    }
    if(x>=O){
        return x;
    }else{
        return -x;
    }
}

arguments:

arguments是一个JS免费赠送的关键字;

代表,传递进来的所有的参数,是一个数组!

var abs = function(x){
    console.log("x=>"+x);
    for (var i = 0; i<arguments.length ; i++){
        console.log(arguments[i]);
    }
}

问题: arguments包含所有的参数,我们有时候想使用多余的参数来进行附加操作。需要排除已有参数

rest:

以前:

if(arguments.length>2){
    for (var i = 2; i<arguments.length ; i++){
        //。。。。
    }
}

ES6引入的新特性,获取除了已经定义的参数之外的所有参数

function x(a,b,...rest){
    console.log("a=>"+a);
    console.log("b=>"+b);
    console.log(rest);
}

rest参数只能写在最后面,必须用...标识。

变量作用域

在javascript中, var定义变量实际是有作用域的。

假设在函数体中声明,则在函数体外不可以使用(非要想实现的话,后面可以研究一下闭包)

function x() {
    var x = 1;
    x = x + 1;
}
x = x + 2;  //Uncaught ReferenceError: x is not defined  在函数体外未定义x

如果两个函数使用了相同的变量名,只要在函数内部,就不冲突

function x() {
    var x = 1;
    x = x + 1;
}
function y() {
    var x = 'A';
    x = x + 1;
}

内部函数可以访问外部函数的成员,反之则不行

function ma() {
    var x = 1;
    
    //内部函数可以访问外部函数的成员,反之则不行
    function yun() {
        var y = x + 1;  //2
    }
    var z = y + 1; //Uncaught ReferenceError: y is not defined
}

假设,内部函数变量和外部函数的变量重名

function ma() {
    var x = 1;
    
    function yun() {
        var x = 'A';
        console.log('inner'+ x); //innerA
    }
    console.log ('outer'+ x); //outer1
    yun()
}
ma()

假设在JavaScript中函数查找变量从自身函数开始,由"内"向“外”查找。

假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量。

提升变量的作用域

function ma() {
    var = "x" + y;
    conso1e.log(x);
    var y = 'y';
}

结果: xundefined

说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值

function ma() {
    var y;
    var x= "x" + y;
    console.log(x);
    y = 'y';
}

这个是在JavaScript建立之初就存在的特性。

养成规范:所有的变量定义都放在函数的头部,不要乱放,便于代码维护。

function ma() {
    var x = 1,
        y = x + 1,
        z,i,a; //undefined
        
    //之后随意用
}

全局函数:

//全局变量
var x = 1;
function f() {
    console.log(x);
}
f();
console.log(x);

全局对象 window

var x = 'xxx';
alert(x);
alert(window.x); //默认所有的全局变量,都会自动绑定在window对象下;

alert()这个函数本身也是一个window变量

var x = 'xxx';

window.alert(x);

var old_alert = window.alert;

//o1d_alert(x);

window.alert = function() {
};

//发现alert()失效了
window. alert(123);

//恢复
window.alert = o1d_alert;
window.alert(456);

Javascript 实际上只有一个全局作用域,任何变量((函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错RefrenceError

规范:由于我们所有的全局变量都会绑定到我们的 window 上。如果不同的js文件,使用了相同的全局变量,就会冲突

如何能够减少冲突?

把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题。例如:jQuery

//唯一全局变量
var Mayun = {};

//定义全局变量
Mayun.name = 'kuangshen';
Mayun.add = function (a,b) {
    return a + b;
}

局部作用域 let

function x() {
    for (var i = 0; i < 100; i++) {
        console.log(i)
    }
    console.log(i+1); //问题?  i出了这个作用域还可以使用
}

ES6 let 关键字,解决局部作用域冲突问题!

建议使用let定义局部作用域的变量

function x() {
    for (let i = 0; i < 100; i++) {
        console.log(i)
    }
    console.log(i+1); //uncaught ReferenceError: i is not defined
}

常量 const

在ES6之前,怎么定义常量:只有用全部大写字母命名的变量就是常量;建议不要修改这样的值

var PI = '3.14';
console.log(PI);
PI = '213'; //可以改变这个值
console.log(PI)

在ES6引入了常量关键字 const

const PI = '3.14'; //只读变量
console.log(PI);
PI = '123'; //TypeError: Assignment to constant variab1e.
console.log(PI);

方法

定义方法

方法就是把函数放在对象的里面,对象只有两个东西:属性和方法

var mayunlong = {
    name: '马云龙',
    birth: 1999,
    // 方法
    age: function (){
        // 今年 - 出生的年
        var now = new Date().getFullYear();
        return now-this.birth;
    }
}
//属性
mayunlong.name
//方法,一定要带()
mayunlong.age()

this.代表什么? this是无法指向的,是默认指向调用它的那个对象

用apply可以控制this指向

function getAge() {
        // 今年 - 出生的年
        var now = new Date().getFullYear();
        return now - this.birth;
    }

    var mayunlong = {
        name: '马云龙',
        birth: 1999,
        // 方法
        age:getAge
    }

    getAge.apply(mayunlong,[]); //this,指向了mayunlong,参数为空

原型继承

定义的对象名._proto_ = 对象名

表示该对象的原型是另一个对象,具有另一个对象的方法和属性

var student = {
    name: "qinjiang",
    age: 3,
    run : function () {
        console.log(this.name + " run. . .. ");
    }
};
var xiaoming = {
    name : "xiaoming"
};
//原型对象,小明的原型是student
xiaoming._proto_ = student;
var Bird = {
    fly : function () {
        console.log(this.name + " f1y.. .. ");
    }
};
//小明的原型是Bird
xiaoming.__proto__ = Bird;

原型链:百度搜一下

class继承

class关键字,是在ES6引入的

本质还是原型对象

function Student(name){
    this.name = name;
}
// ES6之前给Student新增一个方法
Student.prototype.hello = function (){
    alert('Hello')
}

//ES6之后=============
// 定义一个学生的类
class Student{

    constructor(name){
        this.name =name;
    }
    hello(){
        alert('he11o')
    }
}

//创建Student的类的对象
var xiaoming = new Student("xiaoming");
var xiaohong = new Student("xiaohong");
xiaoming.hello()//可以调用Student类的方法

//class继承的方法
class XiaoStudent extends Student{
    constructor(name,grade) {
        super(name);
        this.grade = grade;
    }
    myGrade(){
        alert('我是一名小学生')
    }
}
var xiaohong = new XiaoStudent("xiaohong",1);
xiaohong.myGrade() //调用XiaoStudent类的方法

常用对象

标准对象

typeof 123
"number"
typeof '123'
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof {}
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"

Date

基本使用

var now = new Date(); //(中国标准时间)
now.getFullYear();  //年
now.getMonth();     //月  0~11代表月
now.getDate();      //日
now.getDay();       //星期几
now.getHours();     //时
now.getMinutes();   //分
now.getseconds();   //秒
now.getTime();      //时间戳 全世界统一 1970 1.1 0:00:00~至今 毫秒数
console.log(new Date(1578106175991))//时间戳转为时间

转换

now = new Date(1578106175991)
Sat Jan 04 2020 10:49:35 GMT+0800(中国标准时间)
now.toLocalestring() //注意,调用一个方法,不是一个属性!
"2020/1/4上午10:49: 35"
now.toGMTstring
"sat,04 Jan 2020 02:49:35 GMT"

JSON

早期,所有数据传输习惯使用 XML 文件!

  • JSON(JavaScript Object Notation,JS对象简谱)是一种轻量级的数据交换格式
  • 简洁和清晰的层次结构使得JSON成为理想的数据交换语言。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

在JavaScript一切皆为对象、任何js支持的类型都可以用JSON来表示; number,string...格式:

  • 对象都用{}
  • 数组都用[]
  • 所有的键值对都是用key:value

JSON字符串和JS对象的转化

var user = {
    name : "qinjiang",
    age: 3,
    sex: '男'
}
//对象转化为json字符串 {"name":"qinjiang","age": 3,"sex":"男"}
var jsonuser = JSON.stringify(user);

//json字符串转化为对象参数为json字符串
var obj =JSON.parse('{"name":"qinjiang","age":3,"sex":"男"}');

JSON和JS对象的区别

var obj = { a:'hello', b:'world'};
var json ='{"a":"hello","b":"world"}'

Ajax

  • 原生的js写法 xhr等 异步请求
  • jQuey封装好的方法 $(""#name").ajax("")
  • axios请求

操作Dom元素

DOM:文档对象模型

核心:浏览器网页就是一个Dom树形结构!

要操作一个Dom节点,就必须要先获得这个Dom节点

获得Dom节点,这是原生代码,之后我们尽示都是用jQuery() ;

对应CSS选择器
var h1 = document.getElementsByTagName("h1");  //获取标签
var p1 = document.getElementById("p1");       //获取Id节点
var p2 = document.getElementsByclassName('p2');  //获取class节点
var father = document.getElementById('father');  
var childrens = father.children; //获取父节点下的所有子节点
//father.firstchi1d    //第一个子节点
//father.lastchild     //最后一个子节点

插入Dom

我们获得了某个Dom节点,假设这个dom节点是空的,我们通过innerHTML就可以增加一个元素了,但是这个DOM节点已经存在元素了,我们就不能这么干了!会产生覆盖

追加

<p id="js ">Javascript</p>
<div id="list">
    <p id="se ">JavaSE</p>
    <p id="ee ">JavaEE</p>
    <p id="me">JavaME</p>
</div>
<script>
    var js = document.getElementById('js');  //已存在的节点
    var list = document.getE1ementById('list');
    list.appendchild(js); //追加到后面
</script>

创建一个新的标签,实现插入

<script>
    var js = document.getElementById('js'); //己经存在的节点
    var list = document.getElementById('list');
    
    //通过JS 创建一个新的节点
    var newP = document.createElement('p'); //创建一个p标签
    newP.id ='newP';
    newP.innerText = "He11o,Kuangshen";
    //创建一个标签节点〔通过这个属性,可以设置任意的值)
    var myscript = document.createElement('script');
    myscript.setAttribute('type','text/javascript')
    
    //可以创建一个style标签
    var mystyle= document.createElement('style');//创建了一个空style标签
    mystyle.setAttribute('type','text/css');
    mystyle.innerHTML = 'body{background-color: chartreuse;} ';//设置标签内容
    document.getElementsByTagName('head')[0].appendchild(mystyle)
</script>

insertBefore

var ee = document.getE1ementById('ee');
var js = document.getElementeyId('js');
var list = document.getElementById('list'); 
//要包含的节点.insertBefore(newNode,targetNode)
list.insertBefore(js,ee);

更新Dom

<div id="id1">
</div>
<script>
var id1 = document.getElementById('id1');
</script>

<!--操作文本-->
id1.innerText = '456'  //修改文本的值
id1.innerHTML = '<strong>123</strong>'
"<strong>123</strong>"  //可以解析HTML文本标签

<!--操作CSS-->
id1.style.color = 'yellow'; //属性使用字符串包裹
id1.style.fontSize='20px';//下划线转驼峰命名
id1.style.padding = '2em'

删除Dom

删除节点的步骤:先获取父节点,在通过父节点删除自己

注意:删除多个节点的时候,children是在时刻变化的,删除节点的时候一定要注意!

<div id="father">
    <h1>标题一</h1>
    <p id="p1">p1</p>
    <p class="p2">p2</p>
</div>
<script>
    var self = document.getElementById('p1');
    var father = p1.parentElement;
    father.removechild(self)
    
    // 删除是一个动态的过程;当你把0位置的删除时,1位置的就变成了0位置
    father.removechild(father.chi1dren[0])
    father.removechild(father.children[1])
    father.removechild(father.chi1dren[2])
</script>

操作表单(验证)

表单是什么form DOM树

  • 文本框 text
  • 下拉框 < select >
  • 单选框 radio
  • 多选框 checkbox
  • 隐藏域 hidden
  • 密码框 password

表单的目的:提交信息

获得要提交的信息

<form action="post">
    <p>
        <span>用户名:</span><input type="text" id="username">
    </p>
    <!--多选框的值,就是定义好的value-->
    <p>
        <span>性别:</span>
        <input type="radio" name="sex" value="man" id="boy">
        <input type="radio" name="sex" value="women" id="girl">女
    </p>
</form>
<script>
    var input_text = document.getElementById('username');
    var boy_radio = document.getElementById('boy');
    var girl_radio = document.getElementById('girl');
    
    //得到输入框的值
    input_text.value
    //修改输入框的值
    input_text.value = '123'
    //对于单选框,多选框等等固定的值,boy_radio.value只能取到当前的值
    boy_radio.checked;
    //查看返回的结果,是否为true,如果为true,则被选中
    girL_radio.checked = true;  //赋值就可以选中了
</script>

提交表单 md5加密密码,表单优似

<!--
表单绑定提交事件
onsubmit = 绑定一个提交检测的函数,true.false
将这个结果返回给表单,使用onsubmit接收!
onsubmit = "return aaa( )"
-->
<form action="https://www.baidu.com/" method="post" onsubmit="return aaa()">
    <p>
        <span>用户名:</span><input type="text" id="username" name="username">
    </p>
    <p>
        <button type="submit">提交</button>
        <span>密码: </span>
        <input type="password" id="input-password">
    </p>
    <input type="hidden" id="md5-password" name="password" >
    <!--绑定事件onclick被点击-->
</form>
<script>
    function aaa(){
        alert(1);
        var uname = document.getElementById('username');
        var pwd = document.getElementById('input-password');
        var md5pwd = document.getElementById('md5-password');
        //pwd.value = md5(pwd.value);
        md5pwd.value = md5(pwd.value) ;
        //可以校验判断表单内容,true就是通过提交,false,阻止提交
        return true;
}

操作Bom元素

BOM:浏览器对象模型

浏览器内核

  • IE
  • Chrome
  • FireFox

三方浏览器

  • QQ浏览器
  • 360浏览器

window 代表浏览器窗口

window.alert(1)
undefined
window.innerHeight  //内部高度
258
window.innerwidth
919
window.outerHeight  //外部高度
994
window.outerwidth
919

Navigator,封装了浏览器的信息

大多数时候,我们不会使用navigator对象,因为会被人为修改

不建议使用这些属性来判断和编写代码

navigator.appName
"Netscape"
navigator.appversion
"5.0 (windows NT 10.0;wOw64) App1ewebKit/537.36 (KHTML,like Gecko)chrome/63.0.3239.132 safari/537.36"
navigator.userAgent
"Mozi11a/5.0 (windows NT 10.0; wOW64) ApplewebKit/537.36 (KHTML,7ikeGecko) chrome/63.0.3239.132 safari/537.36"
navigator.platform
"win32"

screen 代表屏幕尺寸

screen.width
1920px
screen.height
1080px

location 代表当前页面的URL信息

host:"www.baidu.com"   //主机
href:"https://www.baidu.com/"  //地址
protocol:"https:"  //协议
reload:f reload() //刷新网页
//设置新的地址
location.assign ('https://b1og.kuangstudy.com/')

document 代表当前页面信息

document.title
"百度一下,你就知道"
document.title='狂神说"
"狂神说"

获取具体的文档树节点(选择器)

<dl id="app">
    <dt>Java</dt>
    <dd>JavaSE</dd>
    <dd>JavaEE</dd>
</d1>
<script>
var dl = document.getElementById('app');
</script>=

获取cookie

document.cookie
'_guid=111872281.88375976493059340.578110638877.133;monitor_count=1"

劫持cookie原理

例如www.taobao.com

<script src="aa.js">
<!--恶意人员写一些代码;获取你的cookie上传到他的服务器-->
</script>

服务器端可以设置cookie: httponly 防止劫持

history 代表浏览器的历史记录

history.back()  //网页后退
history.forward //网页前进

jQuery

jQuery库,里面存在大量的Javascript函数

获取jQuery

可以去官网下载或者CSDN吧查看

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset= "UTF-8">
        <title>Title</title>
        <!--cdn引入-->
        <script src="https://cdn.bootcss.com/jquery/3.4.1/core.js">
        </script>
    </head>
<body>
$(selector).action()
$(选择器的标签).事件
    <a href="" id="test-jquery">点我</a>
<script>
    //选择器就是css的选择器
    $('#test-jquery').click(function () {
        alert('hello,jQuery');
    })
</script>
</body>
</htm1>

选择器的文档工具站: http://jquery.cuishifeng.cn/

事件

鼠标事件

网页加载完毕后,触发的事件
$(document).ready(function(){
  // 在这里写你的代码...
});

操作Dom

节点文本操作

$('#test-ul li[name=python]').text();   //获得值
$('#test-ul li[name=python]').text('设置值');  //设置值
$('#test-ul').html();         //获得值
$('#test-u7').html('<strong>123</strong>');   //设置值

CSS的操作

$('#test-ul li[name=python]').css({"color","red"})

元素的显示和隐藏:本质 display : none

$('#test-ul li[name=python]').show()
$('#test-ul li[name=python]').hide()

Layer 弹窗组件
Element-ui

JavaWeb

基本概念

web开发:

  • web,网页的意思,www.baidu.com

  • 静态web

    • html ,css
    • 提供给所有人看的数据始终不会发生变化!
  • 动态web

    • 提供给所有人看的数据会发生变化!每个人看到的信息各不相同
    • 技术栈:Servlet/JSP,ASP,PHP

在java中,动态web资源开发的技术统称为JavaWeb

web应用程序

可以提供浏览器访问的程序;

  • index.html...多个web资源,这些web资源可以被外界访问,对外界提供服务
  • 能访问的资源都存在于一台计算机上,通过URL访问
  • web资源放在同一个文件夹下,web应用程序-->Tomcat:服务器
  • 一个web应用由多部分组成(静态web,动态web)
    • html,css,js
    • jsp,servlet
    • java程序
    • jar包
    • 配置文件(Properties)

web应用程序编写完毕后,若想提供给外界访问:需要一个服务器来统一管理

静态web

  • .html等都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取。通络;

![image-20211221192521204](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211221192521204.png)

  • 静态web存在的缺点
    • Web页面无法动态更新,所有用户看到的都是同一个页面
      • 轮播图,点击特效都是伪动态。
      • JS[实际开发中,用的最多]
      • VBScript
    • 无法和数据库交互(数据无法持久化,用户无法交互)

动态web

页面会动态展示:"Web的页面展示的效果因人而异"

![image-20211221193335603](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211221193335603.png)

缺点

  • 假如服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布。
    • 停机维护

优点:

  • 可以动态更新,页面可以不同
  • 可以与数据库交互(数据持久化:注册,商品信息,用户信息)

web服务器

ASP:

  • 微软:国内最早流行的就是ASP;
  • 在HTML中嵌入了VB的脚本,ASP + COM;
  • 在ASP开发中,基本一个页面都有几千行的业务代码,页面极其混乱
  • 维护成本高!
  • C# IIS服务器

PHP

  • PHP开发速度很快,功能强大,跨平台,代码简单
  • 无法承载大量访问(局限性)

JSP/Servlet

  • sun公司主推的B/S架构
  • 基于java语言
  • 可以承载三高问题带来的影响。三高:高并发,高可用,高性能

服务器

是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息

IIS:微软的;ASP...Windows中自带的

Tomacat

访问测试:http://localhost:8080/

遇到的问题:

  1. java环境变量没有配置,闪退
  2. 闪退:需要配置兼容性
  3. 乱码:配置文件中设置

![image-20211222125556584](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211222125556584.png)

更改域名配置:

![image-20211222130741813](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211222130741813.png)

![image-20211222130348933](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211222130348933.png)

![image-20211222130508086](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20211222130508086.png)

可以配置启动的端口号:

  • tomcat的默认端口号:8080

  • mysql:3306

  • http:80

  • https:443

200代表成功访问,307代表重定向

配置主机的名称

  • 默认的主机名为:localhost-->127.0.0.1
  • 默认网站应用存放的位置为:webapps

面试题:

请你谈谈网站是如何进行访问的

  1. 输入一个域名:回车

  2. 检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射

    1. 有:就返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问

      127.0.0.1   www.mayunlong.com
      
    2. 没有:去DNS服务器找,找到就返回,找不到就报错

      ![image-20220103180753491](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103180753491.png)

配置一下环境变量(可选)

发布一个web应用

  • 将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了

网站应该有的结构

--webapps : Tomcat服务器的web目录
   -ROOT
   -MaYun : 网站的目录名
        -WEB-INF
           -classes : java程序
           -lib : web应用所依赖的jar包
           -web.xml  : 网站的配置文件
         -index.jsp : 默认的首页
         - static
             -css
                  -style.css
             -js
             -img
         - ......

HTTP

HTTP(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上

  • 文本:html,字符串
  • 超文本:图片,音乐,视频
  • 80

Https:安全的

  • 443

Http请求

  • 客户端 --> 发请求(request)--> 服务器
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET     请求方法:get/post
Status Code: 200 OK     状态码:200
Remote Address: 61.179.104.42:443  远程地址

请求行

get方式提交 : 我们可以在url中看到我们提交的信息,不安全,高效.
post : 比较安全 , 传输大文件.

消息头

Accept:支持的数据类型

Accept-Encoding:支持哪种编码格式:GBK UTF-8 GB2312 ISO8859-1

Cache-Control:缓存控制

Connection:告诉浏览器,请求完成还是断开还是保持连接

Host:主机...

Http响应

  • 服务器 --> 响应 --> 客户端
access-control: private   缓存控制
Connection:Keep-Alive    连接:保持连接
Content-Encoding
Set-Cookie
Content-Type:text/html

响应体

Refresh:告诉客户端,多久刷新一次

Location:让网页重新定位

响应状态码

200 :请求响应成功

3xx : 请求重定向

  • 重定向:你重新到我给你的新位置去

404 : 找不到资源

  • 资源不存在

5xx:服务器代码错误 500 502(网关错误)

  • 网站崩了

常见面试题:

当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?

Maven

Maven能够自动导入和配置jar包

Maven项目架构管理工具

Maven的核心思想:约定大于配置

  • 有约束,不要违反

配置Maven:

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录
  • 在path中配置 %MAVEN_HOME%\bin
  • cmd : mvn -version 测试Maven是否安装成功。

阿里云镜像

镜像:mirrors

  • 作用:加速下载
    <mirror>
          <id>aliyunmaven</id>
          <mirrorOf>*</mirrorOf>
          <name>阿里云公共仓库</name>
          <url>https://maven.aliyun.com/repository/public</url>
    </mirror>

本地仓库

本地和远程仓库,建立一个本地仓库

![image-20220104224301821](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220104224301821.png)

![image-20220104224427418](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220104224427418.png)

在IDEA中使用Maven

![image-20220103203005440](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103203005440.png)

![image-20220103203253456](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103203253456.png)

![image-20220103203430777](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103203430777.png)

创建一个普通的Maven项目:不用勾选create。。。

![image-20220103205009858](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103205009858.png)

web目录下创建java普通项目

![image-20220103205328352](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103205328352.png)

![image-20220103205752572](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103205752572.png)

配置Tomcat

![image-20220103211020576](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103211020576.png)

解决警告问题

![image-20220103211208719](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103211208719.png)

![image-20220103211527741](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103211527741.png)

maven的一些配置介绍

![image-20220103212327364](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220103212327364.png)

pom文件

pom.xml是maven的核心配置文件

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

<!-- Maven版本和头文件 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- 配置的GAV -->
  <groupId>com.ma</groupId>
  <artifactId>javaweb-01-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!-- package : 项目的打包方式
  jar : java应用
  war : java web应用
  -->
  <packaging>war</packaging>

  <!-- 配置 -->
  <properties>
    <!-- 项目的默认构建编码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 编码版本 可修改 -->
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!-- 项目依赖 -->
  <dependencies>
    <!-- 具体依赖的jar包配置 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!-- 项目构建的东西 -->
  <build>
    <finalName>javaweb-01-maven</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

![image-20220104223507459](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220104223507459.png)

pom.xml中一些配置问题

<dependencies>
    <!--具体依赖的jar包配置文件-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
    <!-- Maven的高级之处在于,他会帮你导入这个JAR包所依赖的其他jar -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
</dependencies>

<!-- 在build中配置resources,来防止我们资源导出失败的问题 -->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <!-- 不去过滤这个问题 -->
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

Servlet

  • Servlet是sun公司开发的动态web
  • Servlet接口Sun公司默认提供两个实现类 HttpServlet GenericServlet

![image-20220105201646864](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105201646864.png)

  • sun在api中提供一个接口叫:Servlet。
    • 编写一个类,实现Servlet接口。
    • 开发好的java类部署到web服务器中。

把实现Servlet接口的Java程序叫Servlet。

maven写servlet时pom.xml的依赖

![image-20220104232117035](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220104232117035.png)

web.xml版本更改方法

![image-20220104234423307](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220104234423307.png)

更改成tomcat服务器的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" version="4.0"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
</web-app>

编写一个Servlet程序在浏览器上显示

  • 创建maven项目中的webapp时自带的jsp程序

![image-20220105002925259](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105002925259.png)

  • 给pom.xml中引jar包(跟创建web程序时直接导jar包一样)

![image-20220105003259149](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105003259149.png)

  • servlet.java

![image-20220105003511570](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105003511570.png)

![image-20220105003710667](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105003710667.png)

再做maven项目时,只需要创建一个项目就行,之后其他的用module。

因为父类的maven项目是普通的,创建module时可以勾选webapp来创建web项目。

  • 父项目中

        <groupId>com.mayunlong.javaweb</groupId>
        <artifactId>mavenweb</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>servlet-01</module>
        </modules>
    
  • 子项目中

    <parent>
        <artifactId>mavenweb</artifactId>
        <groupId>com.mayunlong.javaweb</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>servlet-01</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    

将web.xml改为最新的

<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" version="4.0"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
    
</web-app>

编写Servlet程序

  1. 编写一个普通类

  2. 重写doGET和doPOST

    //由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        System.out.println("进入doGet方法");
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();  //响应流
        writer.println("Hello Servlet!");
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
    
  3. 编写Servlet映射

    为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要再web服务中注册我们写的Servlet,还需要给它一个浏览器能够访问的路径

    <!-- 注册Servlet -->
    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>com.ma.servlet.MyServlet</servlet-class>
    </servlet>
    <!-- servlet映射的请求路径 -->
    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/index</url-pattern>
    </servlet-mapping>
    
  4. 配置tomcat

    ![image-20220105221903406](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105221903406.png)

  5. 启动测试

原理

![image-20220105223115681](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105223115681.png)

![image-20220105223542137](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220105223542137.png)

mapping

  1. 一个Servlet可以指定一个映射路径

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/index</url-pattern>
    </servlet-mapping>
    
  2. 一个Servlet可以指定多个映射路径

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/index</url-pattern>
        <url-pattern>/shop</url-pattern>
        <url-pattern>/buy</url-pattern>
        <url-pattern>/green</url-pattern>
        <url-pattern>/server</url-pattern>
    </servlet-mapping>
    
  3. 一个Servlet可以指定通用映射路径

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/index/*</url-pattern>
    </servlet-mapping>
    
  4. 默认请求路径

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
  5. 指定一些后缀或者前缀

    <!-- 可以自定义后缀实现请求映射
         注意点:*前面不能加项目映射的路径
         index/xxx.ma可以访问-->
    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>*.ma</url-pattern>
    </servlet-mapping>
    
  6. 优先级:指定了固有的映射路径优先级最高,如果找不到就走默认请求路径

    <!-- 注册Servlet -->
    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>com.ma.servlet.MyServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>error</servlet-name>
        <servlet-class>com.ma.servlet.ErrorServlet</servlet-class>
    </servlet>
    <!-- servlet映射的请求路径 -->
    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/index</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>error</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

ServletContext

![image-20220112230006148](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220112230006148.png)

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。

共享数据

在一个Servlet程序中在ServletContext池中保存数据,在另一个Servlet程序可以拿到保存的数据。

![image-20220106224513066](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220106224513066.png)

  • setAttribute
package com.ma.servletcontext;

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.PrintWriter;

/**
 * @author MaYunLong
 * @date 2022/1/6 - 22:16
 */
public class MyServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this.getInitParameter()   初始化参数
        //this.getServletConfig()   servlet配置
        //this.getServletContext()  servlet上下文
        ServletContext context = this.getServletContext();
        String username = "马云龙";
        context.setAttribute("username",username);   //将一个数据保存在了ServletContext中,名字为: username 值: username

        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.println("set从ServletContext池中获取" + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
  • getAttribute
package com.ma.servletcontext;

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.PrintWriter;

/**
 * @author MaYunLong
 * @date 2022/1/6 - 22:21
 */
public class GetServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.println("从ServletContext池中找到了" + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" version="4.0"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
    <servlet>
        <servlet-name>set</servlet-name>
        <servlet-class>com.ma.servletcontext.MyServletContext</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>set</servlet-name>
        <url-pattern>/setA</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>get</servlet-name>
        <servlet-class>com.ma.servletcontext.GetServletContext</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>get</servlet-name>
        <url-pattern>/getA</url-pattern>
    </servlet-mapping>
</web-app>

获取初始化参数

public class MyServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().println(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
<!-- 配置一些web应用初始化参数 -->
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>

请求转发

![image-20220106230711016](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220106230711016.png)

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    RequestDispatcher requestDispatcher = context.getRequestDispatcher("/getp"); //转发的请求路径
    requestDispatcher.forward(req,resp);   //调用forward实现请求转发
}
<!-- 配置一些web应用初始化参数 -->
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
<servlet>
    <servlet-name>getp</servlet-name>
    <servlet-class>com.ma.servletcontext.MyServletContext</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>getp</servlet-name>
    <url-pattern>/getp</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>getF</servlet-name>
    <servlet-class>com.ma.servletcontext.ForwardServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>getF</servlet-name>
    <url-pattern>/getF</url-pattern>
</servlet-mapping>

读取资源文件

Porperties

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath

public class PropertiesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/ma/servlet/aa.properties");
        Properties properties = new Properties();
        properties.load(stream);
        String user = properties.getProperty("username");
        String pwd = properties.getProperty("password");

        resp.getWriter().println(user+pwd);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
<servlet>
    <servlet-name>pro</servlet-name>
    <servlet-class>com.ma.servlet.PropertiesServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>pro</servlet-name>
    <url-pattern>/pro</url-pattern>
</servlet-mapping>
<resources>
  <resource>
    <directory>src/main/resources</directory>
    <includes>
      <include>**/*.properties</include>
      <include>**/*.xml</include>
    </includes>
  </resource>
  <resource>
    <directory>src/main/java</directory>
    <includes>
      <include>**/*.properties</include>
      <include>**/*.xml</include>
    </includes>
  </resource>
</resources>

HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

简单分类

负责向浏览器发送数据的方法

ServletOutPutStream getOutPutStream() throws IOException;
PrintWriter getWriter() throws IOException;

负责向浏览器发送响应头的方法

void setCharacterEncoding(String var1);

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);

响应状态码常量

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

常见应用

  1. 向浏览器输出消息(getWriter)
  2. 下载文件
    1. 要获取下载文件的路径
    2. 下载的文件名是啥?
    3. 设置想办法让浏览器能够支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutputStream对象
    7. 将FileOutputStream流写入到buffer缓冲区
    8. 使用OutputStream将缓冲区中的数据输出到客户端!
public class MyHttpServletResponse extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1. 要获取下载文件的路径
        String realPath = "C:\\Users\\Marcus YL\\Desktop\\java\\mavenweb\\servlet-02\\target\\classes\\马云龙.jpg";
        System.out.println("要获取下载文件的路径" + realPath);
//        2. 下载的文件名是啥?
        String substring = realPath.substring(realPath.lastIndexOf("\\") + 1);
//        3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,让中文文件名URLEncoder.encode编码
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(substring,"UTF-8"));
//        4. 获取下载文件的输入流
        FileInputStream fileInputStream = new FileInputStream(realPath);
//        5. 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
//        6. 获取OutputStream对象
        ServletOutputStream outputStream = resp.getOutputStream();
//        7. 将FileOutputStream流写入到buffer缓冲区
        while (( len=fileInputStream.read(buffer))>0){
            outputStream.write(buffer,0,len);
        }
//        8. 使用OutputStream将缓冲区中的数据输出到客户端!
        fileInputStream.close();
        outputStream.close();
    }
  1. 验证码
  • 前端实现
  • 后端实现,需要用java的图片类,生成一个图片
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //如何让浏览器5秒自动刷新一次
    resp.setHeader("refresh","3");
    //在内存中创建一个图片
    BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_3BYTE_BGR);
    //得到图片
    Graphics graphics = (Graphics2D) image.getGraphics();  //笔
    //设置图片的背景颜色
    graphics.setColor(Color.white);
    graphics.fillRect(0,0,80,20);
    //给图片写数据
    graphics.setColor(Color.blue);
    graphics.setFont(new Font(null,Font.BOLD,20));
    graphics.drawString(makeNum(),0,20);

    //告诉浏览器,这个请求用图片的方式打开
    resp.setContentType("image/png");
    //网站存在缓存,不让浏览器缓存
    resp.setDateHeader("expires",-1);
    resp.setHeader("Cache-Control","no-cache");
    resp.setHeader("Pragma","no-cache");

    //把图片写给浏览器
    ImageIO.write(image,"png",resp.getOutputStream());
}

//生成随机数
private String makeNum(){
    Random random = new Random();
    String num = random.nextInt(99999999) + "";
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < 7-num.length(); i++) {
        buffer.append("0");
    }
    num = buffer.toString() + num;
    return num;
}

重定向

一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向

常见场景

  • 用户登录
void sendRedirect(String var1) throws IOException;
/*
resp.setHeader("Location","/r/img");
resp.setStatus(302);
*/
resp.sendRedirect("/s2/img"); //重定向

面试题:重定向和转发的区别

相同点:

  • 页面都会实现跳转

不同点:

  • 请求转发的时候,url地址栏不会变化 307
  • 重定向时候,url地址栏会发生变化 302

HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息

获取参数,请求转发

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobbies");

        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        //通过请求转发
        //因为请求转发还是会保留项目地址,所以请求转发还有个/s3,如果用重定向的话就没有/s3了
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }
}

![image-20220112225522471](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220112225522471.png)

会话:用户打开了一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程称之为会话

有状态会话:

一个网站,怎么证明你来过?

客户端 服务端 服务端证明客户端来过

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
  2. 服务器登记你来过了,下次你来的时候匹配你;

Cookie和Session的区别

  1. 存储位置不同: cookie是保存在客户端, session是保存服务器端
  2. 存储数据量大小不同: cookie存储是有限的, 不超过4KB, seesion是无限制的;
  3. 存储的数据类型不同:cookie只能存储键值对的字符串类型,而session可以存储任意类型
  4. 默认有效期不同:cookie默认是会话级别的cookie,而session默认有效期是30分钟

用法

  1. 从请求中拿到cookie信息

  2. 服务器响应给客户端cookie

cookie[] cookies = req.getcookies(); //获得cookie
cookie.getName();  //获得cookie中的key
cookie.getValue();  //获得cookie中的value
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务器,告诉你,你来的时间,把这个时间封装成为一个 信件,你下次带来,我就知道你来了

        //解决中文乱码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("UTF-16");

        PrintWriter out = resp.getWriter();

        //Cookie,服务器端从客户端获取;
        Cookie[] cookies = req.getCookies();  //这里返回数组,说明Cookie可能存在多个

        //判断Cookie是否存在
        if (cookies!=null){
            //如果存在怎么办
            out.write("你上一次访问的时间是:");

            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取Cookie的名字
                if (cookie.getName().equals("lastLoginTime")){
                    //获取Cookie中的值
                    long l = Long.parseLong(cookie.getValue());
                    Date date = new Date(l);
                    out.write(date.toLocaleString());
                }
            }
        }else {
            out.write("这是第一次访问本站");
        }

        //服务给客户端响应一个cookie;
        Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
        //cookie有效期为一天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

cookie:一般会保存在本地的用户目录下appdate;

一个网站cookie是否存在上限!聊聊细节问题

  • 一个Cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie,每个站点最多存放20个
  • Cookie大小有限制4kb
  • 300个cookie浏览器上限

删除Cookie:

  • 不设置有效期,关闭浏览器,自动失效
  • 设置有效期时间为0C

Session

![image-20220112225802260](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220112225802260.png)

常见常见:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!

  • 服务器会给每一个用户(浏览器)创建一个Session对象
  • 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登录之后,整个网站它都可以访问!-->保存用户的信息;保存购物车的信息。

Session和Cookie的区别

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存
  • Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的东西,减少服务器资源的浪费)
  • Session对象由服务创建

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 在整个网站中经常会使用的数据,我们将它保存在Session中;

使用Session

//解决乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");

//得到Session
HttpSession session = req.getSession();

//给Session中存东西
session.setAttribute("name","马云龙");

//获取Session的ID
String id = session.getId();

//判断Session是不是新创建的
if (session.isNew()) {
    resp.getWriter().write("session创建成功,ID:"+id);
}else {
    resp.getWriter().write("session已经在服务器中存在了,ID:"+id);
}

//Session创建的时候做了什么事情;
Cookie cookie = new Cookie("JSESSIONID",id);
resp.addCookie(cookie);
//解决乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");

//得到Session
HttpSession session = req.getSession();

Object name = session.getAttribute("name");
String name1 = (String)name;
System.out.println(name1);
//手动注销Session
session.invalidate();

会话自动过期:web.xml配置

<!--设置session默认的失效时间-->
<session-config>
<!--15分钟后session自动失效,以分钟为单位-->
    <session-timeout>1</session-timeout>
</session-config>

JSP

JavaServer pages:java服务器端页面,也和servlet一样,用于动态Web技术

最大特点:

  • 写JSP就像在写HTML
  • 区别
    • HTML只给用户提供静态数据
    • JSP页面中可以嵌入JAVA代码,为用户提供动态数据;

JSP原理

Jsp是怎么执行的

  • 代码层面,没有任何问题
  • 服务器内部工作
    tomcat中有一个work目录;
    IDEA中使用Tomcat的会在IDEA的tomcat中生产一个work目录
  • 浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
  • JSP最终也会被转换成为一个Java类!
  • JSP本质上就是一个Servlet
//初始化
public void _jspInit() {
    
}
//销毁
public void _jspDestroy() {
    
}
//JSPService
public void _jspservice(.HttpServletRequest request,HttpservletResponse)
  1. 判断请求
  2. 内置一些对象
final javax.servlet.jsp.Pagecontext pagecontext;//页面上下文
javax.servlet.http.Httpsession session = null; //Session
final javax.servlet.servletcontext application;  //applicationcontext
final javax.servlet.servletconfig config;  //config
javax.servlet.jsp.spwriter out = null;   //out
final java.lang.object page = this;   //page:当前
HttpServletRequest request;    //请求
HttpservletResponse response;   //响应
  1. 输出页面前增加的代码
response.setcontentType ("text/html");  //设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this,request,response,
                            null,true,8192,true);
jspx_page_context = pagecontext;
application = pagecontext. getservletcontext();config = pagecontext.getservletconfig(;
session = pagecontext.getsession(;
out = pagecontext.getout(;
_jspx_out = out;
  1. 以上的这些对象可以在JSP页面直接使用

![image-20220113192250565](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220113192250565.png)

在JSP页面中;
只要是JAVA代码就会原封不动的输出;

如果是HTML代码,就会被转换为:

out.write("<html>\r\n");

这样的格式,输出到前端!

JSP基础语法

![image-20220113194611959](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220113194611959.png)

![image-20220113195136005](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220113195136005.png)

<%-- JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>
--%>
<%-- jsp脚本片段 --%>
<%
  int sum = 0;
  for (int i = 1; i <=100 ; i++) {
    sum += i;
  }
  out.println("<h1>Sum=" + sum + "</h1>");
%>
<hr>
<%-- 在代码嵌入HTML元素 --%>
<%
  for (int i = 0; i < 5; i++) {
%>
<h1>Hello,world <%=i%> </h1>
<%
  }
%>
<%-- JSP声明
JSP声明:会被编译到JSP生成Java的类中!
其他的,就会被生成到_jspService方法中!
--%>
<%!
  static {
  System.out.println("Loading Servlet!");
  }
  private int globalVar = 0;
  public void index() {
    System.out.println("进入了方法index!");
  }
%>

JSP的注释,不会在客户端显示,HTML就会!

![image-20220113205323776](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220113205323776.png)

<%-- 定制错误页面 --%>
<%-- <%@page errorPage="error/500.jsp"%> --%>
<%-- 显示的声明这是一个错误页面 --%>
<%@ page isErrorPage="true"%>
<%@ page pageEncoding="UTF-8"%>
<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
<hr>

<%--jSP标签
jsp:incLude:拼接页面,本质还是三个--%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>

9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application 【ServletContext】 存东西
  • config 【ServletConfig】
  • out
  • page
  • exception

![image-20220113220521520](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220113220521520.png)

四大作用域

从底层到高层(作用域): page->request-->session-->application

  • request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻
  • session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车
  • application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据

标签,EL表达式

EL表达式:${ }

  • 获取数据

  • 执行运算

  • 获取web开发的常用对象


调用java方法

JSP标签

<%-- jsp:include --%>
<%--
http://localhost:8080/jsptag.jsp?name=xxx&age=xxx
--%>
<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="xxx"></jsp:param>
    <jsp:param name="age" value="xxx"></jsp:param>
</jsp:forward>

JSTL标签

<%-- 引入JSTL核心标签库,我们才能使用JSTL标签 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  • 核心标签

![image-20220113224341476](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220113224341476.png)

JSTL标签库使用步骤

  • 引入对应的taglib
  • 使用其中的方法
  • 在Tomcat也需要引入jstl的包,否则会报错:JSTL解析错误
<h4>if测试</h4>
<hr>
<form action="jstl.index.jsp" method="get">
    <%--
    EL表达式获取表单中的数据
    ${param.参数名}
    --%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登录">
</form>
<%-- 判断如果提交的用户名是管理员,则登录成功 --%>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="管理员欢迎您!"/>
</c:if>
<c:out value="${isAdmin}"/>

JavaBean

实体类

  1. JavaBean有特定的写法:

  2. 必须要有一个无参构造属性必须私有化

  3. 必须有对应的get/set方法;

一般用来和数据库的字段做映射ORM;

ORM:对象关系映射

  • 表--->类
  • 字段-->属性
  • 行记录---->对象

Poeple表

id name age address
1 小马 22 新疆
2 小李 23 新疆
3 小张 24 新疆
class People{
    private int id;
    private String name;
    private int id;
    private String address;
}

class A{
    new People(1,"小马",22,"新疆");
}

MVC三层架构

Model View Controller 模型、视图、控制器

早些年:

![image-20220117234155530](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220117234155530.png)

用户直接访问控制层,控制层就可以直接操作数据库;

Servlet--CRUD(增删改查)-->数据库弊端:
程序十分臃肿,不利于维护
servlet的代码中:
处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的!
程序员调用
 |
JDBC
 |
Mysq1 oracle sqlserver ...

MVC三层架构

![image-20220117235944004](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220117235944004.png)

![image-20220118000901623](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220118000901623.png)

过滤器Filter

过滤器:过滤网站的数据

  • 处理中文乱码
  • 登录验证。。

![image-20220118003104437](C:\Users\Marcus YL\AppData\Roaming\Typora\typora-user-images\image-20220118003104437.png)

开发步骤

  1. 导包 实现Filetr接口 javax.servlet

  2. 编写过滤器

    实现Filter接口,重写对应的方法

    public class CharacterEncodingFilter implements Filter {
    
        //初始化: web服务器启动,就已经初始化了,随时等待过滤器对象出现!
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("CharacterEncoding已经初始化了");
        }
    
        //filterChain :过滤器链
        /*
        1. 过滤器中的所有代码,在过滤特定请求时都会执行
        2. 必须要让过滤器继续通行
             filterChain.doFilter(req,resp);
         */
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
            resp.setCharacterEncoding("UTF-8");
            req.setCharacterEncoding("UTF-8");
            resp.setContentType("text/html;charset=utf-8");
    
            System.out.println("CharacterEncodingFilter执行前");
            filterChain.doFilter(req,resp);  //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
            System.out.println("CharacterEncodingFilter执行后");
        }
    
        //销毁 web服务器关闭的时候,过滤会销毁
        @Override
        public void destroy() {
            System.out.println("CharacterEncoding已经销毁");
        }
    }
    
  3. web.xml配置Filter过滤器

<filter>
  <filter-name>filter</filter-name>
  <filter-class>com.ma.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>filter</filter-name>
  <!--只要是/servlet的任何请求,会经过这个过滤器-->
  <url-pattern>/servlet/*</url-pattern>
</filter-mapping>

监听器

实现一个监听器的接口;(有N种)

posted @ 2022-03-24 18:27  M_L  阅读(98)  评论(0)    收藏  举报