Java基础知识(四)(WEB)

Java基础知识(四)

1.Web概念概述

  • JavaWeb:使用Java语言开发基于互联网的项目

  • 软件架构:
    1. C/S:Client/Server 客户端/服务器端
    在用户本地有一个客户端程序,在远程有一个服务器程序
    优点:用户体验好
    缺点:开发、安装、部署、维护麻烦
    2. B/S:Browser/Server 浏览器/服务器端
    只需要一个浏览器,用户通过不同的网址(URL),客户访问不同的服务器端程序
    优点:开发、安装、部署、维护简单
    缺点:如果应用过大,用户体验可能会受到影响;对硬件要求过高

  • B/S架构详解

    • 资源分类:
      1. 静态资源:使用静态网页开发技术发布的资源
        特点:所有用户访问,得到的结果是一样的
        如:文本、图片、音频、视频,HTML(用于搭建基础网页,展示页面内容),CSS(用于美化页面,布局页面),JavaScript(控制页面的元素,让页面有一些动态效果)
        如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器。浏览器中内置了静态资源的解析引擎,可以来展示静态资源
      2. 动态资源:使用动态网页及时发布的资源
        特点:所有用户访问,得到的结果可能不一样
        如:jsp/servlet,php,asp…
        如果用户请求的是动态资源,那么服务器会执行动态资源,转换成静态资源,再发送给浏览器。

2.HTML搭建基础网页,展示页面内容

                  👉HTML属性👈

  • 概念:Hyper Text Markup Language 超文本标记语言,是最基础的网络开发语言

  • 语法:
    1. html文档后缀名 .html或 .htm
    2. 标签分为
    围堵标签:有开始标签和结束标签。如<html></html>
    自闭和标签:</br>
    3. 标签可以嵌套
    4. 在开始标签中可以定义属性。属性是由键值对构成,值需要用引号引起来(单双都可)
    5. html不区分大小写,但建议小写

  • form:用于表单的定义。可以定义一个范围,范围代表采集用户数据的范围
    属性:
    1. action:指定提交数据的URL
    2. method:指定提交方式
    分类:一共7种,2种比较常用
    get:参数会在地址栏中显示,会封装到请求行中请求参数的长度是有限制的不太安全
    post:参数不会在地址栏中显示,会封装在请求体中请求参数的大小没有限制较为安全
    表单项中的值要想被提交:必须指定其name属性

  • 一些零碎的知识(👧当初没记住的)
    1. 单选框radio,复选框checkbox,一般会提供一个value值,指定其被选中后提交的值,checked属性可以指定默认值,要想让多个单选框实现单选的效果,name必须一致
    2. label的for属性一般会和input的id属性值对应。如果对应了,则点击label区域,会让input输入框获取焦点
    3. 取色器color
    4. textarea文本域,cols指定列数,每一行有多少字符,rows默认有多少行

3.CSS页面美化和布局控制

  • 概念:Cascading Style Sheets 层叠样式表
  • 好处:
    1. 功能强大
    2. 将内容展示和样式控制分离:降低耦合度,解耦;让分工协作更容易;提高开发效率
  • 选择器:筛选具有相似特征的元素
    1. 基本选择器
    id选择器:建议id值唯一,#id属性值{}
    元素选择器:标签名称{},id选择器高于元素选择器
    类选择器:选择具有相同class属性值的元素,.class属性值{},id>类>元素
    2. 扩展选择器:
    选择所有元素 *{}
    并集选择器:选择器1,选择器2
    子选择器:选择器1 选择器2{} (1下的2)
    父选择器:选择器1>选择器2{}(2的父1)
    属性选择器(选择元素名称,属性名=属性值的元素):元素名称[属性名=”属性值“]{}
    伪类选择器:元素:状态{}
  • 盒子模型:控制布局
    1. margin:外边距
    2. padding:内边距
    默认情况下内边距会影响整个盒子的大小
    解决:设置盒子的属性 box-sizing:border-box
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
<style>
    *{
        margin: 0px;
        padding: 0px;
        box-sizing: border-box;
    }
    body{
        background: url("img/1.jpg") no-repeat center;
    }

    .rg_layout{
        width: 900px;
        height: 500px;
        border: 8px solid #f0f0ff;
        background-color: rgba(255,255,255,0.8);
        /*s水平居中*/
        margin: auto;
        margin-top: 90px;
    }

    .rg_left{
        float: left;
        margin: 15px;
    }

    .rg_left p:first-child{
        color:#ffdf26;
        font-size: 20px;
    }

    .rg_left p:last-child{
        color:#a6a6a6;
        font-size:20px;
    }

    .rg_center{
        float: left;
        width: 450px;
        margin-top: 45px;
        margin-left: 35px;
    }

    .rg_right{
        float: right;
        margin: 13px;
    }

    .rg_right p:first-child{
        font-size: 15px;
    }

    .rg_right p a{
        color:pink;
    }

    .td_left{
        width: 100px;
        text-align: right;
        height: 45px;
    }

    .td_right{
        padding-left: 50px;
    }

    #username,#password,#email,#name,#tel,#birthday{
        width: 250px;
        height: 29px;
        border: 1px solid #a6a6a6;
        /*设置圆角*/
        border-radius: 5px;
        padding-left: 15px;
    }

    #checkcode{
        width: 110px;
        height: 29px;
        border: 1px solid #a6a6a6;
        /*设置圆角*/
        border-radius: 5px;
        padding-left: 15px;
    }

    #img_check{
        height: 29px;
        vertical-align: middle;
    }

    #btn_sub{
        width: 150px;
        height: 40px;
        background-color: #ffdf26;
        border: 1px solid #ffdf26;
        margin-left: 50px;
    }
</style>
</head>
<body>

<div class="rg_layout">
    <div class="rg_left">
        <p>新用户注册</p>
        <p>USER REGISTER</p>
    </div>

    <div class="rg_center">
        <div class="rg_form">
            <form action="#" method="post">
                <table>
                    <tr>
                        <td class="td_left"><label for="username">用户名</label></td>
                        <td class="td_right"><input type="text" name="username" id="username" placeholder="请输入用户名"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label for="password">密码</label></td>
                        <td class="td_right"><input type="password" name="password" id="password" placeholder="请输入密码"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label for="email">Emile</label></td>
                        <td class="td_right"><input type="email" name="email" id="email" placeholder="请输入Emile"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label for="name">姓名</label></td>
                        <td class="td_right"><input type="text" name="name" id="name" placeholder="请输入姓名"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label for="tel">手机号</label></td>
                        <td class="td_right"><input type="text" name="tel" id="tel" placeholder="手机号"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label>性别</label></td>
                        <td  class="td_right"><input type="radio" name="gender" id="male"><input type="radio" name="gender" id="femal"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label for="birthday">出生日期</label></td>
                        <td class="td_right"><input type="date" id="birthday" placeholder="请输入出生日期"></td>
                    </tr>
                    <tr>
                        <td class="td_left"><label for="checkcode">验证码</label></td>
                        <td class="td_right"><input type="text" name="checkcode" id="checkcode" placeholder="请输入验证码"/>
                            <img src="img/0.png" id="img_check"></td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center"><input type="submit" value="注册" id="btn_sub"></td>
                    </tr>
                </table>
            </form>
        </div>
    </div>

    <div class="rg_right">
        <p>已有账号<a href="#">立即登录</a></p>
    </div>
</div>

</body>
</html>

4.JavaScript

  • 概念:一门客户端脚本语言
    运行在客户端浏览器;每一个浏览器都有JavaScript的解析引擎
    脚本语言:不需要编译,直接就可以被浏览器解析执行
  • 功能:
    可以来增强用户和html页面的交互过程,可以来控制html元素,让页面有一些动态的效果,增强用户的体验
  • 发展史:
    1992年,Nombase公司开发出第一门客户端脚本语言,专门用于表单的校验。命名为:c–,后来改名为ScriptEase
    1995年,Netscape公司开发了一门客户端脚本语言:LiveScript。后来,请来SUN公司的专家,修改LiveScript:JavaScript
    1996年,微软抄袭JavaScript开发出JScript
    1997年,ECMA(欧洲计算机制造商协会),ECMAScript所有客户端脚本语言的标准
    *JavaScript=ECMAScript+JavaScript(BOM+DOM)

4.1 ECMAScript

4.1.1 基本语法
	1. 与html的结合方式:
	内部JS:定义`<script>`,标签体内容就是JS代码
	外部JS:定义`<script>`,通过src属性引入外部的js文件
	注意:
	`<script>`可以定义在html页面的任何位置,但是定义的位置会影响执行次序
	`<script>`可以定义多个
	2. 注释
	单行注释://注释内容
	多行注释:`/*注释内容*/`
	3. 数据类型
	<font color="#d6b2c6">原始数据类型(基本数据类型):</font>
	number(数字:整数/小数/NaN(not a number))
	string:字符串(没有字符的概念 “” ‘’都可以)
	boolean:true/false
	null:一个对象为空的占位符
	undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined
	<font color="#d6b2c6">引用数据类型:</font>对象
	4. 变量:一小块存储数据的内存空间
	Java语言是强类型语言,而JavaScript是弱类型语言
	(强类型开辟变量存储空间时,定义了空间将来存储的数据的数据类型,只能存储固定类型的数据)
	(弱类型开辟变量存储空间时,不定义空间将来存储的数据的数据类型,可以存储任意类型的数据)
	<font color="#d6b2c6">语法:</font>var 变量名=初始化值;
	`typeof()`获取变量的类型,注:null运算后得到的是object
	5. 运算符
	<font color="#d6b2c6">一元运算符</font>:只有一个运算数的运算符 ++ --0 +(正号) -(负号);
	在js中,如果运算数不是运算符所要求的类型,那么 js引擎会自动将运算符进行类型转换
	string转number,按照字面值转换,如果字面值不是数字,则转为NaN
	boolean转number,true转为1,false转为0
	<font color="#d6b2c6">算术运算符:</font>+ - * / %...
	<font color="#d6b2c6">赋值运算符:</font>= += -=...
	<font color="#d6b2c6">比较运算符:</font>> < >= <= == ===(全等于)
	类型相同:直接比较;字符串按照字典顺序按位比较
	类型不同:先进行类型转换,再比较
	===:在比较之前先判断类型。如果类型不同直接返回false
	<font color="#d6b2c6">逻辑运算符:</font>&& || !
	其他类型转boolean:
	number:0或NaN为假,非0为真
	string:除了空字符串(""),其他都是false
	null&undefined:都是false
	对象:所有对象都为true
	<font color="#d6b2c6">三元运算符:</font>?:
	<font color="#d6b2c6">流程控制语句:</font>?:
	6. 流程控制语句
	if else;
	switch:在Java中switch可以接收的数据类型:byte、int、short、char、枚举、String;JS中可以任意原始数据类型;
	while;
	do while;
	for
	7. JS特殊语法
	语句以;结尾,如果一行只有一条语句,则;可以省略(不建议);
	变量用var关键字,也可以不使用:用var定义的是局部变量;不用定义的是全局变量(不建议)

99乘法表联系:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>99乘法表e</title>
    <style>
        td{
            border: 1px solid;
        }
    </style>
    <script>
        document.write("<table align='center'>")
        for(var i=1;i<=9;i++){
            document.write("<tr>");
            for(var j=1;j<=i;j++){
                document.write("<td>");
                document.write(i+"*"+j+"="+(i*j)+"&nbsp;");
                document.write("</td>")
            }
            document.write("</tr>");
        }
    </script>
</head>
</html>
4.1.2 基本对象
  1. Function:函数(方法)对象
    创建:
    var fun = new Function(形式参数列表,方法体)
    function 方法名称(形式参数列表){
    方法体
    }
    var 方法名=function()
    属性:length:形参的个数
    特点:
    方法定义时形参的类型不用写,返回值类型也不写;
    方法是一个对象,如果定义名称相同的方法,会覆盖;
    在JS中只与方法的名称有关,和参数列表无关;
    在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数
    调用:方法名称(实际参数列表);
//求任意个数的和
        function add() {
            var sum=0;
            for (var i = 0; i < arguments.length; i++) {
                sum+=arguments[i];
            }
            return sum;
        }
        var s=add(1,2,5);
        alert(s);
  1. Array:数组对象
    创建:
    var arr = new Array(元素列表) ;
    var arr = new Array(默认长度);
    var arr = [元素列表];
    方法:
    join():将数组中的元素按照指定的分隔符拼接为字符串
    push():向数组的末尾添加一个或更多元素,并返回新的长度
    属性:length:数组的长度
    特点:JS中,数组元素的类型是可变的,数组的长度是可变的
  2. Boolean
  3. Date
    创建:var myDate=new Date();Date 对象会自动把当前日期和时间保存为其初始值。
    方法:
    toLocaleString():据本地时间格式,把 Date 对象转换为字符串
    getTime():返回 1970 年 1 月 1 日至今的毫秒数
  4. Math
    创建:无需创建,通过把 Math 作为对象使用就可以调用其所有属性和方法
    方法:
    random():返回 0 ~ 1 之间的随机数(包含0,不包含1)
    ceil(x):对数进行上舍入
    floor(x):对数进行下舍入
    round(x):把数四舍五入为最接近的整数
    属性:PI
  5. Number
  6. String
  7. RegExp:正则表达式对象
    正则表达式:定义字符串的组成规则
    单个字符:[]
    如:[abc] [a-zA-Z0-9_]
    特殊符号代表特殊含义的单个字符
    \d:单个数字字符
    \w:单个单词字符。
    量词符号:
    ?:表示出现0次或1次
    *:表示出现0次或1次
    +:出现1次或多次
    {m,n}:表示m<=数量<=n m如果缺省,表示最多n次,你缺省,最少m次
    正则对象
    创建:
    var reg=new new RegExp(“正则表达式”);
    var reg=/正则表达式/;
    方法:
    test:检索字符串中指定的值。返回 true 或 false。
    开始结束符号:^:开始;$:结束
  8. Global
    特点:全局对象,这个Global中封装的方法不需要对象就可以直接调用。方法名();
    方法:
    encodeURI():把字符串编码为 URI
    decodeURI():解码某个编码的 URI
    encodeURIComponent():把字符串编码为 URI 组件
    decodeURIComponent():解码一个编码的 URI 组件
    parseInt():解析一个字符串并返回一个整数
    isNaN():检查某个值是否是NaN(NaN和任何包括自己==比较都为false,只能用isNaN比较)
    eval():计算 JavaScript 字符串,并把它作为脚本代码来执行

4.2 BOM

  • 概念:Browser Object Model 浏览器对象模型
    将浏览器的各个组成部分封装成对象
  • 组成:
    Window:窗口对象
    Navigator:浏览器对象
    Screen:显示器屏幕对象
    History:历史记录对象
    Location:地址栏对象

  • Window:窗口对象
    1. 方法
    与弹出窗口有关的方法:
    alert() 显示带有一段消息和一个确认按钮的警告框
    confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框,如果点击确定方法返回true,取消返回false
    prompt() 显示可提示用户输入的对话框,返回值,获取用户输入的值
    与开关有关的方法:
    open() 打开一个新的浏览器窗口或查找一个已命名的窗口
    close() 关闭浏览器窗口,谁调用关谁
    与定时器有关的方法:
    setTimeout() 在指定的毫秒数后调用函数或计算表达式
    一次性定时器,参数:js代码或者对象方法,毫秒值,返回值:唯一标识,用于取消定时器
    clearTimeout() 取消由 setTimeout() 方法设置的 timeout
    setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式,循环定时器
    clearInterval() 取消由 setInterval() 设置的 timeout
    2. 属性:
    获取其他BOM对象
    history
    location
    Navigator
    Screen
    获取DOM对象
    document
    3. 特点:
    window对象不需要创建可以直接使用window,window.方法名
    window引用可以省略,方法名()
  • Location:地址栏对象
    1. 创建
    window.location
    location
    2. 方法:
    reload() 重新加载当前文档
    3. 属性:
    href 设置或返回完整的 URL

代码:获取页面标签(元素)对象 Element document.getElementById("ID值")
操作Element对象:
1. 修改属性值:明确获取的对象是哪一个;查看API文档,找其中有哪些属性值可以设置
2. 修改标签体内容:属性:innerHTML 获取元素对象;使用innerHTML属性修改标签体内容

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>自动跳转</title>
    <style>
        p{
            text-align: center;
        }
        span{
            color: red;
        }
    </style>
    <script>
        var second=5;
        function showtime() {
            second--;
            if(second<=0){
                location.href="https://www.baidu.com"
            }
            var time = document.getElementById("time");
            time.innerHTML=second+"";
        }
        setInterval(showtime,1000);
    </script>
</head>
<body>
    <p><span id="time">5</span>s之后自动跳转</p>
</body>
</html>
  • History:历史记录对象
    1. 创建
    window.history
    history
    location
    2. 方法:
    back() 加载 history 列表中的前一个 URL
    forward() 加载 history 列表中的下一个 URL
    go(参数) 加载 history 列表中的某个具体页面,参数:正数表示前进几个历史记录,负数表示后退几个历史记录
    3. 属性:
    length 返回当前窗口历史列表中的 URL 数量

4.3 DOM

  • 概念:Document Object Model 文档对象模型
    将标记语言文档的各个组成部分,封装为对象。可以使用这些对象,对标记语言文档进行CRUD的动态操作
  • W3C DOM 标准被分为 3 个不同的部分:
    Core DOM - 所有文档类型的标准模型
    Document:文档对象
    Element:元素对象
    Attribute:属性对象
    Text:文本对象
    Comment:注释对象
    Node:节点对象,其他五个的父类对象
    XML DOM - XML 文档的标准模型
    HTML DOM - HTML 文档的标准模型

Core DOM

  • Document:文档对象
    1. 创建(获取):在html dom模型中可以使用window对象来获取
    window.document
    document
    2. 方法
    获取element对象:
    getElementById() 查找具有指定的唯一 ID 的元素
    getElementsByTagName() 返回所有具有指定名称的元素节点,返回值是一个数组
    getElementsByClassName() 返回所有具有指定class的元素节点,返回值是一个数组
    getElementsByName() 返回所有具有指定name的元素节点,返回值是一个数组
    创建其他DOM对象:
    createAttribute(name) 创建拥有指定名称的属性节点,并返回新的 Attr 对象
    createComment() 创建注释节点
    createElement() 创建元素节点
    createTextNode() 创建文本节点
  • Element:元素对象
    1. 获取/创建:通过document来获取和创建
    2. 方法
    removeAttribute() 删除指定的属性
    setAttribute() 添加新属性
  • Node:节点对象,其他五个的父类对象
    1. 特点:所有dom对象都可以被认为是一个节点
    2. 方法
    CRUD dom树:
    appendChild() 向节点的子节点列表的结尾添加新的子节点
    removeChild() 删除(并返回)当前节点的指定子节点
    replaceChild() 用新节点替换一个子节点
    3. 属性:
    parentNode 返回节点的父节点

超链接功能:
1.可以被点击:样式
2.点击后跳转到href指定的url
需求:保留1,去掉功能2
实现:href="javascript:void(0)"


HTML DOM

  • 标签体的设置和获取:innerHTML
  • 使用html元素对象的属性
  • 控制样式
    使用元素的style属性来设置
    提前定义好类选择器的样式,通过元素的className属性来设置其class属性
事件监听机制
  • 概念:某些组件被执行了某些操作后,触发某些代码的执行
    事件:某些操作。如:单击、双击、键盘按下了,鼠标移动了
    事件源:组件。如:按钮 文本输入框…
    监听器:代码
    注册监听:将事件、事件源、监听器结合在一起。当事件源上发生了某一个事件,则触发执行某个监听器代码
  • 常见的事件:
    1. onclick 当用户点击某个对象时调用的事件句柄
    2. ondblclick 当用户双击某个对象时调用的事件句柄
    3. onblur 元素失去焦点
    4. onfocus 元素获得焦点
    5. onmousedown 鼠标按钮被按下
    定义方法时,定义一个形参接收event对象,event的button属性可以获取鼠标按钮哪个键被点击
    6. onmousemove 鼠标被移动
    7. onmouseout 鼠标从某元素移开
    8. onmouseover 鼠标移到某元素之上
    9. onmouseup 鼠标按键被松开
    10. onkeydown 某个键盘按键被按下
    11. onkeypress 某个键盘按键被按下并松开
    12. onkeyup 某个键盘按键被松开
    13. onchange 域的内容被改变
    14. onselect 文本被选中
    15. onsubmit 确认按钮被点击
    16. onreset 重置按钮被点击

5.Bootstrap

  • 概念:一个前端开发的框架,Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript 开发的简洁、直观、强悍的前端开发框架,使得 Web 开发更加快捷。
    框架:一个半成品软件,开发人员可以在框架基础上进行开发,简化编码
    好处:定义了很多的css和js插件。开发人员直接可以使用这些样式和插件得到丰富的页面效果;响应式布局:同一套页面可以兼容不同分辨率的设备
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Bootstrap 101 Template</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="js/jquery-3.4.1.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
</head>
<body>
<h1>你好,世界!</h1>
</body>
</html>

5.1 响应式布局

同一套页面可以兼容不同分辨率设备

  • 实现:依赖于栅格系统:将一行平均分成12个格子,可以指定元素占几个格子
  • 步骤:
    1. 定义容器。相当于之前的table
    容器分类:container(固定宽度);container-fluid(100% 宽度)
    2. 定义行。相当于tr
    样式:row
    3. 定义元素。相当于td
    指定该元素在不同设备上所占的格子数目。样式:col-设备代号-格子数目
    设备代号:
    .col-xs- 超小屏幕 手机 (<768px)
    .col-sm- 小屏幕 平板 (≥768px)
    .col-md- 中等屏幕 桌面显示器 (≥992px)
    .col-lg- 大屏幕 大桌面显示器 (≥1200px)

注意:
一行中如果格子数目超过12,则超出部分自动换行;
栅格向上兼容,适用于与屏幕大于或等于分界点大小的设备;
如果真实设备宽度小于了设置栅格类属性的设备代码的最小值,会一个元素占满一整行

5.2 全局CSS样式和JS插件

Bootstrap中文官网

  • 全局CSS样式:
    按钮 class="btn btn-primary"
    图片 class="img-responsive" class="img-rounded" class="img-circle" class="img-thumbnail"
    表格 class="table"
    表单 class="form-group" class="form-control"
  • 组件:
    导航条
    分页条
  • 插件:
    轮播图

6.XML

概念:Extersible Markup Language 可扩展标记语言

  • 可扩展:标签都是自定义的。
  • 功能
    存储数据:配置文件;在网络中传输
  • XML与HTML区别
    同出自w3c:万维网联盟
    类似properties的功能
    1. xml标签都是自定义的,html标签是预定义的
    2. xml语法非常严格,html语法松散
    3. xml存储数据,html展示数据

语法结构

  • 基本语法
    1. xml文档的后缀名 .xml
    2. xml第一行必须定义为文档声明
    3. xml文档中有且仅有一个根标签
    4. 属性值必须使用引号(单双都可)引起来
    5. 标签必须正确关闭
    6. xml标签名称区分大小写
  • 组成部分
    1. 文档声明
    格式:<?xml 属性列表?>
    属性列表:
    version:版本号,必须的属性
    encoding:编码方式,告知解析引擎当前文档所用的字符集,默认:ISO-8859-1
    standalone: 是否独立  取值:yes(不依赖其他文件)/no(依赖其他文件)
    2. 指令 (了解):结合css的 <?xml-stylesheet type="text/css" href="a.css" ?>
    3. 标签:标签名称自定义的
    规则:
    名称可以包含字母、数字和其他字符
    名称不能以数字或者标点符号开始
    名称不能以字母xml(Xml、XML、…)开始
    名称不能包含空格
    4. 属性:id属性值唯一
    5. 文本:
    CDATA区:在该区域中的数据会被原样展示<![CDATA[ 数据 ]]>
  • 约束:规定xml文档的书写规范
    作为框架的使用者(程序员):
      1. 能够在xml中引入约束文档
      2. 能够简单地读懂约束文档
    分类:
      1. DTD:一种简单的约束技术
      2. Schema:一种复杂的约束技术
    DTD:
      1. 引入dtd文档(.dtd)到xml文档中:
       内部dtd:将约束规则定义在xml文档中;
       外部dtd:将约束的规则定义在外部的dtd文件中
         本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
         网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" ”dtd文件的位置“>
    Schema (.xsd)
      1. 填写xml文档
      2. 引入xsi前缀
      3. 引入xsd文件命名空间
      4. 为每个xsd约束声明一个前缀,作为标识

解析:操作XML文档,将文档中的数据读取到内存中

  • 操作XML文档
      1. 解析(读取):将文档中的数据读取到内存中
      2. 写入:将内存中的数据保存到xml文档中。持久化的存储
  • 解析XML的方式
      1. DOM:将标记语言文档一次性加载进内存,在内存中形成一棵dom树
        优点:操作方便,可以对文档进行CRUD的所有操作
        缺点:占内存
      2. SAX:逐行读取,基于事件驱动的
        优点:不占内存
        缺点:只能读取,不能增删改
  • xml常见的解析器
      1. JASP:sun公司提供的解析器,支持dom和sax两种思想
      2. DOM4J:一款非常优秀的解析器
      3. Jsoup:jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM、CSS以及类似于JQuery的操作方法来取出和操作数据。
      4. PULL:Android操作系统内置的解析器,sax方式
  • Jsoup:jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM、CSS以及类似于JQuery的操作方法来取出和操作数据
      步骤:
        1. 导入jar包
        2. 获取Document对象
        3. 获取对应的标签Element对象
        4. 获取数据
  //获取Document对象,根据xml文档获取
        //获取xml的path路径
        String path = jsoup1.class.getClassLoader().getResource("xml.xml").getPath();
        //解析xml文档,加载文档进内存,获取dom树--->Document
        Document document = Jsoup.parse(new File(path), "UTF-8");
        //获取元素对象 Element对象
        Elements elements = document.getElementsByTag("name");
        Element element=elements.get(0);
        String name=element.text();
        System.out.println(name);
  • 对象的使用
      1.Jsoup:工具类,可以解析html或xml文档,返回Doucument
        parse:解析html或xml文档,返回Document
          parse(File in, String charsetName):解析xml或html文件的
          parse(String html):解析xml或html字符串
          parse(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
      2.Doucument:文档对象。代表内存中的dom树
        获取Element对象
          getElementById(String id):根据id属性值获取唯一的element对象
          getElementByTag(String tagName):根据标签名称获取元素对象集合
          getElementByAttribute(String key):根据属性名称获取元素对象集合
          getElementByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合
      3.Elements:元素Element对象的集合。可以当作ArrayList<Element>来使用
      4.Element:元素对象
        获取子元素对象
          getElementById(String id):根据id属性值获取唯一的element对象
          getElementByTag(String tagName):根据标签名称获取元素对象集合
          getElementByAttribute(String key):根据属性名称获取元素对象集合
          getElementByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合
        获取属性值
          String attr(String key):根据属性名称获取属性值
        获取文本内容
          String text():获取所有子标签的纯文本内容
          String html():获取标签体的所有内容(包括子标签的标签和文本字内容)
      5.Node:节点对象
        是Document和Element的父类对象
  • 快捷查询方式
      1.selector:选择器
        使用的方法:Elements select(String cssQuery)
          语法:参考Selector类中定义的语法
      2.XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言
        使用Jsoup的XPath需要额外导入jar包
        查询w3cschool参考手册,使用xpath的语法完成查询

7.web服务器软件:Tomcat

  • 服务器:安装了服务器软件的计算机
  • 服务器软件:接收用户的请求,处理请求,做出响应
  • web服务器软件:接收用户的请求,处理请求,做出响应
      在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目
      web容器
  • 常见的Java相关的web服务器软件:
      webLogic:Oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费
      webSphere:IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费
      JBOSS:JBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费
      Tomcat:Apache基金组织,中小型的JavaEE服务器,仅支持少量JavaEE规范,开源,免费
  • JavaEE:Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范

Tomcat

  • 配置
      部署项目的方式:
        1.直接将项目放到webapps目录下即可
          /项目名称:项目的访问路径—>虚拟路径
          简化部署:将项目打成一个war包,再将war包放置在webapps目录下,war包会解压缩
        2.配置conf/server.xml
          在<Host>标签体中配置<Context docBase="项目路径" path=“自定义”>
          docBase:项目存放的路径;path:虚拟目录
        3.在conf\Catalina\localhost创建任意名称的xml文件。在文件中编写,虚拟路径:xml的文件名称
  • 静态项目和动态项目:
      目录结构
        Java动态项目的目录结构
        --项目的根目录
          --WEB-INF目录:
            --web.xml:web项目的核心文件配置文件
            --classes目录:放置字节码文件的目录
            --lib目录:放置依赖jar包
  • 将Tomcat集成到IDEA中,并且创建JavaEE项目,部署项目。

IDEA与tomcat的相关配置

  • IDEA会为每一个tomcat部署的项目单独建立一份配置文件
      查看控制台的log:Using CATALINA_BASE: “C:\Users\丫.IntelliJIdea2019.2\system\tomcat_demo0”
  • 工作空间项目 和 tomcat部署的web项目
      tomcat真正访问的时“tomcat部署的web项目”,“tomcat部署的web项目”对应着“工作空间项目”的web目录下的所有资源
      WEB-INF目录下的资源不能被浏览器直接访问到

8.Servlet:

  • 概念:运行在服务器端的小程序
      Servlet就是一个接口,定义了Java类被浏览器访问到(Tomcat识别)的规则
      将来我们自定义一个类,实现Servlet接口,复写方法
  • 快速入门:
      1.创建JavaEE项目
      2.定义一个类,实现Servlet接口
      3.实现接口类中的抽象方法
      4.配置Servlet,在web.xml中:
<!--  配置servlet  -->
    <servlet>
        <servlet-name>demo1</servlet-name>
        <servlet-class>day01.se.web.servlet.ServletDemo1</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
  • 执行原理
      1.当服务器接受到客户端浏览器的请求后,会解析请求的URL路径,获取访问的Servlet的资源路径
      2.查找web.xml文件是否有对应的<url-pattern>标签体内容
      3.如果有,则再找到<servlet-class>全类名
      4.tomcat会将字节码文件加载进内存,并且创建其对象
      5.调用其方法

  • Servlet中的生命周期
      1.被创建:执行init方法,只执行一次
        Servlet什么时候被创建?
          默认情况下,第一次被访问时,Servlet被创建
          可以配置执行Servlet的创建时机
            在servlet标签下配置:
            <!--指定Servlet的创建时机
            1.第一次被访问时创建,<load-on-startup>的值为负数
            2.在服务器启动时创建,<load-on-startup>的值为0或正整数
            --><load-on-startup>5</load-on-startup>
        Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
          多个用户同时访问时,可能存在线程安全问题
          解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量也不要对其修改值
      2.提供服务:执行service方法,执行多次
        每次访问Servlet时,Service方法都会被调用一次。
      3.被销毁:执行destroy方法,执行一次
        Servlet被销毁时被执行。服务器(只有)正常关闭时才会执行。被销毁之前被执行,一般用于释放资源
/**
 * Servlet的方法
 */
public class ServletDemo2 implements Servlet {
    /**
     * 初始化方法
     * 在Servlet被创建时,执行。只会执行一次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init...");
    }

    /**
     *获取ServletConfig对象
     * ServletConfig:Servlet的配置对象
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 提供服务方法
     * 每一次Servlet被访问时,执行。执行多次
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service...");
    }

    /**
     * 获取serlvet的一些信息,版本,作者等
     * @return
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 销毁方法
     * 在服务器正常关闭时,执行,执行一次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }
}


  • Servlet3.0:
      好处:
        支持注解配置
      步骤:
        1.创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
        2.定义一个类,实现Servlet接口
        3.复写一个方法
        4.使用@WebServlet注解,进行配置@WebServlet("资源路径")

  • Servlet体系结构
      Servlet----接口
         |
      GenericServlet----抽象类
         |
      HttpServlet----抽象类
  • GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
      将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可
  • HttpServlet:对http协议的一种封装,简化操作
      1.定义继承HttpServlet
      2.复写doGet/doPost方法

  • Servlet相关配置
      1.urlpartten:Servlet访问路径
        一个Servlet可以定义多个访问路径@WebServlet({"/demo1","/demo","demo2"})
      2.路径定义规则:
        1./xxx
        2./xxx/xxx
        3.*.do

9.HTTP:

  • 概念:Hyper Text Transfer Protoco 超文本传输协议
      传输协议:定义了客户端与服务器端发送数据的格式
      特点:
        1.基于TCP/IP的高级协议
        2.默认端口号:80
        3.基于请求/响应模型的:一次请求对应一次响应
        4.无状态的:每次请求之间相互独立,不能交互数据
      历史版本:
        1.0:每一次请求响应都会建立新的连接
        1.1:复原连接
  • 请求消息数据格式
      1.请求行
        请求方式 请求URL 请求协议/版本
        例子:GET /login.in HTTP/1.1
        请求方式:
          HTTP有7种请求方式,常用的有2种
            GET:
              1.请求参数在请求行中,在url之后
              2.请求的url有限制
              3.不太安全
            POST:
              1.请求参数在请求体中
              2.请求的url长度没有限制
              3.相对安全
      2.请求头请求头名称:请求头值
        常见的请求头
          1.User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息、
            可以在服务器端获取该头信息,解决浏览器的兼容问题
          2.Referer:告诉服务器,当前请求从哪里来
            作用:防盗链;统计工作
      3.请求空行
        空行,用于分割POST请求头和请求体的
      4.请求体(正文)
        封装POST请求消息的请求参数的
  • 响应消息:服务器端发给客户端的数据
      数据格式:
        1.响应行
          1.组成:协议/版本 响应的状态码 状态码描述
          2.响应状态码:服务器告诉客户端浏览器本次请求和响应的状态
            1.状态码都是3位数字
            2.分类:
              1.1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx状态码
              2.2xx:成功。代表:200
              3.3xx:重定向。代表:302(重定向),304(访问缓存)
              4.4xx:客户端错误。代表:404(请求路径没有对应的资源),405(请求方式没有对应的doxx方法)
              5.5xx:服务器端错误。代表:500(服务器内部出现异常)
        2.响应头
          1.格式:头名称:值
          2.常见的响应头:
            1.Content-Type:服务器端告诉客户端本次响应体的数据格式及编码格式
            2.Content-disposition:服务器告诉客户端以什么格式打开响应体数据
              值:
                in-line:默认值,在当前页面内打开
                attachment;filename=xxx:以附件形式打开响应体。文件下载
        3.响应空行
        4.响应体:传输的数据

request对象和response对象的原理
  1.request和response对象是由服务器创建的,我们来使用它
  2.request对象是来获取请求消息,response是来设置响应消息

10.Request对象

  • request对象继承体系结构:
      ServletRequest – 接口
         | 继承
      HttpServletRequest – 接口
         | 实现
      org.apache.catalina.connector.RequestFacade 类(tomcat)
  • request功能:
      1.获取请求消息数据
        1.获取请求行数据
          方法:
            1.获取请求方式:String getMethod()
            2.获取虚拟目录String getContexPath()
            3.获取Servlet路径:String getServlet()
            4.获取get方式的请求参数:String getQueryString()
            5.获取请求的uriString getRequestURI() StringBuffer getRequestURL()
              URL:统一资源定位符(长的)http://localhost:8080/day0_war_exploded/demo01
              URI:统一资源标识符(范围更大,短的)/day0_war_exploded/demo01
            6.获取协议及版本:String getProtocol()
            7.获取客户机的ip地址:String getRemoteAddr()
        2.获取请求头数据
      方法:
        String getHeader(String name)通过请求头的名称获取请求头的值
        Enumeration<String> getHeaderNames():获取所有的请求头名称
        3.获取请求体数据
          请求体:只有POST请求方式,才有请求体,在请求体封装了POST请求的请求参数
          步骤:
            1.获取数据流
              BufferedReader getReader():获取字符输入流,只能操作字符数据
              ServletInputStream getInputStream():获取字节输入流,可以操作操作所有类型的数据
            2.再从流对象中拿数据
      2.其他功能:
        1.获取请求参数通用方式:无论是get还是post请求方式都可以使用下列方法来获取请求参数
          1.String getParameter(String name)根绝参数名称获取参数值
          2.String[] getParameterValues(String name):根绝参数名称获取参数值数组
          3.Enumeration<String> getParameterNames():获取所有请求的参数名称
          4.Map<String, String[]> getParameterMap()获取所有参数的集合
        中文乱码问题:
          get方式:tomcat 8已经将get乱码问题解决了
          post方式:会乱码
            解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8")
        2.请求转发:一种在服务器内部的资源跳转方式
          1.步骤
            1.通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
            2.使用RequestDispatcher 对象进行转发:forward(ServletRequest request, ServletResponse)
          2.特点:
            1.浏览器地址栏路径不发生变化
            2.只能转发到当前服务器内部资源中
            3.转发是一次请求
        3.共享数据:
          域对象:一个有作用范围的对象,可以在范围内共享数据
          request域:代表一次请求的范围,一般用于转发的多个资源中共享数据
          方法:
            1.setAttribute(String name, Object obj):存储数据
            2.getAttitude(String name):通过键来获取值
            3.removeAttribute(String name):通过键来移除键值对
        4.获取ServletContext:
          getServletContext()

ServletContext

  • 概念:代表整个web应用,可以和程序的容器(服务器)来通信
  • 获取:
      1.通过request对象获取:request.getServletContext()
      2.通过HttpServlet获取:this.getServletContext()
  • 功能:
      1.获取MIME类型:
        MIME类型:在互联网通信过程中定义的一种文件数据类型
          格式:大类型/小类型   eg:text/html
        方法:String getMimeType(String file)
      2.域对象:共享数据
          1.setAttribute(String name, Object obj):存储数据
          2.getAttitude(String name):通过键来获取值
          3.removeAttribute(String name):通过键来移除键值对
        ServletContext对象范围:所有用户所有请求的数据
      3.获取文件的真实(服务器)路径
        1.方法:String getRealPath(String path)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String method = request.getMethod();
        System.out.println(method);
        String contextPath = request.getContextPath();
        System.out.println(contextPath);
        String servletPath = request.getServletPath();
        System.out.println(servletPath);
        String queryString = request.getQueryString();
        System.out.println(queryString);
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURI);
        System.out.println(requestURL);
        String protocol = request.getProtocol();
        System.out.println(protocol);
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
    }
 String referer = request.getHeader("referer");
        //防盗链
        if(referer!=null){
            response.getWriter().write("ok");
        }else {
            System.out.println("no");
        }

  • BeanUtils工具类,简化数据封装
      用于封装JavaBean
      1.JavaBean:标准的Java类
       1.要求:
        1.类必须被public修饰
        2.必须提供空参的构造方器
        3.成员变量必须使用private修饰
        4.提供公共的getter和setter方法
       2.功能:封装数据
      2.概念:
        成员变量:
        属性:setter和getter方法截取后的产物
      3.方法:
        1.setProperty
        2.getProperty()
        3.populate(Object obj , Map map):将map集合的键值对信息,封装到对应的JavaBean对象中

11.Respose对象

  • 功能:设置响应消息
      1.设置响应行
        1.格式:HTTP/1.1 200 ok
        2.设置状态码:setStatus(int sc)
      2.设置响应头:setHeader(String name , String value)
      3.设置响应体:
        使用步骤
          1.获取输出流
            字符输出流:PrintWriter getWriter()
            字节输出流:ServletOutputStream getOutputStream()
          2.使用输出流,将数据输出到客户端浏览器
/**
 * 重定向
 */
@WebServlet("/response1")
public class response extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("1被访问了");
        //访问/response1会自动跳转到2
        //1.设置状态码为302
        response.setStatus(302);
        //2.设置响应头location
        response.setHeader("location","/day0_war_exploded/response2");
        //简单的重定向方法
        response.sendRedirect("/day0_war_exploded/response2");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • 重定向(redirect)的特点
      1.地址栏发生变化
      2.重定向可以访问其他站点(服务器)的资源
      3.重定向是两次请求,不能使用request对象来共享数据
  • 转发(forward)的特点
      1.地址栏路径不变
      2.转发只能访问当前服务器下的资源
      3.转发是一次请求,可以使用request对象来共享数据
  • 路径写法
      1.路径分类
        1.相对路径:通过相对路径不可以确定唯一资源,不以/而以.开头路径
          规则:找到当前资源与目标资源之间的相对位置关系
            ./:当前目录
            ../:后退一级目录
        2.绝对路径:通过绝对路径可以确定唯一资源,以/开头的路径
          规则:判断定义的路径是给谁用的?判断请求将来从哪里发出
            给客户端浏览器使用:需要加虚拟目录(项目的访问路径),建议虚拟目录动态获取,比如重定向…
            给服务器使用:不需要加虚拟目录,比如转发路径
//动态获取虚拟目录
        String contextPath = request.getContextPath();
        response.sendRedirect(contextPath+"/response2");
  • 服务器输出字符数据到浏览器
    注意:乱码问题:PrintWriter pw=response.getWriter();获取的流默认ISO-8859-1,设置该流默认编码,告诉浏览器响应体使用的编码
		//获取流对象之前,设置默认编码
        //response.setCharacterEncoding("utf-8");
		//告诉浏览器,服务器发送的消息体数据的编码。建议浏览器使用该编码解码
        //response.setHeader("content-type","text/html;charset=utf-8");

        //简单的形式
        response.setContentType("text/html;charset=utf-8");

        //获取字符输出流
        PrintWriter pw=response.getWriter();
        
        //输出数据
        //pw.write("<h1>你好</h1>");
        pw.write("你好啊");
  • 服务器输出字节数据到浏览器
		response.setContentType("text/html;charset=utf-8");
		//获取字节输出流
        ServletOutputStream sos=response.getOutputStream();
        //输出数据
        sos.write("你好".getBytes("utf-8"));
  • 验证码案例
      1.本质:图片
      2.目的:防止恶意表单注册
@WebServlet("/CheckCode")
public class CheckCode extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width=100;
        int height=50;
        //1.创建一个对象,在内存中图片(验证码图片对象)
        BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);

        //2.美化图片

        //2.1 填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.pink);//设置画笔颜色
        g.fillRect(0,0,width,height);

        //2.2画边框
        g.setColor(Color.blue);
        g.drawRect(0,0,width-1,height-1);

        //2.3写验证码
        String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        //生成随机角标
        Random ran=new Random();
        for (int i = 1; i <=4; i++) {
            int index = ran.nextInt(str.length());
            //获取字符
            char c = str.charAt(index);//随机字符
            g.drawString(c+"",width/5*i,height/2);
        }
        //2.4画干扰线
        g.setColor(Color.cyan);
        for (int i = 0; i < 10; i++) {
            //随机生成坐标点
            int x = ran.nextInt(width);
            int x2 = ran.nextInt(width);
            int y = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x,x2,y,y2);
        }

        //3.将图片输出到页面展示
        ImageIO.write(image,"jpg",response.getOutputStream());
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        /*
            点击图片换一张
            1.给图片绑定单机事件
            2.重新设置图片的src属性值
         */
        window.onload=function () {
            //1.获取图片对象
            var img = document.getElementById("check");
            //2.绑定单机事件
            img.onclick=function () {
                //加时间戳
                var date=new Date().getTime();
                img.src="/day0_war_exploded/CheckCode?"+date;
            }
        }
    </script>
</head>
<body>
    <img id="check" src="/day0_war_exploded/CheckCode">
</body>
</html>
  • 文件下载案例
      需求:
        1.页面显示超链接
        2.点击超链接后弹出下载提示框
        3.完成图片文件下载
      分析:
        1.超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
        2.任何资源都必须弹出下载提示框
        3.使用响应头设置资源的打开方式:content-disposition:attachment;filename=xxx以附件形式
      步骤:
        1.定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
        2.定义Servlet
          1.获取文件名称
          2.使用字节输入流加载文件进内存
          3.指定response的响应头:content-disposition:attachment;filename=xxx;
          4.将数据写出到response输出流
      中文文件名问题
        解决思路:
          1.获取客户端使用的浏览器版本信息
          2.根据不同
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取请求参数,文件名称
        String filename = request.getParameter("filename");
        //2.使用字节输入流加载文件进内存
        //2.1找到文件服务器路径
        ServletContext servletContext = this.getServletContext();
        String realPath = servletContext.getRealPath("/img/" + filename);
        //2.2用字节流关联
        FileInputStream fis=new FileInputStream(realPath);
        //3.设置response的响应头
        //3.1设置响应头类型
        String mimeType = servletContext.getMimeType(filename);//获取MIME类型
        response.setHeader("content-type",mimeType);
        //3.2设置响应头打开方式
         //解决中文文件名问题
        //1.获取user-agent请求头
        String agent = request.getHeader("user-agent");
        //2.使用工具类方法编译文件名即可
        filename=DownLoadUtils.getFilename(agent,filename);
        response.setHeader("content-disposition","attachment;filename="+filename);
        //4.将输入流的数据写出到输出流中
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] buff=new byte[1024*8];
        int len=0;
        while ((len=fis.read(buff))!=-1){
            outputStream.write(buff,0,len);
        }
        fis.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/day0_war_exploded/downloadServlet?filename=1.jpg">图片</a>
</body>
</html>

12.会话技术

  • 会话:一次会话中包含多次请求和响应
      一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
  • 功能:共享数据:在一次会话的范围内的多次请求间,共享数据
  • 方式
      1.客户端会话技术:Cookie
      2.服务器端会话技术:Session

12.1 Cookie:小甜点

  • 概念:客户端会话技术,将数据保存到客户端
  • 快速入门:
      使用步骤:
        1.创建Cookie对象,绑定数据
          new Cookie(String name, String value)
        2.发送Cookie
          response.addCookie(Cookie cookie)
        3.获取Cookie,拿到数据
          Cookie[] request.getCookies()
@WebServlet("/cookiedemo")
public class cookiedemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Cookie对象
        Cookie c=new Cookie("msg","hello");
        //2.发送Cookie
        response.addCookie(c);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

@WebServlet("/cookiedemo2")
public class cookiedemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //3.获取Cookie
        Cookie[] cs = request.getCookies();
        //获取数据,遍历Cookies
        for (Cookie c : cs) {
            String name = c.getName();
            String value = c.getValue();
            System.out.println(name+":"+value);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • 实现原理:基于响应头set-cookie和请求头cookie实现
  • Cookie的细节:
      1.一次可不可以发送多个Cookie
        可以
        可以创建多个Cookie对象,使用response调用多次addCookie方法发送Cookie即可
      2.Cookie在浏览器保存多久
        1.默认情况下,当浏览器关闭后,Cookie数据被销毁
        2.持久化存储:
          setMaxAge(int seconds)
          1.正数:将Cookie数据写到硬盘的文件中seconds秒。持久化存储。cookie存活时间,
          2.负数:默认值
          3.零:删除cookie信息
      3.Cookie能不能存中文
        在tomcat8之前,cookie中不能直接存储中文数据
          需要将中文数据转码—一般采用url编码(%E3)
        在tomcat8之后,cookie支持中文数据,但特殊字符仍然不支持
      4.Cookie共享问题
        1.假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
          默认情况下cookie不能共享
          setPath(String path):设置cookie的获取范围,默认情况下会设置当前的虚拟目录
          如果要共享,则可以将path设置为“/”
        2.不同的tomcat服务器间可以共享吗
          setDomain(String path):如果设置一级域名相同,那么多个服务器之间的cookie可以共享
  • Cookie的特点和作用
      1.cookie存储在客户端浏览器
      2.浏览器对于单个cookie的大小(4KB左右)有限制,以及对同一个域名下的总cookie数量也有限制(20个)
     作用
      1.cookie一般用于存储少量不太敏感的数据
      2.在不登录的情况下,完成服务器对客户端的身份识别
  • 案例:记住上一次访问时间
      1.需求:
        1.访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
        2.如果不是第一次,则提示:欢迎回来,您上次访问的时间是:显示时间字符串
      2.分析
        1.可以采用cookie来判断
        2.在服务器中的Servlet是否有一个名为lastTime的cookie
          1.有:不是第一次访问
            1.响应数据:欢迎回来,您上次访问的时间为lastTime
            2.写回cookie:lastTime
          2.没有:是第一次访问
            1.响应数据:您好,欢迎您首次访问
            2.写回cookie:lastTime=
@WebServlet("/cookiedemo")
public class cookiedemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应的消息体的数据格式及编码
        response.setContentType("text/html;charset=utf-8");
        //获取所有的cookie
        Cookie[] cookies = request.getCookies();
        boolean flag=false;
        //遍历
        if(cookies!=null && cookies.length>0){
            for (Cookie cookie : cookies) {
                //获取cookie的名称
                String name = cookie.getName();
                //判断是否是lastTime
                if("lastTime".equals(name)){
                    //有该cookie
                    flag=true;
                    //设置cookie的value值
                    //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
                    Date date=new Date();
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String str_date = sdf.format(date);
                    System.out.println("编码前"+str_date);
                    //URL编码
                    str_date= URLEncoder.encode(str_date,"utf-8");
                    System.out.println("编码后"+str_date);

                    //响应数据
                    //获取cookie的value
                    String value = cookie.getValue();
                    System.out.println("解码前"+value);
                    //URL解码
                    value= URLDecoder.decode(value,"utf-8");
                    System.out.println("解码后"+str_date);
                    response.getWriter().write("<h1>欢迎回来,您上次的访问时间为"+value+"</h1>");

                    cookie.setValue(str_date);
                    //设置cookie的存活时间
                    cookie.setMaxAge(60*60*24*30);
                    response.addCookie(cookie);
                    break;
                }
            }
        }
        if(cookies==null||cookies.length==0||flag==false){
            //第一次访问
            //设置cookie的value值
            //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
            Date date=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String str_date = sdf.format(date);
            System.out.println("编码前"+str_date);
            //URL编码
            str_date= URLEncoder.encode(str_date,"utf-8");
            System.out.println("编码后"+str_date);
            Cookie cookie=new Cookie("lastTime",str_date);
            //设置cookie的存活时间
            cookie.setMaxAge(60*60*24*30);
            response.addCookie(cookie);
            //响应数据
            //获取cookie的value
            String value = cookie.getValue();
            response.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

12.2 Session:主菜

  • 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象。HttpSession
  • 快速入门:
      1.获取HttpSession对象:
        HttpSession session = request.getSession()
      2.使用HttpSession对象:
        Object getAttribute(String name)
        void setAttribute(String name , Object value)
        void removeAttribute(String name)
  • 原理:Session的实现是依赖于Cookie的
  • 细节:
      当客户点关闭后,服务器不关闭,两次获取session是否为同一个?
        默认情况下不是
        如果需要相同,则可以创建cookie,键为JESSIONID,设置最大存活时间,让cookie持久化保存
        Cookie c=new Cookie("JESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
      客户端不关闭,服务器关闭后,两次获取的Session是否为同一个?
        不是同一个,但是要确保数据不丢失
          session的钝化:
            在服务器正常关闭之前,将session对象序列化到硬盘上
          session的活化
            在服务器启动后,将session文件转化为内存中的对象即可
      session什么时候被销毁?
        1.服务器关闭
        2.session对象调用invalidate()
        3.session默认失效时间是30分钟
          选择性配置修改
          <session-conig>
            <session-timeout>30</session-timeout>
          </session-config>
  • 特点:
      1.session用于存储一次会话的多次请求的数据,存在服务器端
      2.session可以存储任意类型,任意大小的数据

  • session与cookie的区别
      1.session存储数据在服务器端,cookie在客户端
      2.session没有数据大小的限制,cookie有
      3.session数据安全,cookie相对于不安全

  • 验证码判断案例
      1.需求
        1.访问带有验证码的登录界面login.jsp
        2.用户输入用户名,密码以及验证码
          如果用户名和密码有误,跳转登录界面,提示:用户名和密码错误
          如果验证码输入有误,跳转登录界面,提示:验证码错误
          如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置request编码
        request.setCharacterEncoding("utf-8");
        //2.获取参数
        String uesrname = request.getParameter("uesrname");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");
        //获取生成的验证码
        HttpSession session=request.getSession();
        String checkCode_session = (String) session.getAttribute("checkCode_session");
        //删除session中存储的验证码
        session.removeAttribute("checkCode_session");
        //先判断验证码是否正确
         if(checkCode_session!=null&&checkCode_session.equalsIgnoreCase(checkCode)){
            //忽略大小写比较字符串,再判断用户,密码正确与否
            if("z".equals(uesrname)&&"1".equals(password)){
                //登录成功,存储信息
                //重定向到success.jsp
                session.setAttribute("user",uesrname);
                response.sendRedirect(request.getContextPath()+"/success.jsp");
            }
            else{
                //登录失败
                //存储信息,转发到login.jsp
                request.setAttribute("error","");
                request.getRequestDispatcher("").forward(request,response);
            }
        }else {
            //验证码不一致
            //存储提示信息到request
            request.setAttribute("cc_error","验证码错误");
            //转发到登陆界面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

@WebServlet("/CheckCode")
public class CheckCode extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width=100;
        int height=50;
        //1.创建一个对象,在内存中图片(验证码图片对象)
        BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);

        //2.美化图片

        //2.1 填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.pink);//设置画笔颜色
        g.fillRect(0,0,width,height);

        //2.2画边框
        g.setColor(Color.blue);
        g.drawRect(0,0,width-1,height-1);

        //2.3写验证码
        String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        //生成随机角标
        Random ran=new Random();
        StringBuilder sb=new StringBuilder();
        for (int i = 1; i <=4; i++) {
            int index = ran.nextInt(str.length());
            //获取字符
            char c = str.charAt(index);//随机字符

            sb.append(c);

            //写验证码
            g.drawString(c+"",width/5*i,height/2);
        }
        //2.4画干扰线
        g.setColor(Color.cyan);
        for (int i = 0; i < 10; i++) {
            //随机生成坐标点
            int x = ran.nextInt(width);
            int x2 = ran.nextInt(width);
            int y = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x,x2,y,y2);
        }
        String s = sb.toString();
        //将验证码存入session
        request.getSession().setAttribute("checkCode_session",s);

        //3.将图片输出到页面展示
        ImageIO.write(image,"jpg",response.getOutputStream());
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
    <script>
        window.onload=function () {
            document.getElementById("img").onclick=function () {
                this.src="/day0_war_exploded/CheckCode?time="+new Date().getTime();
            }
        }
    </script>
</head>
<body>
    <form action="/day0_war_exploded/loginServlet" method="post">
        <table>
            <tr>
                <td>用户名</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>密码</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td>验证码</td>
                <td><input type="text" name="checkCode"></td>
            </tr>
            <tr>
                <td colspan="2"><img id="img" src="/day0_war_exploded/CheckCode"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="登录"></td>
            </tr>
        </table>
    </form>
	<div>
    	<%=request.getAttribute("error")==null?"": request.getAttribute("error")%>
	</div>
	<div>
   	 	<%=request.getAttribute("cc_error")==null?"": request.getAttribute("cc_error")%>
	</div>
</body>
</html>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
    <h1><%= request.getSession().getAttribute("user")  %>,欢迎您</h1>
</body>
</html>

13.JSP

  • 概念:Java Servlet Pages:Java服务器端页面
      可以理解为一个特殊的页面,其中既可以直接定义html标签也可以直接写Java代码
      用于简化书写
  • 原理
      本质上就是一个Servlet
  • JSP的脚本:JSP定义Java代码的方式
      1.<% 代码 %>:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么
      2.<%! 代码 %>:定义的Java代码,在JSP转换后的Java类的成员位置
      3.<%= 代码 %>:定义的Java代码,会输出到页面上。输出语句可以定义什么,该脚本就可以定义什么
  • 指令
      作用:用于配置JSP页面,导入资源文件
      格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2....%>
      分类:
        1.page:配置JSP页面的
          contentType:等同于response.setContentType()
            1.设置响应体的mime类型的字符集
            2.设置当前JSP页面的编码(只能是高级的IDE才能生效,低级工具需设定pageEncoding属性设置)
          import:导包
          errorPage:当前页面发生错误后会自动跳转到指定的错误页面
          isErrorPage:标识当前页面是否是错误页面
            true:是,可以使用内置对象exception
            false:否,默认值,不可以使用内置对象exception
        2.include:页面包含的。导入页面的资源文件
          <%@include file=""%>
        3.taglib:导入资源
          <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core%>
            prefix:前缀,自定义的
  • 注释
      1.html注释<!-- -->:只能注释html片段
      2.jsp注释:推荐使用
        <%-- --%>:可以注释所有
  • JSP内置对象
      在jsp页面中不需要获取和创建,可以直接使用的对象
      JSP一共有9个内置对象
变量名真实对象作用
pageContextPageContext当前页面共享数据,还可以获取其他八个内置对象
requestHttpServletRequest一次请求访问的的多个资源(转发)共享数据
sessionHttpSession一次会话的多个请求间共享数据
applicationServletContext所有用户间共享数据
responseHttpServletResponse响应对象
pageObject当前页面(Servlet)的对象 this
outJspWriter输出对象,数据输出到页面上
configServletConfigServlet的配置对象
exceptionThrowable异常对象

out和response.getWriter()区别:
在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
response.getWriter()数据永远在out.write()之前。

14.MVC:开发模式

  • JSP演变:
      1.早期只有servlet,只能使用response输出标签数据,非常麻烦
      2.后来有了JSP,简化了servlet的开发,如果过度使用JSP,在JSP中写大量Java和html造成难于维护及分工协作问题
      3.再后来,Java的web开发借鉴MVC开发模式,使得程序的设计更加合理
  • MVC:
      1.M:Model,模型,JavaBean
        完成具体的业务操作,如查询数据库,封装对象
      2.V:View,视图,JSP
        展示数据
      3.C:Controller,控制器,Servlet
        获取用户的输入,调用模型,将数据交给视图来展示
      优缺点:
        1.优点:耦合性低,方便维护,可以利于分工协作,重用性高
        2.缺点:使得项目架构变得复杂,对开发人员要求高

15.EL表达式

  • 概念:Expression Language 表达式语言
  • 作用:替换和简化jsp页面中Java代码的编写
  • 语法:${表达式}
  • 注意:
      JSP默认支持EL表达式
        如果要忽略EL表达式
          1.设置JSP中page指令中的属性isELIgnored="true",忽略当前页面中所有的EL表达式
          2.\${}:忽略当前这个EL表达式
  • 使用:
      1.运算
        运算符:
          1.算术运算符:±*/(div) %(mod)
          2.比较运算发:><>=<= == !=
          3.逻辑运算符:&&(and) ||(or) !(not)
          4.空运算符:empty
            用于判断字符串、集合、数组对象是否为null或者长度是否为0,${empty list} ${not empty list}
      2.获取值
        1.EL表达式只能从域对象获取值
        2.语法:
          1.${域名称。键名}:从指定域中获取键的值
            域名称:
              1. pageScope --> pageContext
              2.requestScope --> request
              3.sessionScope --> session
              4.applicationScope --> application(Servlet)
          举例:在request域中存储了name=张三 获取:${requestScope.name}
          2.${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
          3.获取对象、List集合、Map集合的值
            1.对象:${域名称.键名.属性名}
              本质上会去调用对象的getter方法
            2.List集合:${域名称.键名[索引]}
            3.Map集合:${域名称.键名.key名称} ${域名称.键名["key名称"]}
      3.隐式对象:
        EL表达式有11个隐式表达式
          pageContext:获取jsp其他八个内置对象
            ${pageContext.request.contentPath}:动态获取虚拟目录

16.JSTL

  • 概念:JavaServer Pages Tag Library JSP标准标签库
      是由Apache组织提供的开源的免费的jsp标签
  • 作用:用于简化和替换jsp页面上的Java代码
  • 使用步骤:
      1.导入jstl相关jar包
      2.引入标签库:taglib指令:<%@ %>
      3.使用标签
  • 常用的JSTL标签
      1.if:相当于Java的if语句
        1.属性:
          test:必须属性,接受Boolean表达式
            如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
            一般情况下,test属性会和el表达式一起使用
        2.注意:c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
      2.choose:相当于Java的switch语句,when相当于case,other相当于default
      3.foreach:相当于Java的for语句
        1.完成重复操作
          属性:
            begin:开始值
            end:结束值
            var:临时变量
            step:步长
            varStatus:循环状态对象
              index:容器中元素的索引,从0开始
              count:循环次数,从1开始
        2.遍历容器
          属性:
            items:容器对象
            var:容器中元素的临时变量
              varStatus:循环状态对象
                index:容器中元素的索引,从0开始
                count:循环次数,从1开始
        2.遍历容器

17.三层架构:软件设计架构

  1. 界面层(表示层/web层):用户看到的界面。用户可以通过界面上的组件和服务器进行交互
  2. 业务逻辑层(service层):处理业务逻辑的。
  3. 数据访问层(dao层)

18.Filter:过滤器

  • 作用:一般用于完成通过的操作。如:登录验证、统一编码处理、敏感字符的过滤…
  • 步骤:
      1.定义一个类,实现接口Filter
      2.复写方法
        1.web.xml
        2.注解
  • 过滤器执行流程
      1.执行过滤器
      2.执行放行后的资源
      3.回来执行放行代码下的代码
  • 生命周期
@WebFilter("/*")
public class Filterdemo2 implements Filter {
    /**
     * 在服务器启动后,会创建Filter对象,然后调用init方法,执行一次,用于加载资源
     * @param config
     * @throws ServletException
     */
    public void init(FilterConfig config) throws ServletException {

    }

    /**
     * 每一次被请求拦截资源时,会执行,执行多次
     * @param req
     * @param resp
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        chain.doFilter(req, resp);
    }

    /**
     * 在服务器关闭后被销毁,如果服务器是正常启动,则会执行destroy方法,执行一次,用于释放资源
     */
    public void destroy() {
    }

}

  • 过滤器配置详解
      拦截路径详解:
        1.具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
        2.拦截目录:/uesr/* 访问user下的所有资源时,过滤器都会被执行
        3.后缀名拦截:.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
        4.拦截所有资源:/
    访问所有资源时,过滤器都会被执行
      拦截方式配置:资源被访问的方式
        注解配置
          设置dispatcherTypes属性
            1.REQUEST:浏览器直接请求资源,默认值
            2.FORWARD:转发访问资源
            3.INCLUDE:包含访问资源
            4.ERROR:错误跳转资源
            5.ASYNC:异步访问资源
        web.xml配置
          设置<dispatcher>< /dispatcher>标签即可
  • 过滤器链(配置多个过滤器)
      执行顺序:如果有两个过滤器:过滤器1和过滤器2
        1.过滤器1
        2.过滤器2
        3.资源执行
        4.过滤器2
        5.过滤器1
      过滤器先后顺序问题:
        1.注解配置:按照类名的字符串比较规则比较,值小的先执行
          如:AFilter和BFilter ,A就先执行了
        2.web.xml配置:<filter-mapping>谁先定义谁先执行
  • 登录验证案例
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //0.强制转换
        HttpServletRequest request=(HttpServletRequest)req;
        //1.获取资源请求路径
        String uri = request.getRequestURI();
        //2.判断是否包含登录相关资源,要注意排除掉css/js/图片等资源
        if(uri.contains("login.jsp")||uri.contains("/loginServlet")||uri.contains("/css/")||uri.contains("/js/")||uri.contains("/fonts/")||uri.contains("/checkCodeServlet")){
             //包含,用户想登录,放行
            chain.doFilter(req,resp);
        }else{
            //不包含,验证用户是否登录
            //从session中获取user
            Object user = request.getSession().getAttribute("user");
            if(user!=null){
                //已经登录,放行
                chain.doFilter(req,resp);
            }else{
                //没有登录,跳转登录界面
                request.setAttribute("login_msg","您尚未登录,请先登录");
                request.getRequestDispatcher("/login.jsp").forward(request,resp);
            }
        }
    }
  • 敏感词汇过滤
      设计模式:一些通用的解决固定问题的方式
        1.装饰模式
        2.代理模式
          概念:
            1.真实对象:被代理的对象
            2.代理对象:
            3.代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
          实现方式:
            1.静态代理:有一个类文件描述代理模式
            2.动态代理:在内存中形成代理类
              实现步骤
                1.代理对象和真实对象实现相同的接口
                2.代理对象=Proxy.newInstance();
                3.使用代理对象调用方法
                4.增强方法
              增强方式:
                1.增强参数列表
                2.增强返回值类型
                3.增强方法体执行逻辑
lenov l=new lenov();
        //动态代理增强l对象
        /*
            三个参数:
                1.类加载器:真实对象l.getClass().getClassLoader()
                2.接口数组:真实对象l.getClass().getInterfaces()
                3.处理器:new InvocationHandler()
         */
        Lenovo proxy_l = (Lenovo)Proxy.newProxyInstance(l.getClass().getClassLoader(), l.getClass().getInterfaces(), new InvocationHandler() {
            /*
                代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
                    参数:
                        1.proxy:代理对象
                        2.method:代理对象调用的方法,被封装为的对象
                        3.args:代理对象调用的方法时,传递的实际参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //判断是否是sale方法
                if(method.getName().equals("sale")){
                    //增强参数
                    double money=(double)args[0];
                    money=money*0.85;
                    //使用真实对象调用该方法
                    String obj = (String) method.invoke(l, money);
                    //增强返回值
                    return obj+"鼠标垫";
                }else {
                    Object obj = method.invoke(l, args);
                    return obj;
                }
            }
        });
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 敏感词汇过滤
 */
@WebFilter("/*")
public class sensitiveFilter implements Filter {
    private List<String> list=new ArrayList<String>();//敏感词汇List集合
    public void init(FilterConfig config) throws ServletException {
        try {
            //获取文件真实路径
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("/WEF-INF/classes/words.txt");
            //读取文件
            BufferedReader br= new BufferedReader(new FileReader(realPath));
            //将文件的每一行都添加到List
            String line=null;
            while ((line=br.readLine())!=null){
                list.add(line);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

   public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //1.创建代理对象,增强getParameter方法
       ServletRequest proxy_req =(ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //增强getParameter方法
                //判断是否是getParameter方法
                if(method.getName().equals("getParameter")){
                    //增强返回值
                    //获取返回值
                    String value=(String) method.invoke(req,resp);
                    if(value!=null){
                        for (String s : list) {
                            if(value.contains(s)){
                                value=value.replaceAll(s,"***");
                            }
                        }
                    }
                    return value;
                }
                //判断是否是getParameterMap方法
                //判断是否是getParameterValue方法
                return method.invoke(req,resp);
            }
        });
        //2.放行
        chain.doFilter(proxy_req, resp);
    }

    public void destroy() {

    }

}

19.Listener:监听器

  • 概念:web的三大组件之一
      事件监听机制
        事件:一件事情
        事件源:事件发生的地方
        监听器:一个对象
        注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码
  • ServletContextListener:监听ServletContextListener对象的创建和销毁
      方法
        void contextDestroyed(ServletContextEvent sce):
          ServletContextListener对象被销毁之前会调用该方法后会调用该方法
        void contextInitialized(ServletContextEvent sce):
          ServletContextListener对象创建后调用该方法
      步骤
        1.定义一个类,实现ServletContextListener接口
        2.复写方法
        3.配置
          1.web.xml
          2.注解

20.JQuery

  • 概念:一个JavaScript的框架,简化JS开发
      JavaScript框架:本质上就是一些js文件,封装了js的原生代码
  • JQuery对象和JS对象区别和转换
      1.JQuery对象在操作时,更加方便
      2.JQuery对象在js对象方法不通用
      3.两者转换
        jq–>:jq对象[索引] 或者 jq对象.get(索引)
        js–>:$(js对象)
  • 选择器:筛选具有相似特征的元素
      1.基本语法学习:
        1.事件绑定 $("#b1").click(function () { });
        2.入口函数 $(function () { });可以定义多次,onload只能一次
        3.样式控制
    选择器
  • DOM操作
      1.内容操作
        1.html():获取/设置元素的标签体内容
        2.text():获取/设置元素的标签体纯文本内容
        3.val():获取/设置元素的value属性值
      2.属性操作
        1.通用属性操作
          1.attr():获取/设置元素的属性
          2.removeAttr():删除属性
          3.prop():获取/设置元素的属性
          4.removeProp():删除属性
         attr和prop区别:
          1.如果操作的是元素的固有属性,则建议使用prop
          2.如果操作自定义元素建议用attr
        2.对class属性操作
          1.addClass():添加class属性
          2.removeClass():删除class属性
          3.toggleClass():切换class属性,有就add没有就remove
          4.css():
      3.CRUD操作 操作
  • 动画
    。。。

AJAX

  • 概念:Asynchronous JavaScript And XML 异步的JavaScript和XML
  • 实现方法
      1.原生js方式
      2.JQuery实现方式
        1.$.ajax
        2.$.get
        3.$.post

JSON

  • 概念:JavaScript Object Notation JavaScript对象表示法
      JSON 是存储和交换文本信息的语法。类似 XML。JSON 比 XML 更小、更快,更易解析。
  • 语法:
      基本规则:
      获取数据:

Redis

  • 概念:是一款高性能的NOSQL系列的非关系型数据库
    一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据

Jedis

  • 一款Java操作redis数据库的工具
  • 使用步骤
      1.下载jar包
      2.使用

Maven

  • 标准目录结构
    src/main/java 核心代码部分
    src/main/resources 配置文件部分
    src/test/java 测试代码部分
    src/test/resources 测试配置文件
    src/main/webapp 页面资源,js、css、图片等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值