Java Web

目录

1、HTML

1.1idea创建HTML文件

1.2HTML文件的书写规范

1.3HTML标签介绍

1.4常用标签介绍

1.5其它标签

2、CSS技术

2.1CSS和HTML的结合方式

2.2CSS选择器

2.2.1标签名选择器

2.2.2id选择器

2.2.3class选择器

2.2.4组合选择器

3、JavaScript

3.1JavaScript介绍

3.2JavaScript和html代码的结合方式

3.3变量

3.4关系(比较)运算

3.5逻辑运算

3.5数组

3.6函数

3.6.1函数的两种定义方式

3.6.2函数的arguments隐形参数(只在function函数内)

3.7JS中自定义对象

3.8JS中的事件

3.9DOM模型

3.9.1Document对象

3.9.2Document对象中的方法介绍

3.9.3正则表达式

3.9.4节点的常用属性和方法

4、JQuery

4.1JQuery介绍

4.2jQuery核心函数

4.3jQuery对象和dom对象区分

4.4jQuery选择器

4.5jQuery的属性操作

4.6DOM的增删改

4.7CSS样式操作

4.8jQuery样式

4.9jQuery事件操作

5、XML

5.1XML简介

5.2文档声明

5.3元素(标签)

什么是 XML 元素?

XML 命名规则

XML 属性

5.4xml语法规则

5.5Dom4j解析技术

6、Tomcat

6.1JavaWeb的概念

6.2Web资源的分类

6.3常用的Web服务器

6.4Tomcat服务器和Servlet版本的对应关系

6.5Tomcat的使用

6.6IDEA整合Tomcat服务器

6.7IDEA中动态web工程的操作

7、Servlet

7.1Servlet技术

72.ServletConfig类

7.3ServletContext类

7.4HTTP 协议

7.5.HttpServletRequest 类

7.6HttpServletResponse 类

8、书城第二阶段-用户注册和登录

8.1JavaEE项目的三层架构

8.2先创建书城需要的数据库和表。

8.3编写数据库表对应的 JavaBean 对象。

8.4编写工具类 JdbcUtils

8.5编写 BaseDao

8.6编写 UserDao 和测试

8.7编写 UserService 和测试

8.8编写 web 层

8.8.1实现用户注册的功能

8.8.2IDEA 中 Debug 调试的使用

8.9用户登录功能的实现

9、jsp

9.1jsp概述

9.2jsp 的三种语法

9.3jsp 九大内置对象

9.4jsp 四大域对象

9.5jsp 中的 out 输出和 response.getWriter 输出的区别

9.6jsp 的常用标签

9.7jsp 的练习题

9.8 Listener 监听器

10、EL表达式&JSTL标签库

10.1EL表达式

10.2JSTL 标签库(次重点****)

11、文件的上传和下载

11.1文件的上传介绍(*****重点)

11.2文件上传,HTTP 协议的说明。

11.3commons-fileupload.jar 常用 API 介绍说明

11.4fileupload 类库的使用:

11.5文件下载

12、Cookie和Session

12.1Cookie

12.2Session 会话

13、JSON、AJAX、i18n

13.1Json

13.2AJAX 请求

13.3i18n 国际化(了解内容)


1、HTML

1.1idea创建HTML文件

  1. 创建一个web工程(静态的web工程):file-->new-->project-->static web-->next-->设置project name和project location-->finish
  2. 在工程下创建html页面:点击工程名右键-->new-->HTML File-->设置html文件名-->Enter
  3. 运行:右键-->run ;或者选择右上角的一个浏览器运行

1.2HTML文件的书写规范

<!DOCTYPE html><!-- 约束,声明-->
<html lang="en"> <!-- html标签,表示html的开始,lang="en"表示英文,html标签中一般分为两部分:head和body-->
<head> <!--表示头部信息,一般包含三部分内容,title标题,css样式,js代码 -->
    <meta charset="UTF-8"><!--表示当前页面使用utf-8字符集 -->
    <title>标题</title><!-- 表示标题-->
</head>
<body><!-- body标签是整个html页面的主体内容-->
hello
</body>
</html><!-- 整个html页面的结束-->

html的代码注释:<!-- 这是html注释   -->

1.3HTML标签介绍

1.标签的样式:<标签名>封装的数据</标签名>

2.标签名大小写不敏感

3.标签拥有自己的属性

  • 基本属性:bgcolor="red"      可以修改简单的样式效果
  • 事件属性:οnclick="alert('你好!');"

4.标签又分为单标签和双标签

单标签格式:<标签名/>   <br/>换行  <hr/>水平线

双标签格式:<标签名>...封装的数据...</标签名>

标签的语法:

<!--标签不能交叉嵌套-->

<!--标签必须正确关闭-->

<!--属性必须有值,属性值必须加引号-->

<!-- 注释不能嵌套-->

1.4常用标签介绍

可参照文档:W3cschool.CHM学习使用

字体和特殊符号:
<font color="red" face="宋体" size="7">我是字体标签</font><!--设置字体的样式size的最大值为7 -->
我是&lt;br&gt;标签<!--输出我是<br>标签字样-->
我是&nbsp;&nbsp;&nbsp;空格

HTML 中有用的字符实体:

标题:
<h1 align="center">标题1</h1><!--设置对齐属性-->
<h6 align="left">标题6</h6><!--h1到h6都是标题标签,h1最大,h6最小-->

超链接:

<a href="http://www.baidu.com">百度</a><br/><!--a标签是超链接,href属性设置连接的地址,target属性设置那个目标进行跳转,默认是当前页面跳转 -->
<a href="http://www.baidu.com" target="_self">百度_self</a><br/><!--_self表示当前页面-->
<a href="http://www.baidu.com" target="_blank">百度_blank</a><!--_blank表示打开新页面来进行跳转-->

列表标签:

<ul type="none">         <!-- ul是无序列表,type属性可以修改列表项前面的符号-->
    <li>赵四</li>        <!--li是列表项 -->
    <li>刘能</li>
</ul>
<ol type="I">            <!-- ol是有序列表,type属性可以修改列表项前面的符号-->
    <li>小沈阳</li>
    <li>宋小宝</li>
</ol>

img标签:

<img src="../imgs/1.jpg" width="100" height="120" border="1" alt="图片找不到"><!-- 设置图片标签的路径、宽、高、边框和图片找不到时的显示内容-->

路径问题:

在javase中路径分为相对路径和绝对路径:
相对路径:从工程名开始算 
绝对路径:盘符:/目录/文件名

在web中路径分为相对路径和绝对路径:
相对路径:
. 当前文件所在的目录
.. 当前文件所在的上一级目录
文件名   表示当前文件所在目录的文件,相当于./文件名
绝对路径:
正确格式是:http://ip:port/工程名/资源路径
错误格式:盘符:/目录/文件名

表格标签:

<table align="center" cellspacing="0" border="1" width="300" height="300">
    <tr>
        <td align="center"><b>1.1</b></td>
        <th>1.2</th>
    </tr>
    <tr>
        <td>2.2</td>
        <td>2.2</td>
    </tr>
</table>
<!-- table:表格标签,tr:行标签,td:单元格标签,th:表头标签(默认标签中的文字加粗居中)-->
rowspan="2" 设置跨两行 colspan="2"设置跨两列

iframe标签:

<iframe src="hello.html" width="500" height="400"></iframe>
<!--iframe标签可以在页面上开辟一个小区域显示一个单独的页面 -->

iframe标签和a标签组合使用:

<iframe src="hello.html" width="500" height="400" name="abc"></iframe>
<a href="hello.html" target="abc">hello.html页面</a>
<!--点击超链接时,在iframe的小窗口中显示href中的指定内容-->

表单标签:

表单标签就是html页面中,用来收集用户信息的所有元素集合,然后把这些信息发送给服务器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单的显示</title>
</head>
<body>
<form>
    用户名称:<input type="text" value="默认值"/><br/>
    用户密码:    <input type="password" maxlength="13"/><br/>
    确认密码:<input type="password"/><br/>
    性别:    <input type="radio" name="sex" checked="checked"/>男<input type="radio" name="sex"/>女<br/>
    <!-- 设置name属性对其进行分组,确保只能选其中一个,checked="checked"表示默认选中-->
    兴趣爱好:<input type="checkbox" checked="checked"/>java<input type="checkbox"/>javaScript<input type="checkbox"/>c++<br/>
    国籍:<select>
    <option>--请选择国籍--</option>
    <option selected="selected">中国</option> <!--设置下拉列表的默认选中 -->
    <option>美国</option>
    <option>日本</option>
         </select><br/>
    自我评价:<textarea rows="10" cols="20">我是默认值</textarea><br/>
    <!--设置文本域10行,每行可以显示20个字符宽度,起始标签和结束标签中的内容是默认值 -->
    <input type="reset" value="修改"><br/>
    <!--value属性设置重置按钮上的字样,不设置时默认是”修改“字样 -->
    <input type="submit">
    <input type="button" value="abc">
    <input type="file"><!--文件上传域 -->
    <input type="hidden">

</form>
</body>
</html>

 

表单和表格搭配使用:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单的显示</title>
</head>
<body>
<!--action设置提交的服务器地址,method设置提交的方式GET(默认值)或post -->
<form action="http://www.baidu.com" method="get">
    <h1 align="center">用户注册</h1>
    <table align="center">
        <tr>
            <td>用户名称:</td>
            <td><input type="text" name="username" value="默认值"/></td>
        </tr>
        <tr>
            <td>用户密码:</td>
            <td><input type="text" name="password" value="默认值"/></td>
        </tr>
        <tr>
            <td>确认密码:</td>
            <td><input name="repassword" type="password"/><br/></td>
        </tr>
        <tr>
            <td>性别: </td>
            <td>
                <input type="radio" name="sex" value="boy" checked="checked"/>男
                <input type="radio"value="girl" name="sex"/>女
            </td>
        </tr>
        <tr>
            <td>兴趣爱好:</td>
            <td>
                <input type="checkbox" name="hobby" value="java" checked="checked"/>java
                <input type="checkbox" name="hobby" value="javaScript"/>javaScript
                <input type="checkbox" name="hobby" value="c++"/>c++
            </td>
        </tr>
        <tr>
            <td>国籍:</td>
            <td>
                <select name="country">
                    <option value="none">--请选择国籍--</option>
                    <option selected="selected" value="china">中国</option> <!--设置下拉列表的默认选中 -->
                    <option value="amarican">美国</option>
                    <option value="jarepean">日本</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>自我评价:</td>
            <td><textarea name="desc" rows="10" cols="20">我是默认值</textarea></td>
        </tr>
        <tr>
            <td><input type="reset" value="修改"></td>
            <td align="center"><input type="submit"></td>
        </tr>
    </table>

</form>
</body>
</html>

表单提交的时候,数据没有发送给服务器的三种情况:

  • 表单项没有name属性值
  • 单选、复选(下拉列表中的option标签)都需要添加value属性,以便发送给服务器
  • 表单项不在提交的form标签中

GET请求的特点是:

1、浏览器地址栏中的地址是:action 属性[+?+请求参数]

请求参数的格式是:name=value&name=value

2、不安全

3、它有数据长度的限制

POST请求的特点:

1、浏览器地址栏中只有action属性值

2、相对于GET请求要安全

3、理论上没有数据长度的限制

1.5其它标签

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>其它标签</title>
</head>
<body>
<!--
div标签    默认独占一行
span标签   它的长度是封装数据的长度
p段落标签   默认会在段落的上方或下方空出一行(如果已有就不再空)
-->
<div>div标签1</div>
<div>div标签2</div>
<span>span标签1</span>
<span>span标签2</span>
<p>段落标签1</p>
<p>段落标签2</p>
</body>
</html>

2、CSS技术

可以参照文档:CSS2.0.chm学习使用

css是层叠样式表单。是用于(增强)控制网页样式并允许将样式信息与网页内容分离的一种标志性语言。

2.1CSS和HTML的结合方式

第一种:在标签的style属性上设置,修改标签样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div style="border: 1px solid red;width: 100px;background-color: antiquewhite">div标签1</div>
    <div>div标签2</div>
    <span>span标签1</span>
    <span>span标签2</span>
</body>
</html>

这种方法的缺点:

  1. 如果标签多了,样式多了,代码量非常庞大
  2. 可读性非常差
  3. css代码没什么复用性可言

第二种:在head标签中,使用style标签来定义各种自己需要的css样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- style标签专门用来定义css样式代码-->
    <style type="text/css">
        /*这是css注释*/
        div{
            border: 1px solid red;
        }
        span{
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <div>div标签1</div>
    <div>div标签2</div>
    <span>span标签1</span>
    <span>span标签2</span>
</body>
</html>
  • css注释:/*这是css的注释*/

这种方式的缺点:

  1. 只能在同一页面内复用代码,不能在多个页面中复用css代码
  2. 维护起来不方便,实际的项目中会有成千上万的页面,要到每个页面中去修改,工作量太大了

第三种:使用html的<link rel="stylesheet" type="text/css" href="./style.css"/>标签导入css样式文件(把css样式写成一个单独的css文件,再通过link标签引入即可复用)

/*css样式代码*/
div{
    border: 1px solid red;
}
span{
    border: 1px solid red;
}



<!--html代码:-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- link标签专门用来引入css样式代码-->
    <link rel="stylesheet" type="text/css" href="1.css"/>
</head>
<body>
<div>div标签1</div>
<div>div标签2</div>
<span>span标签1</span>
<span>span标签2</span>
</body>
</html>

2.2CSS选择器

2.2.1标签名选择器

标签名选择器格式:标签名{ 属性:值;}

标签名选择器可以决定哪些标签被动的使用这个样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- style标签专门用来定义css样式代码-->
    <style type="text/css">
        /*这是css注释*/
        div{
            border: 1px solid yellow;
            color:blue;
            font-size: 30px;
        }
        span{
            border: 5px dashed blue; /*边框设置*/
            color: yellow; /*字体颜色*/
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div>div标签1</div>
    <div>div标签2</div>
    <span>span标签1</span>
    <span>span标签2</span>
</body>
</html>

2.2.2id选择器

id选择器的格式:#id属性值{属性:值;}

id选择器可以让我们通过id属性选择性的使用这个样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>id选择器</title>
    <style type="text/css">
       #id001{
           color: blue;
           font-size: 30px;
           border: 1px solid yellow;/*边框实线*/
       }
        #id002{
            color: red;
            font-size: 20px;
            border: 5px dotted blue;/*点线式边框*/
        }
    </style>
</head>
<body>
<div id="id001">div标签1</div>
<div id="id002">div标签1</div>
</body>
</html>

2.2.3class选择器

class选择器格式:.class属性值{属性:值;}

class类型选择器,可以通过class属性有效的选择性的去使用这个样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>class选择器</title>
    <style type="text/css">
        .class01{
            color: blue;
            font-size: 30px;
            border: 1px solid yellow;
        }
        .class02{
            color: gray;
            font-size: 26px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <div class="class01" >div标签1</div>
    <div class="class02">div标签2</div>
    <span class="class01">span标签1</span>
    <span>span标签2</span>
</body>
</html>

2.2.4组合选择器

组合选择器的格式:选择器1,选择器2,选择器n{属性:值;}

组合选择器可以让多个选择器共用同一个css样式代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组合选择器</title>
    <style type="text/css">
        .class01,#id01{
            color: blue;
            font-size: 20px;
            border: 1px yellow solid;
            background-color: wheat;
            width: 100px;
            height: 100px;
            text-align: center;/*文本居中*/
            margin-left: auto;/*标签居中*/
            margin-right: auto;/*标签居中*/
        }
        a{text-decoration: none}
    </style>
</head>
<body>
<div class="class01">div标签</div>
<span id="id01">span标签</span>
<div>div标签</div>
<div>div标签</div>
<a href="http://www.baidu.con">百度</a>
</body>
</html>

3、JavaScript

3.1JavaScript介绍

JavaScript语言诞生主要是完成页面的数据验证。因此它运行在客户端,需要运行浏览器来解析执行JavaScript代码。JS是弱类型,JAVA是强类型。

特点:

  1. 交互性(它可以做的就是信息的动态交换)
  2. 安全性(不允许直接访问本地硬盘)
  3. 跨平台性(只要是可以解析JS的浏览器都可以执行,和平台无关)

3.2JavaScript和html代码的结合方式

第一种方式:只需要在head标签中,或者在body标签中,使用script标签来书写javascrip代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
        //alert是JavaScript语言提供的一个警告框函数
        //它可以接收任意类型的参数,这个参数就是警告框的提示信息
        alert("hello javascript")
    </script>
</head>
<body>

</body>
</html>

第二种方式:使用script标签引入单独的javascript代码文件

1.js代码文件:

alert("hello 哟哟");

html代码文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 现在需要使用script引入外部的js文件来执行-->
    <!--src属性专门用来引入js文件路径(可以是相对路径,也可以是绝对路径) -->
    <!-- script标签可以用来定义js代码,也可以用来引入js文件,
    但是一个script标签中两个功能二选一使用,不能同时使用两个功能-->
    <script type="text/javascript" src="1.js"></script>
    <script>
        alert("what are you dong?")//这样写是可以的
    </script>
</head>
<body>

</body>
</html>

3.3变量

什么是变量?变量是可以存放某些值的内存的命名

JavaScript的变量类型;

数值类型:number

字符串类型:String

对象类型:object

布尔类型:boolean

函数类型:function

JavaScript里特殊的值:

undefined:未定义,所有js变量未赋予初始值的时候,默认值都是undefined

null:空值

NAN:全称是Not a Number,非数字,非数值。

js中定义变量格式:

var 变量名;

var 变量名=值;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>变量</title>
    <script type="text/javascript">
        var i;//undefined
        alert(i);
        i=12;//number
        alert(typeof (i));//typeof是javascript语言提供的一个函数,它可以取变量的数据类型反回
        i="abc";//string
        alert(typeof (i));
        var a=12;
        var b="abc";
        alert(a*b);//NaN,非数值,非数值
    </script>
</head>
<body>

</body>
</html>

3.4关系(比较)运算

javascript中的关系运算符除了java中有的,还有一些特别的

  • 等于:==(是简单的做字面值的比较)
  • 全等于:===(除了做字面值的比较之外,还会比较两个变量的数据类型
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关系运算</title>
    <script type="text/javascript">
        var a="12";
        var b=12;
        alert(a==b);//true
        alert(a===b);//false
    </script>
</head>
<body>

</body>
</html>

3.5逻辑运算

且运算:&&     或运算:||     取反运算:!

  • 在javascript语言中,所有的变量,都可以作为一个boolean类型的变量去使用,0、null、undefined、""(空串)都认为是false

&&且运算:

第一种情况:当表达式全为真时,反回最后一个表达式的值

第二种情况:当表达式中,有一个为假的时候,反回第一个为假的表达式的值

||或运算:

第一种情况:当表达式全为假时,反回最后一个表达式的值

第二种情况:只要有一个表达式为真,就会反回第一个为真的表达式的值

3.5数组

JS中数组的定义格式;

var 数组名=[];//空数组

var 数组名=[1,"abc",true];//定义数组同时赋予元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数组</title>
    <script type="text/javascript">
        var arr=[];//定义一个空数组
        alert(arr.length);//数组长度0
        arr[0]=12;
        alert(arr.length);//数组长度1
        //javascript语言中的数组,只要我们通过数组下标赋值,那么最大的下标值,就会自动的给数组做扩容操作
        arr[2]="abc";
        alert(arr.length);//数组长度3
        alert(arr[1]); //undefined
        //数组的遍历
        for (var i=0;i<arr.length;i++){
            alert(arr[i]);
        }
    </script>
</head>
<body>

</body>
</html>

3.6函数

3.6.1函数的两种定义方式

第一种:可以通过function关键字来定义函数

格式如下:

function 函数名(形参列表){

函数体

}

在javascript语言中,如何定义带有返回值的函数?只要在函数体内直接使用return语句反回值即可

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数</title>
    <script type="text/javascript">
        //无参函数
        function fun() {
            alert("无参函数被调用了!")
        }
        fun();//函数调用

        //带参函数
        function fun2(a,b) {
            alert("有参函数fun2被调用了a="+a+",b="+b)
        }
        fun2(12,"abc")

        //带返回值的函数
        function sum(num1,num2) {
            return num1+num2;
        }
        alert(sum(12,"abc"));
    </script>
</head>
<body>

</body>
</html>

函数的第二种定义方式,格式如下:

var 函数名=function(形参列表){函数体}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>函数</title>
    <script type="text/javascript">
        var  fun=function () {
            alert("无参函数");
        }
        fun();
        var fun2=function (a,b) {
            alert("有参函数a="+a+",b="+b)
        }
        fun2(19,"jjjkkk");
        var fun3=function (a,b) {
            return a+b;
        }
        alert(fun3(12,3));
    </script>
</head>
<body>

</body>
</html>

注:在JAVA中函数允许重载。但在JS中函数的重载会直接覆盖掉上一次的定义

3.6.2函数的arguments隐形参数(只在function函数内)

就是在function函数中不需要定义,但却可以直接用来获取所有参数的变量,我们管它叫隐形参数。

隐形参数特别像java基础的可变长参数一样,public void fun(object...args);相当于一个数组

那么js中的隐形参数也跟java的可变长参数一样,操作类似数组

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>隐形参数</title>
    <script type="text/javascript">
        function fun() {
            alert(arguments.length);//传入的参数个数
            alert(arguments[0]);//1
            alert(arguments[1]);//ab
            alert(arguments[2]);//true

            for (var i=0;i<arguments.length;i++){
                alert(arguments[i]);
            }
            alert("无参函数");
        }
        fun(1,"ab",true);
    </script>
</head>
<body>

</body>
</html>

3.7JS中自定义对象

Object形式的自定义对象

对象的定义:

var 变量名=new Object();//对象实例(空对象)

变量名.属性名=值;    //定义一个属性

变量名.函数名=function(){}   //定义一个函数

对象的访问:

变量名.属性/函数名();

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>object形式自定义对象</title>
    <script type="text/javascript">
        var obj=new Object();
        obj.name="华仔";
        obj.age=18;
        obj.fun=function () {
            alert("姓名:"+this.name+",年龄"+this.age);
        }
        obj.fun();
        alert(obj.age);
    </script>
</head>
<body>

</body>
</html>

{]花括号形式的自定义对象

对象的定义:

var 变量名={

属性名:值,

属性名:值,

函数名:function(){}

};

对象的访问:

变量名.属性/函数名();

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>大括号形式的自定义对象</title>
    <script type="text/javascript">
        var obj={
            name:"胡歌",
            age:18,
            fun:function () {
                alert("姓名:"+this.name+",年龄:"+this.age);
            }
        };
        obj.fun();
        alert(obj.name);
        alert(obj.age);
    </script>
</head>
<body>

</body>
</html>

3.8JS中的事件

什么是事件?事件是电脑输入设备与页面进行交互的响应,我们称之为事件

常用的事件:

  • onload加载完成事件:页面加载完成之后,常用于页面JS代码初始化操作
  • onclick点击事件:常用于按钮的点击响应操作
  • onblur失去焦点事件:常用于输入框失去焦点后验证其输入内容是否合法
  • onchange内容发生改变事件:常用于下拉列表和输入框内容发生改变后操作
  • onsubmit表单提交事件:常用于表单提交前,验证所有表单项是否合法

事件的注册又分为静态注册和动态注册两种:

什么是事件的注册(绑定)?

其实就是告诉浏览器,当事件响应后要执行哪些操作代码,叫事件注册或事件绑定

静态注册事件:通过html的标签事件属性直接赋予事件响应后的代码,这种方式我们叫静态注册

动态注册事件:是指先通过js代码得到标签的dom对象,然后再通过dom对象.事件名=function(){}这种形式赋予事件响应后的代码,叫动态注册

动态注册基本步骤:1.获取标签对象 2.标签对象.事件名=function(){}

onload事件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onload事件</title>
    <script type="text/javascript">
        function onloadfun() {
            alert('静态注册onload事件');
        }

        //onload事件动态注册,是固定写法
        window.onload=function () {
            alert('动态注册onload事件');
        }
    </script>
</head>
<!--静态注册onload事件
onload事件是浏览器解析完页面之后就会自动触发的事件
<body onload="onloadfun()">
-->
<body>

</body>
</html>

onclick事件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onclick</title>
    <script type="text/javascript">
        function onclickfun() {
            alert("静态注册onclick事件")
        }

        //动态注册onclick事件
        window.onclick=function () {
            //1获取标签对象(document是javascript语言提供的一个对象【文档】)
           var btnobj= document.getElementById("btn01");
            //2通过标签对象.事件名=function(){}
            btnobj.onclick=function () {
                alert("动态注册的onclick事件");
            }
        }
    </script>
</head>
<body>
    <button onclick="onclickfun()">按钮1</button><!--静态注册onclick事件 -->
    <button id="btn01">按钮2</button>
</body>
</html>

onblur失去焦点事件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onblur</title>
    <script type="text/javascript">
        //静态注册失去焦点事件
        function onblurfun() {
            //console是控制台对象,是javascript语言提供专门用于向浏览器的控制台打印输出,用于测试使用
            //log是打印的方法
            console.log("静态注册失去焦点onblur事件");
        }
        //动态注册onblur事件
        window.onload=function () {
           var passwordobj= document.getElementById("onblur");
           passwordobj.onblur=function () {
                console.log("动态注册失去焦点onblur事件");
           }
        }
    </script>
</head>
<body>
    用户名:<input type="text" onblur="onblurfun()"/><br/>
    密码:<input type="password" id="onblur"/><br/>
</body>
</html>

onchange:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onchange</title>
    <script type="text/javascript">
        function onchangefun() {
            alert("女神已经改变了")
        }
        window.onload=function () {
           var selectobj= document.getElementById("se01");
           selectobj.onchange=function () {
                alert("男生已经发生改变");
           }
        }
    </script>
</head>
<body>
        请选择你心中的女神:
        <select onchange="onchangefun()"><!-- 静态注册onchange事件-->
            <option>芳芳</option>
            <option>佳佳</option>
            <option>环环</option>
            <option>圆圆</option>
        </select>

        请选择你心中的男神:
        <select id="se01"><!-- 动态注册onchange事件-->
            <option>国哥</option>
            <option>华仔</option>
            <option>富城</option>
            <option>余名</option>
        </select>
</body>
</html>

onsubmit表单提交事件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onsubmit</title>
    <script type="text/javascript">
        function onsubmitfun() {
            alert("静态注册表单提交事件。。。发现不合法");//要验证所有的表单项是否合法,如果有一个不合法就停止提交
            return false;
        }
        window.onload=function () {
           var formobj= document.getElementById("form");
           formobj.onsubmit=function () {
                alert("动态注册表单提交事件。。。发现不合法");
                return false;//改为return true或不写return语句时就会提交成功
           }
        }
    </script>
</head>
<body>           <!--onsubmit的值为"return false"时就会停止提交 -->
        <form action="http://localhost:8080" method="get" onsubmit="return onsubmitfun()">
            <input type="submit" value="静态注册"/>
        </form>
        <form action="http://localhost:8080" method="get" id="form">
            <input type="submit" value="动态注册"/>
        </form>
</body>
</html>

3.9DOM模型

DOM全称是Document Object  Model 文档对象模型

大白话,就是把文档中的标签,属性,文本,转化称为对象来管理。

那么,他们是如何实现把标签,属性,文本转化称为对象来管理的呢

3.9.1Document对象

Document对象的理解:

第一点:Document它管理了所有的html文档内容

第二点:document它是一种树结构的文档。有层级关系

第三点:它让我们把所有的标签都对象化

第四点:我们可以通过document访问所有的标签对象

3.9.2Document对象中的方法介绍

  • document.getElementById(elementId):通过标签的id属性查找标签dom对象,elementId是标签的id属性值
  • document.getElementByName(elementName):通过标签的name属性查找标签dom对象,elementName是标签的name属性值
  • document.getElementByTagName(tagname):通过标签名查找标签dom对象,tagname是标签名
  • document.creatElement(tagName):方法,通过给定的标签名,创建一个标签对象,tagname是要创建的标签

getElementById:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>getElementById</title>
    <script type="text/javascript">
        /*需求:当用户点击了校验按钮,要获取输出框的内容。然后验证其是否合法。
        验证的规则是:必须由字母、数字、下划线组成,并且长度是5到12*/
        function onclickfun() {
        var usernameobj=document.getElementById("username");//获取input标签对象
        var usernameText=usernameobj.value;//获取输入框的内容
            // 如何验证字符串是否符合某个规则,需要使用正则表达式技术
            var patt=/^\w{5,12}$/;
            //获取span标签对象
            var usernameSpanObj=document.getElementById("usernameSpan");
            //test()方法用于测试某个字符串,是不是匹配我的规则,匹配就反回true,不匹配就反回false
            if(patt.test(usernameText)){
                //usernameSpanObj.innerHTML="用户名合法";//innerHTML表示起始标签和结束标签里面的内容,可读、可写
                usernameSpanObj.innerHTML="<img src=\"imgs/right.jpg\" width=\"25\" height=\"25\">"
            }else {
                //usernameSpanObj.innerHTML="用户名不合法";
                usernameSpanObj.innerHTML="<img src=\"imgs/wrong.jpg\" width=\"25\" height=\"25\">"
            }
        }
    </script>
</head>
<body>
    用户名:<input type="text" id="username"  value=""/>
    <button onclick="onclickfun()">校验</button>
    <span id="usernameSpan" style="color: red"></span>

</body>
</html>

getElementsByName:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>getElementsByName</title>
    <script type="text/javascript">
        var hobbys=document.getElementsByName("hobby");
        function checkAll() {//全选
            //checked表示复选框的选中状态,如果选中是true,不选中是false,checked这个属性可读、可写
            for(var i=0;i<hobbys.length;i++){
                hobbys[i].checked=true;
            }
        }
        function checkNo() {//全不选
            for(var i=0;i<hobbys.length;i++){
                hobbys[i].checked=false;
            }
        }
        function checkReverse() {//反选
            for(var i=0;i<hobbys.length;i++){
                hobbys[i].checked=!hobbys[i].checked
            }
        }
    </script>
</head>
<body>
    兴趣爱好:
    <input type="checkbox" name="hobby" value="cpp"/>c++
    <input type="checkbox" name="hobby" value="java"/>java
    <input type="checkbox" name="hobby" value="js"/>javascript
    <br/>
    <button onclick="checkAll()">全选</button>
    <button onclick="checkNo()">全不选</button>
    <button onclick="checkReverse()">反选</button>
</body>
</html>

getElementsByTagName:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>getElementsByTagName</title>
    <script type="text/javascript">
       var inputsObj= document.getElementsByTagName("input");
       function checkAll() {
        for (var i=0;i<inputsObj.length;i++){
            inputsObj[i].checked=true;
        }
       }
    </script>
</head>
<body>
    兴趣爱好:
    <input type="checkbox"  value="cpp"/>c++
    <input type="checkbox"  value="java"/>java
    <input type="checkbox"  value="js"/>javascript
    <br/>
    <button onclick="checkAll()">全选</button>
</body>
</html>

creatElement:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>creatElement</title>
    <script type="text/javascript">
        //创建一个标签显示在页面上,标签里面的内容是:小舞,我爱你
        window.onload=function () {
            var divObj= document.createElement("div");//创建div空标签
            divObj.innerHTML="小舞,我爱你"//给标签添加内容
            document.body.appendChild(divObj);//document.boddy:直接获取boddy标签的对象,然后加入子节点div到boddy里面
        }
       </script>
</head>
<body>
</body>
</html>

注:

document对象的三个查询方法,如果有id属性,优先使用getElementById方法来进行查询

如果没有id属性,则优先使用getElementByName方法来进行查询

如果id属性和name属性都没有最后再按标签名查,getElementsByTagName

以上三个方法一定要在页面加载完成之后才能查询到标签对象

3.9.3正则表达式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
       // var patt=new RegExp("e");  //表示要求字符串中是否包含字母e
        //var patt=/e/;  //也是正则表达式对象
       // var patt=/[abc]/; //表示要求字符串中是否包含字母a或b或c
      // var patt=/[^abc]/;
       //var patt=/[a-z]/;//表示要求字符串,是否包含小写字母
       //var patt=/[A-Z]/;//表示要求字符串,是否包含大写字母
       //var patt=/[0-9]/; //表示要求字符串,是否包含数字
      // var patt=/\w/;//表示要求字符串,是否包含字母、数字、下划线
       //var patt=/a+/;//表示要求字符串中是否包含至少一个a
       //var patt=/a*/;//表示要求,字符串中是否包含零个或多个a
      // var patt=/a?/;//表示要求字符串是否包含零个或一个a
       //var patt=/a{3}/;//表示要求字符串是否包含连续三个a
       //var patt=/a{3,5}/;//表示要求字符串,是否包含至少三个连续的a,
       //var patt=/^a{3,5}$/;//表示要求字符串,从头到尾至少三个a,至多五个a
       var patt=/^\w{3,12}$/;//表示要求字符串由字母、数字、下划线组成,从头到尾包含3到12个
       //var patt=/a{3,}/; //表示要求字符串,是否包含至少三个连续的a
      // var patt=/a$/;//表示要求字符串必须以a结尾
       //var patt=/^a/;//表示要求字符串必须以a开头
        var str="waa";
        alert(patt.test(str));
    </script>
</head>
<body>

</body>
</html>

3.9.4节点的常用属性和方法

节点就是标签对象

方法:

  • getElementsByTagName():获取当前节点的指定标签名孩子节点
  • appendChild(oChildNode):可以添加一个子节点,oChildNode是要添加的孩子节点

属性:

  • childNodes:获取当前节点的所有子节点
  • firstChild:获取当前节点的第一个子节点
  • lastChild:获取当前节点的最后一个子节点
  • parentNode:获取当前节点的父节点
  • nextSibling:获取当前节点的下一个节点
  • className:用于获取或设置标签的class属性值
  • innerHTML:表示获取/设置起始标签和结束标签中的内容
  • innerText:表示获取/设置其实标签和结束标签中的文本

4、JQuery

4.1JQuery介绍

什么是JQuery?

  • JQuery,顾名思义,也就是JavaScript和查询(Query),它就是辅助javascript开发的js类库

jQuery好处?

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

jQuery的简单使用:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

<script type="text/javascript" src="../script/jquery-1.7.2.js"></script>
<script type="text/javascript">

	//使用$()代替window.onload
	$(function(){
		//使用选择器获取按钮对象,随后绑定单击响应函数
		$("#btnId").click(function(){
			//弹出Hello
			alert('Hello');
		});
	});

</script>


</head>
<body>

	<button id="btnId">SayHello</button>

</body>
</html>

常见问题:

  1. 使用jQuery一定要引入jQuery库吗?   是,一定
  2. jQuery中的$到底是什么?   它是一个函数
  3. 怎么为按钮添加点击响应函数的?  使用jQuery查询到标签对象,使用标签对象.click(function(){});

4.2jQuery核心函数

$是jQuery的核心函数,能完成jQuery的很多功能,$()就是调用$这个函数

  1. 传入参数为【函数】时:表示页面加载完成之后,相当于window.οnlοad=function(){};
  2. 传入的参数为【html字符串】时:会帮我们创建这个html标签对象
  3. 传入参数为【选择器字符串】时:$("#id属性值");->id选择器,根据id查询标签对象    $("标签名");->标签名选择器,根据指定的标签名查询标签对象   $(".class属性值");->类型选择器,可以根据class属性查询标签对象
  4. 传入参数为【DOM对象】时:会把这个dom对象转化为jQuery对象

4.3jQuery对象和dom对象区分

Dom对象:

  • 通过getElementById、getElementsByName、getElementsByTagName、creatElement方法创建的对象,是Dom对象
  • Dom对象alert出来的效果是:[object HTML 标签名:element]

jQuery对象:

  • 通过jQuery提供的API创建的对象,是jQuery对象
  • 通过jQuery包装的Dom对象,也是jQuery对象
  • 通过jQuery提供的API查询到的对象,是jQuery对象
  • jQuery对象alert出来的效果是:[object  Object]

jQuery对象的本质是什么?

  • jQuery对象是Dom对象的数组,jQuery提供一系列的功能函数

jQuery对象和Dom对象的使用区别?

  • jQuery对象不能使用Dom对象的属性和方法,Dom对象也不能使用jQuery对象的属性和方法

Dom对象和jQuery对象相互转换:

  • dom对象转化为jQuery对象:1.先有dom对象 2.$(dom对象);就可以转化为jQuery对象
  • jQuery对象转化为dom对象:1.先有jQuery对象 2.通过jQuery对象下标取出dom对象

4.4jQuery选择器

  • #id:根据给定的ID匹配一个元素。

  • element:根据给定的元素名匹配所有元素

  • .class:根据给定的类匹配元素。

  • *:匹配所有元素

  • selector1,selector2,selectorN:将每一个选择器匹配到的元素合并后一起返回。

  • ancestor descendant:在给定的祖先元素下匹配所有的后代元素

  • parent > child:在给定的父元素下匹配所有的子元素

  • prev + next:匹配所有紧接在 prev 元素后的 next 元素

  • prev ~ siblings:匹配 prev 元素之后的所有 siblings 元素

  • :first:获取第一个元素

  • :last():获取最后个元素

  • :not(selector):去除所有与给定选择器匹配的元素

  • :even:匹配所有索引值为偶数的元素,从 0 开始计数

  • :odd:匹配所有索引值为奇数的元素,从 0 开始计数

  • :eq(index):匹配一个给定索引值的元素

  • :gt(index):匹配所有大于给定索引值的元素

  • :lt(index):匹配所有小于给定索引值的元素

  • :header:匹配如 h1, h2, h3之类的标题元素

  • :animated:匹配所有正在执行动画效果的元素

  • :focus:触发每一个匹配元素的focus事件。这将触发所有绑定的focus函数,注意,某些对象不支持focus方法。

  • :contains(text):匹配包含给定文本的元素

  • :empty:匹配所有不包含子元素或者文本的空元素

  • :has(selector):匹配含有选择器所匹配的元素的元素

  • :parent:匹配含有子元素或者文本的元素

  • :hidden:匹配所有不可见元素,或者type为hidden的元素

  • :visible:匹配所有的可见元素

  • [attribute]:匹配包含给定属性的元素。注意,在jQuery 1.3中,前导的@符号已经被废除!如果想要兼容最新版本,只需要简单去掉@符号即可。

  • [attribute=value]:匹配给定的属性是某个特定值的元素

  • [attribute!=value]:匹配所有不含有指定的属性,或者属性不等于特定值的元素。

  • [attribute^=value]:匹配给定的属性是以某些值开始的元素

  • [attribute$=value]:匹配给定的属性是以某些值结尾的元素

  • [attribute*=value]:匹配给定的属性是以包含某些值的元素

  • [selector1][selector2][selectorN]:复合属性选择器,需要同时满足多个条件时使用。

  • :nth-child:匹配其父元素下的第N个子或奇偶元素

  • :first-child:匹配第一个子元素

  • :last-child:匹配最后一个子元素

  • :only-child:如果某个元素是父元素中唯一的子元素,那将会被匹配;如果父元素中含有其他元素,那将不会被匹配。

  • :input:匹配所有 input, textarea, select 和 button 元素

  • :text:匹配所有的单行文本框

  • :password:匹配所有密码框

  • :radio:匹配所有单选按钮

  • :checkbox:匹配所有复选框

  • :submit:匹配所有提交按钮

  • :image:匹配所有图像域

  • :reset:匹配所有重置按钮

  • :button:匹配所有按钮

  • :file:匹配所有文件域

  • :hidden:匹配所有不可见元素,或者type为hidden的元素

  • :enabled:匹配所有可用元素

  • :disabled:匹配所有不可用元素

  • :checked:匹配所有选中的被选中元素(复选框、单选框等,不包括select中的option)

4.5jQuery的属性操作

  • html()     它可以设置和获取起始标签和结束标签中的内容,与dom对象的属性innerHTML一样
  • text()      它可以设置和获取其实标签和结束标签中的文本,与dom对象的属性innerTest一样
  • val()       它可以设置和获取表单项的value属性值,与dom对象的属性value一样

val方法可以同时设置多个表单项的选中状态:

$(function(){
//批量操作单选
$(":radio").val(["radio2"]);//将值为radio2的单选项选中
//批量操作筛选框的选中状态
$(":checkbox").val(["checkbox3","checkbox2"]);//将值为checkbox2和checkbox3的复选框选中
//批量操作下拉列表
$("#single").val(["sin2"]);//将id名为single的下拉列表元素中值为sin2的下拉列表选项选中
//同时操作单选、多选、下拉列表
$(":radio,:checkbox,#single").val(["radio2","checkbox3","checkbox2","sin2"]);
})
  • attr()        可以设置和获取属性的值,不推荐操作checked、readOnly、selected、disabled等,attr()方法可以操作非标准的属性,比如自定义属性:abc,bb
  • prop()      可以设置和获取属性的值,只推荐操作checked、readOnly、selected、disabled等
<script type="text/javascript">
$(function(){
	//alert($(":checkbox:first").attr("name"));//获取第一个多选框中name属性的值
	//$(":checkbox:first").attr("name","abc");//设置第一个多选框中name属性的值

	//alert($(":checkbox:first").attr("checked"));//对于标签中未写入的checked属性,反回undefined,官方认为这样不好,因此引入prop
	//alert($(":checkbox:first").prop("checked"));//对于标签中未写入的checked属性,反回false
	//alert($(":checkbox:first").prop("checked"));//对于标签中写入了的checked属性,反回true

	//alert($(":checkbox:first").prop("checked",true));//设置让第一个多选项选中
	//alert($(":checkbox").prop("checked"),false);//设置让所有的多选项都不选中

	//($(":checkbox:first").attr("abc","abvValue"));//给自定义的abc属性赋值
	//alert($(":checkbox:first").attr("abc"));//获取自定义属性的值
})
</script>

jQuery练习:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="../../script/jquery-1.7.2.js"></script>
<script type="text/javascript">
	
	$(function(){
		
		var $items = $(":checkbox[name=items]");
		var items = $("[name='items']");
		//全选按钮
		$("#checkedAllBtn").click(function(){
			items.attr("checked",true);
			$("#checkedAllBox").attr("checked",true);
		});
		//全不选按钮
		$("#checkedNoBtn").click(function(){
			items.attr("checked",false);
			$("#checkedAllBox").attr("checked",false);
		});
		
		//反选按钮
		$("#checkedRevBtn").click(function(){
			items.each(function(){
				this.checked = !this.checked;
			});
			var flag = $("[name='items']:checked").length==4;
			$("#checkedAllBox").attr("checked",flag);
		});
		
		//提交按钮
		$("#sendBtn").click(function(){
			$(":checkbox[name='items']:checked").each(function(){
				alert(this.value);
			});
		});
		
		//全选/全不选复选框
		$("#checkedAllBox").click(function(){
			items.attr("checked",this.checked);
		});
		
		//全选/全不选复选框与items状态同步
		$("[name='items']").click(function(){
			var flag = $("[name='items']:checked").length==4;
			$("#checkedAllBox").attr("checked",flag);
		});
	});
	
</script>
</head>
<body>

	<form method="post" action="">
	
		你爱好的运动是?<input type="checkbox" id="checkedAllBox" />全选/全不选 
		
		<br />
		<input type="checkbox" name="items" value="足球" />足球
		<input type="checkbox" name="items" value="篮球" />篮球
		<input type="checkbox" name="items" value="羽毛球" />羽毛球
		<input type="checkbox" name="items" value="乒乓球" />乒乓球
		<br />
		<input type="button" id="checkedAllBtn" value="全 选" />
		<input type="button" id="checkedNoBtn" value="全不选" />
		<input type="button" id="checkedRevBtn" value="反 选" />
		<input type="button" id="sendBtn" value="提 交" />
	</form>

</body>
</html>

4.6DOM的增删改

内部插入:

  • appendTo()         a.appendTo(b)把a插入到b子元素末尾,成为最后一个子元素         a.append(b)把b插入到a子元素末尾,成为最后一个元素
  • prependTo()        a.prependTo(b)把a插到b所有子元素前面,成为第一个子元素

外部插入:

  • insertAfter()        a.insertAfter(b)得到ba
  • insertBefore()     a.insertBefore(b)得到ab

替换:

  • replaceWith()     a.replaceWith(b),用b替换掉a
  • replaceAll()        a.replaceAll(b),用a替换掉所有的b

删除:

 

  • remove()           a.remove(),删除a标签      a.remove(b),所有的a,是b的话就会删除    
  • empty()             a.empty(),清空a标签里的内容,但a标签还在
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Untitled Document</title>
<link rel="stylesheet" type="text/css" href="styleB/css.css" />
<script type="text/javascript" src="../../script/jquery-1.7.2.js"></script>
<script type="text/javascript">
	
	$(function(){
		
		//删除用户的方法
		function delA(){
			//获取要删除员工的名字
			var name = $(this).parents("tr").find("td:eq(0)").text();
			//弹出一个确认框
			var flag = confirm("确认删除"+name+"吗?");
			if(flag){
				//删除当前a所在的tr
				$(this).parents("tr").remove();
			}
			//取消默认行为
			return false;
		}
		
		//删除用户
		//$("a").click(delA);
		$("a").live("click" , delA);
		
		//添加员工
		$("#addEmpButton").click(function(){
			//获取用户填写的内容
			var name = $("#empName").val();
			var email = $("#email").val();
			var salary = $("#salary").val();
			
			//创建tr
			/*
				<tr>
					<td>Tom</td>
					<td>tom@tom.com</td>
					<td>5000</td>
					<td><a href="#">Delete</a></td>
				</tr>
			*/
			$("<tr></tr>").append("<td>"+name+"</td>")
						  .append("<td>"+email+"</td>")
						  .append("<td>"+salary+"</td>")
						  .append("<td><a href='#'>Delete</a></td>")
						  .appendTo("#employeeTable");
			
		});
	});
	
	
</script>
</head>
<body>

	<table id="employeeTable">
		<tr>
			<th>Name</th>
			<th>Email</th>
			<th>Salary</th>
			<th>&nbsp;</th>
		</tr>
		<tr>
			<td>Tom</td>
			<td>tom@tom.com</td>
			<td>5000</td>
			<td><a href="#">Delete</a></td>
		</tr>
		<tr>
			<td>Jerry</td>
			<td>jerry@sohu.com</td>
			<td>8000</td>
			<td><a href="#">Delete</a></td>
		</tr>
		<tr>
			<td>Bob</td>
			<td>bob@tom.com</td>
			<td>10000</td>
			<td><a href="#">Delete</a></td>
		</tr>
	</table>

	<div id="formDiv">
	
		<h4>添加新员工</h4>

		<table>
			<tr>
				<td class="word">name: </td>
				<td class="inp">
					<input type="text" name="empName" id="empName" />
				</td>
			</tr>
			<tr>
				<td class="word">email: </td>
				<td class="inp">
					<input type="text" name="email" id="email" />
				</td>
			</tr>
			<tr>
				<td class="word">salary: </td>
				<td class="inp">
					<input type="text" name="salary" id="salary" />
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<button id="addEmpButton" value="abc">
						Submit
					</button>
				</td>
			</tr>
		</table>
	</div>
</body>
</html>

4.7CSS样式操作

  • addClass()    添加样式
  • removeClass()    删除样式
  • toggleClass()     有就删除,没有就添加样式
  • offset()     获取和设置元素的坐标
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
	
	div{
		width:100px;
		height:260px;
	}
	
	div.whiteborder{
		border: 2px white solid;
	}
	
	div.redDiv{
		background-color: red;
	}
	
	div.blueBorder{
		border: 5px blue solid;
	}
	
</style>

<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
<script type="text/javascript">
	

	$(function(){
		
		var $divEle = $('div:first');
		
		$('#btn01').click(function(){
			//addClass() - 向被选元素添加一个或多个类
			$divEle.addClass("redDiv blueBorder");//添加红色背景、蓝色边框样式
		});
		
		$('#btn02').click(function(){
			//removeClass() - 从被选元素删除一个或多个类 
			$divEle.removeClass("redDiv");//删除红色背景样式
		});
	
		
		$('#btn03').click(function(){
			//toggleClass() - 对被选元素进行添加/删除类的切换操作 
			$divEle.toggleClass("redDiv");//对于红色背景样式,有就删除,没有就添加
		});
		
		
		$('#btn04').click(function(){
			//offset() - 返回第一个匹配元素相对于文档的位置。
			var pos=$divEle.offset();
			console.log(pos);//打印{top:11,left:380.5}
			// 设置第一个匹配元素相对于文档的位置
			$divEle.offset({
				top:100,
				left:50
			});
		});
		
	
		
	})
</script>
</head>
<body>

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

4.8jQuery样式

基本:

  • show()    将隐藏的元素显示
  • hide()      将可见的元素隐藏
  • toggle()   可见就隐藏,不可见就显示

淡入淡出:

  • fadeIn()   淡入(慢慢可见)
  • fadeOut()   淡出(慢慢消失)
  • fadeTo()    在指定时长内慢慢的将透明度修改到指定的值,0:不可见     1:完全可见    1.5:半透明
  • fadeToggle()    淡入/淡出 切换

以上动画都可以添加参数

1、第一个参数就是动画执行的时长,以毫秒为单位

2、第二个参数是动画的回调函数(动画完成后自动调用的函数)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Untitled Document</title>
		<link href="css/style.css" type="text/css" rel="stylesheet" />
		<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
	
<script type="text/javascript">
	/* 	
		基本
		show([speed,[easing],[fn]]) 
		hide([speed,[easing],[fn]]) 
		toggle([speed],[easing],[fn]) 
		滑动
		slideDown([spe],[eas],[fn]) 
		slideUp([speed,[easing],[fn]]) 
		slideToggle([speed],[easing],[fn]) 
		淡入淡出
		fadeIn([speed],[eas],[fn]) 
		fadeOut([speed],[eas],[fn]) 
		fadeTo([[spe],opa,[eas],[fn]]) 
		fadeToggle([speed,[eas],[fn]])
		*/
		$(function(){
			//显示   show()
			$("#btn1").click(function(){
				$("#div1").show(1000,function () {
						alert("show动画执行完成")
				});
			});		
			//隐藏  hide()
			$("#btn2").click(function(){
				$("#div1").hide(2000);
			});	
			//切换   toggle()
			$("#btn3").click(function(){
				$("#div1").toggle(1000);
			});

			//自己调用自己
			// var abc=function(){
			// 	$("#div1").toggle(1000,abc)
			// }
			// abc();

			//淡入   fadeIn()
			$("#btn4").click(function(){
				$("#div1").fadeIn();
			});	
			//淡出  fadeOut()
			$("#btn5").click(function(){
				$("#div1").fadeOut(2000);
			});	
			
			//淡化到  fadeTo()
			$("#btn6").click(function(){
				$("#div1").fadeTo(1000,0.5,function () {
						alert("fadeTo完成");
				});
			});	
			 //淡化切换  fadeToggle()
				$("#btn7").click(function(){
				$("#div1").fadeToggle();
			});
		})
</script>
	
	</head>
	<body>
		<table style="float: left;">
			<tr>
				<td><button id="btn1">显示show()</button></td>
			</tr>
			<tr>
				<td><button id="btn2">隐藏hide()</button></td>
			</tr>
			<tr>
				<td><button id="btn3">显示/隐藏切换 toggle()</button></td>
			</tr>
			<tr>
				<td><button id="btn4">淡入fadeIn()</button></td>
			</tr>
			<tr>
				<td><button id="btn5">淡出fadeOut()</button></td>
			</tr>
			<tr>
				<td><button id="btn6">淡化到fadeTo()</button></td>
			</tr>
			<tr>
				<td><button id="btn7">淡化切换fadeToggle()</button></td>
			</tr>
		</table>
		
		<div id="div1" style="float:left;border: 1px solid;background-color: blue;width: 300px;height: 200px;">
			jquery动画定义了很多种动画效果,可以很方便的使用这些动画效果
		</div>
	</body>

</html>

4.9jQuery事件操作

$(function(){});和window.οnlοad=function(){};的区别

他们分别是在什么时候触发?

  1. jQuery的页面加载完成之后是浏览器的内核解析完页面的标签创建好DOM对象之后就是马上执行
  2. 原生js的页面加载完成之后,除了要等浏览器内核解析完标签创建好DOM对象,还要等标签显示时需要的内容加载完成

他们触发的顺序?

  1. jQuery页面加载完成之后先执行
  2. 原生js的页面加载完成之后

他们执行的次数?

  1. 原生js的页面加载完成之后,只会执行最后一次的赋值函数
  2. jQuery的页面加载完成之后是全部把注册的function函数,一次顺序全部执行

jQuery中其它的事件处理方法:

  • click()   它可以绑定单击事件,以及触发单击事件
  • mouseover()  鼠标移入事件
  • mouseout()   鼠标移出事件
  • bind()    可以给元素一次性绑定一个或多个事件
  • one()    使用上跟bind一样,但是one方法绑定的事件只会响应一次
  • unbind()    跟bind方法相反的操作,解除事件的绑定
  • live()   也是用来绑定事件,它可以用来绑定选择器匹配的所有元素的事件,哪怕这个元素是后面动态创建出来的也有效
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Untitled Document</title>
		<link href="css/style.css" type="text/css" rel="stylesheet" />
		<script type="text/javascript" src="../../script/jquery-1.7.2.js"></script>
		<script type="text/javascript">
		
			$(function(){
				//1.通常绑定事件的方式
				//2.jQuery提供的绑定方式:bind()函数
				//3.合并“鼠标移入”和“鼠标移出”事件
				//4.合并单击事件
				//5.切换元素可见状态
				//6.只绑定一次
				/*$("h5").click(function () {//传function是绑定事件
					alert("h5单击事件")
				})

				$("button").click(function () {
				$("h5").click();//不传function是触发事件
				})*/

				//鼠标移入事件
				/*$("h5").mouseover(function () {
					console.log("鼠标进来了")
				});
				//鼠标移出事件
				$("h5").mouseout(function () {
					console.log("鼠标出去了")
				});*/

				//使用bind绑定多个事件,发生点击、鼠标移入、鼠标移出h5标签里时都会在控制台输出这句话
				/*$("h5").bind("click mouseover mouseout",function () {
						console.log("这是bind绑定的事件");
				})*/
				//取消绑定click事件和鼠标移入事件
				/*$("h5").unbind("click mouseover");
				$("h5").unbind();//取消绑定所有的事件*/

				//使用one绑定多个事件,和bind不同的是,对点击、移入、移出事件只会各自响应一次
				/*$("h5").one("click mouseover mouseout",function () {
					console.log("这是one绑定的事件");
				})*/

				//使用live绑定的单击事件,对于后面动态创建出来的h5元素也有效,而bind和one不能实现
				$("h5").live("click",function () {
					console.log("这是live绑定的事件");
				})
				$("<h5 class='head'>什么是jQuery</h5>").appendTo("#panel");

			});
		</script>
	</head>
	<body>
		<div id="panel">
			<h5 class="head">什么是jQuery?</h5>
			<button>按钮</button>
			<div class="content">
				jQuery是继Prototype之后又一个优秀的JavaScript库,它是一个由 John Resig 创建于2006年1月的开源项目。jQuery凭借简洁的语法和跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了JavaScript程序员的设计思路和编写程序的方式。
			</div>
		</div>
	</body>

</html>

事件冒泡:

什么是事件冒泡?

事件的冒泡是指,父元素子元素同时监听同一个事件。当触发子元素的事件的时候,同一个事件也被传递到了父元素的事件里去响应

那么如何阻止元素的冒泡呢?

在子元素事件函数体内,,return false,可以阻止事件的冒泡传递

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Untitled Document</title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			body{
				font-size: 13px;
				line-height: 130%;
				padding: 60px;
			}
			#content{
				width: 220px;
				border: 1px solid #0050D0;
				background: #96E555;
			}
			span{
				width: 200px;
				margin: 10px;
				background: #666666;
				cursor: pointer;
				color: white;
				display: block;
			}
			p{
				width: 200px;
				background: #888;
				color: white;
				height: 16px;
			}
		</style>
		<script type="text/javascript" src="jquery-1.7.2.js"></script>
		<script type="text/javascript">
			$(function(){
				$("#content").click(function () {
					alert("我是div");
				})

				$("span").click(function () {
					alert("我是span");
					return false;
				})
			})
		</script>
	</head>
	<body>
		<div id="content">
			外层div元素
			<span>内层span元素</span>
			外层div元素
		</div>
		
		<div id="msg"></div>	
		
		<br><br>
		<a href="http://www.hao123.com">WWW.HAO123.COM</a>	
	</body>
</html>

javaScript事件对象:

事件对象,是封装有触发的事件信息的一个javaScript对象。我们重点关心的是怎么得到这个javaScript的事件对象,以及使用

如何获取javaScript事件对象呢?

在给元素绑定事件的时候,在事件的function(event)参数列表中添加一个参数,这个参数名,我们习惯取名为event,这个event就是javaScript事件处理函数的事件对象

//1.原生javascript获取 事件对象
window.onload=function () {
   document.getElementById("areaDiv").onclick=function (event) {
         console.log(event);
   }
}
//2.JQuery代码获取 事件对象
$(function () {
   $("#areaDiv").click(function (event) {
      console.log(event);
   });
});
//3.使用bind同时对多个事件绑定同一个函数。怎么获取当前操作是什么事件。
$(function () {
   $("#areaDiv").bind("mouseover mouseout",function (event) {
      if (event.type=="mouseover"){
         console.log("鼠标移入");
      }else if(event.type=="mouseout"){
         console.log("鼠标移出");
      }
   });
});

案例:图片跟随

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
	body {
		text-align: center;
	}
	#small {
		margin-top: 150px;
	}
	#showBig {
		position: absolute;
		display: none;
	}
</style>
<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
<script type="text/javascript">
	$(function(){
		$("#small").bind("mouseover mouseout mousemove",function (even) {
			if (even.type=="mouseover"){
				$("#showBig").show();
			}else if (even.type=="mouseout"){
				$("#showBig").hide();
			}else if (even.type=="mousemove"){
				$("#showBig").offset({
					left:even.pageX+10,  //使大图片和鼠标相隔一段距离,防止鼠标向大图片方向移动时图标到了大图片的位置
					top:even.pageY+10   //,以为你鼠标离开了,大图片不显示,从而出现大图片闪烁的现象
				})
			}
		})

	});
</script>
</head>
<body>

	<img id="small" src="img/small.jpg" />
	
	<div id="showBig">
		<img src="img/big.jpg">
	</div>

</body>
</html>

5、XML

5.1XML简介

什么是XML?

  • XML是可扩展的标记性语言

XML的作用?

XML的主要作用有:

  1. 用来保存数据,而且这些数据具有自我描述性
  2. 它还可以作为项目或者模块的配置文件
  3. 它还可以作为网络传输数据的格式(现在Json为主)

5.2文档声明

1)创建一个xml文件:首先创建一个java项目,然后在项目下创建一个目录,在目录下创建一个file,文件名为xxxx.xml即可

2)编写xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 
    <?xml version="1.0" encoding="UTF-8" ?>
    以上内容是xml文件的声明
    version="1.0"      version表示xml的版本
    encoding="UTF-8"   encoding表示xml文件的本身编码
-->
<books> <!--books表示多个图书信息-->
    <book sn="an1234"><!--book表示一个图书信息,sn属性表示图书序列号-->
        <name>时间简史</name><!--name标签表示书名-->
        <author>霍金</author><!--author表示作者-->
        <price>75</price><!--price表示图书价格-->
    </book>
    <book sn="an18255634"><!--book表示一个图书信息,sn属性表示图书序列号-->
        <name>java从入门到精通</name><!--name标签表示书名-->
        <author>沙老师</author><!--author表示作者-->
        <price>95</price><!--price表示图书价格-->
    </book>
    <book sn="1112134" name="斗罗大陆" author="唐三" price="112"/>//单标签
</books>

xml注释:html和xml注释一样,<!--注释信息-->

5.3元素(标签)

什么是 XML 元素?

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

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

<bookstore>
<book category="CHILDREN">
  <title>Harry Potter</title> 
  <author>J K. Rowling</author> 
  <year>2005</year> 
  <price>29.99</price> 
</book>
<book category="WEB">
  <title>Learning XML</title> 
  <author>Erik T. Ray</author> 
  <year>2003</year> 
  <price>39.95</price> 
</book>
</bookstore> 

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

XML 命名规则

XML 元素必须遵循以下命名规则:

  • 名称可以含字母、数字以及其他的字符
  • 名称不能以数字或者标点符号开始
  • 名称不能以字符 “xml”(或者 XML、Xml)开始
  • 名称不能包含空格

可使用任何名称,没有保留的字词。

XML 属性

从 HTML,你会回忆起这个:<img src="computer.gif">。"src" 属性提供有关 <img> 元素的额外信息。

在 HTML 中(以及在 XML 中),属性提供有关元素的额外信息:

5.4xml语法规则

  • 所有 XML 元素都须有关闭标签

  • XML 标签对大小写敏感

  • XML标签 必须正确地嵌套

  • XML 文档必须有根元素(XML 文档必须有一个元素是所有其他元素的父元素。该元素称为根元素。)

  • XML 的属性值须加引号

xml中特殊字符:

文本域(CDATA):CDATA语法可以告诉xml解析器,我CDATA文本里的内容,只是纯文本,不需要xml语法解析

CDATA格式:<![CDATA[这里可以把你输入的字符原样显示,不会解析xml]]>

5.5Dom4j解析技术

由于dom4j不是sun公司的技术,而属于第三方公司的技术,我们需要使用dom4j,就需要到dom4j官方下载dom4j的jar包

1)创建好xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--
    <?xml version="1.0" encoding="UTF-8" ?>
    以上内容是xml文件的声明
    version="1.0"      version表示xml的版本
    encoding="UTF-8"   encoding表示xml文件的本身编码
-->
<books> <!--books表示多个图书信息-->
    <book sn="an1234"><!--book表示一个图书信息,sn属性表示图书序列号-->
        <name>时间简史</name><!--name标签表示书名-->
        <author>霍金</author><!--author表示作者-->
        <price>75</price><!--price表示图书价格-->
    </book>
    <book sn="an18255634"><!--book表示一个图书信息,sn属性表示图书序列号-->
        <name>java从入门到精通</name><!--name标签表示书名-->
        <author>沙老师</author><!--author表示作者-->
        <price>95</price><!--price表示图书价格-->
    </book>
    <book sn="1112134" name="斗罗大陆" author="唐三" price="112"/><!--单标签-->
    <![CDATA[,,,,<<<<<嘿嘿嘿]]>
</books>

2)创建一个与xml中信息对应的类

package com.atguigu.pojo;

import java.math.BigDecimal;

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

    public Book() {
    }

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

    public String getSn() {
        return sn;
    }

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

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

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

    public double getPrice() {
        return price;
    }

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


}

3)导入don4j-1.6.1.jar,添加到类路径中

项目的src下创建一个目录Lib,将jar包复制到此目录中,右键jar包->点击Add as Library...

4)测试类:

先按导入don4j-1.6.1.jar的方法导入两个jar包:hamcrest-core-1.3.jar和junit-4.12.jar

package com.atguigu.pojo;

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

import java.util.List;

public class Dom4jTest {
    @Test
    public void test1()throws Exception{
        //创建一个SAXReader输入流,去读取xml配置文件,生成document对象
        SAXReader saxReader=new SAXReader();
        Document document=saxReader.read("src/books.xml");
        System.out.println(document);
    }

    /*
    读取bookx.xml生成Book类
     */
    @Test
    public void test2()throws Exception{
        //1读取Books.xml文件
        SAXReader saxReader=new SAXReader();
        Document document=saxReader.read("src/books.xml");
        //2通过文档对象获取根元素
       Element rootElement= document.getRootElement();
        System.out.println(rootElement);
        //3根据跟元素获取book标签对象
      List<Element> books=rootElement.elements("book");
        //4遍历,处理每个book标签,转化为book类
        for (Element book:books){
            Element nameElement=book.element("name");//获取name元素
            String nameText=nameElement.getText();//获取name元素中的文本内容

            String priceText=book.elementText("price");//直接获取price标签名中的文本内容
            String authorText=book.elementText("author");

            String snValue=book.attributeValue("sn");//获取sn属性的值

           double price= Double.parseDouble(priceText);
            //System.out.println(price);
            System.out.println(new Book(snValue,nameText,authorText,price));
        }
    }
}

6、Tomcat

6.1JavaWeb的概念

a)什么是JavaWeb?

JavaWeb是指,所有通过java语言编写可以通过浏览器访问的程序的总称,叫JavaWeb,JavaWeb是基于请求和响应来开发的

b)什么是请求?

请求是指客户端给服务器发送数据,叫请求request

c)什么是响应?

响应是指服务器给客户端回传数据,叫响应response

d)请求和响应的关系?

请求和响应是成对出现的,有请求就有响应

6.2Web资源的分类

web资源按实现的技术和呈现的效果的不同,又分为静态资源和动态资源两种

静态资源:html、css、js、txt、mp4视频、jpg图片

动态资源:jsp页面,servlet程序

6.3常用的Web服务器

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

Jboss:是一个遵从JavaEE规范的、开放源代码的、纯java的EJB服务器,它支持所有的JavaEE规范(免费)

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

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

WebLogic:是Oracle公司的产品,是目前应用最广泛的web服务器,支持javaEE规范,而且不断地完善以适应新的开发需求,适合大型项目(收费,用的不多,适合大公司)

6.4Tomcat服务器和Servlet版本的对应关系

当前企业常用的版本jdk 7.*/8.*

Servlet程序从2.5版本是现在市面使用最多的版本(xml配置),到了Servlet3.0之后,就是注解版本的Servlet使用。

6.5Tomcat的使用

a)安装:找到你需要用的Tomcat版本对应的zip压缩包,解压到需要安装的目录即可

b)目录介绍:

Bin        专门用来存放Tomcat服务器的执行程序

conf       专门用来存放Tomcat服务器的配置文件

lib          专门用来存放Tomcat服务器jar包

logs       专门用来存放运行时输出的日记信息

temp      专门用来存放Tomcat服务器运行时产生的临时数据

webapps      专门用来存放部署的web工程

work      是Tomcat运行时的目录,用来存放Tomcat运行时jsp翻译为servlet的源码,和钝化的目录

c)如何启动Tomcat服务器:

找到Tomcat目录下的bin目录下的startup.bat文件,双击,就可以启动Tomcat服务器

如何测试Tomcat服务器启动成功?

打开浏览器,在浏览器地址栏中输入以下地址测试:

1、http://localhost:8080

2、http://127.0.0.1:8080

3、http://真实ip:8080

当出现如下界面,说明Tomcat服务器启动成功:

常见的启动失败的情况有,双击startup.bat文件,就会出现一个小黑窗口一闪而过,这个时候,失败的原因都是因为没有配置好JAVA_HOME环境变量

另一种启动Tomcat服务器的方式

1、打开命令行

2、cd到你的Tomcat的bin目录下

3、敲入启动命令:catalina run

d)Tomcat的停止

1、点击Tomcat服务器窗口的x关闭按钮

2、把Tomcat服务器窗口置为当前窗口,然后按快捷键ctrl+c

3、找到Tomcat的bin目录下的shutdown.bat双击,就可以停止Tomcat服务器

e)如何修改Tomcat的端口号

Mysql的默认端口是:3306      Tomcat的默认端口是:8080

找到Tomcat目录下的conf目录,找到server.xml配置文件,找到Connector标签,修改port属性修改端口号为1—65535之间,修改完端口号,一定要重启Tomcat服务器才能生效

f)如何部署web工程到Tomcat中

第一种方法:只需要把web工程的目录拷贝到Tomcat的webapps目录下即可,然后在浏览器中输入:http://localhost:8080/books/index.html即可访问

第二种方法:找到Tomcat下的conf目录\Catalina\localhost\下,创建如下的配置文件

abc.xml 配置文件内容如下:
<!-- Context 表示一个工程上下文
path 表示工程的访问路径 :/abc
docBase 表示你的工程目录在哪里
-->
<Context path="/abc" docBase="E:\book" />
访问这个工程的路径如下 :http://ip:port/abc/
就表示访问 E:\book 目录
 

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

手托 html 页面的原理:
 
输入访问地址访问的原因:
 

h)ROOT的工程访问,以及默认index.html页面的访问

当我们在浏览器地址栏中输入访问地址如下:
http://ip:port/ ====>>>> 没有工程名的时候,默认访问的是 ROOT 工程。
 
当我们在浏览器地址栏中输入的访问地址如下:
http://ip:port/工程名 / ====>>>> 没有资源名,默认访问 index.html 页面

6.6IDEA整合Tomcat服务器

操作的菜单如下: File | Settings | Build, Execution, Deployment | Application Servers
配置你的 Tomcat 安装目录:
就可以通过创建一个 Model 查看是不是配置成功!!!

6.7IDEA中动态web工程的操作

a)IDEA 中如何创建动态 web 工程
1 、创建一个新模块:
2 、选择你要创建什么类型的模块:
3 、输入你的模块名,点击【 Finish 】完成创建。
4 、创建成功如下图:
b)Web 工程的目录介绍
c) 如何给动态 web 工程添加额外 jar

方法一:将jar包复制到lib文件夹->右键jar包->Add as Library...

方法二:

1 、可以打开项目结构菜单操作界面->file->project structure...,添加一个自己的类库:
2 、添加你你类库需要的 jar 包文件。
3 、选择你添加的类库,给哪个模块使用:
4 、选择 Artifacts 选项,将类库,添加到打包部署中:
 

 

d) 如何在 IDEA 中部署工程到 Tomcat 上运行
 
1 、建议修改 web 工程对应的 Tomcat 运行实例名称:
2 、确认你的 Tomcat 实例中有你要部署运行的 web 工程模块:
3 、你还可以修改你的 Tomcat 实例启动后默认的访问地址:
4 、在 IDEA 中如何运行,和停止 Tomcat 实例。
4.1 、正常启动 Tomcat 实例:
4.2 Debug 方式启动 Tomcat 运行实例:
4.3 、停止 Tomcat 运行实例:
4.4 、重启 Tomcat 运行实例:
e) 修改工程访问路径
 
 
f) 修改运行的端口号
 
g) 修改运行使用的浏览器
 
h) 配置资源热部署

 

7、Servlet

7.1Servlet技术

a)什么是Servlet技术

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

b)手动实现Servlet程序

  1. 编写一个类去实现Servlet接口
  2. 实现service方法,处理请求,并响应数据
  3. 到web.xml中去配置servlet程序的访问地址
  4. 在浏览器中运行http://localhost:8080/06_servlet/hello
package com.atguigu.servlet;

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

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

    }

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

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

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

    @Override
    public void destroy() {

    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--  servlet标签给Tomcat配置Servlet程序-->
    <servlet>
        <!-- servlet-name标签:servlet程序起一个别名(一般是类名)-->
        <servlet-name>HelloServlet</servlet-name>
        <!--servlet-class:是servlet程序的全类名 -->
        <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--servlet-mapping标签给servlet程序配置访问地址 -->
    <servlet-mapping>
        <!--servlet-name标签的作用是告诉服务器,我当前配置的地址给那个servlet程序使用 -->
        <servlet-name>HelloServlet</servlet-name>
        <!-- url-pattern标签配置访问地址
        /在服务器解析的时候,表示地址为:http://ip:port/工程路径
        /hello  表示地址为:http://ip:port/工程路径/hello-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

c)url 地址到 Servlet 程序的访问

 

d)Servlet 的生命周期
1 、执行 Servlet 构造器方法
2 、执行 init 初始化方法
第一、二步,是在第一次访问,的时候创建 Servlet 程序会调用。
3 、执行 service 方法
第三步,每次访问都会调用。
4 、执行 destroy 销毁方法
第四步,在 web 工程停止的时候调用。
 
 
e)GET POST 请求的分发处理
public class HelloServlet implements Servlet {
 /*** service 方法是专门用来处理请求和响应的
 * @param servletRequest 
* @param servletResponse 
* @throws ServletException
 * @throws IOException 
*/ 
@Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { 
System.out.println("3 service === Hello Servlet 被访问了");
 // 类型转换(因为它有 getMethod()方法) 
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; 
// 获取请求的方式 
String method = httpServletRequest.getMethod(); 
if ("GET".equals(method)) {
 doGet(); 
} else if ("POST".equals(method)) { 
doPost(); }
 }
/*** 做 get 请求的操作 */
 public void doGet(){ 
System.out.println("get 请求"); 
System.out.println("get 请求");
 }
/*** 做 post 请求的操作 */
 public void doPost(){ 
System.out.println("post 请求"); 
System.out.println("post 请求");
 } }
f) 通过继承 HttpServlet 实现 Servlet 程序
一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。
1 、编写一个类去继承 HttpServlet
2 、根据业务需要重写 doGet doPost 方法
3 、到 web.xml 中的配置 Servlet 程序的访问地址

 

Servlet 类的代码:
package com.atguigu.servlet;

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

public class HelloServlet2 extends HttpServlet {
    /*
    doGet():在get请求的时候调用
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet2 的doGet方法");
    }

    /*
    doPost():在post请求的时候调用
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloServlet2 的doPost方法");
    }
}
web.xml 中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--  servlet标签给Tomcat配置Servlet程序-->
    
    <servlet>
        <servlet-name>HelloServlet2</servlet-name>
        <servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet2</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
</web-app>

发送请求的html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/06_servlet/hello2" method="get">
   <input type="submit">
</form>
</body>
</html>
g) 使用 IDEA 创建 Servlet 程序
菜单: new ->Servlet 程序
配置 Servlet 的信息:

h)Servlet 类的继承体系

 

72.ServletConfig类

ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类

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

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

a)ServletConfig类的三大作用

  1. 可以获取Servlet程序的别名servlet-name的值
  2. 获取初始化参数init.param
  3. 获取ServletConfig对象
web.xml 中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--  servlet标签给Tomcat配置Servlet程序-->
    <servlet>
        <!-- servlet-name标签:servlet程序起一个别名(一般是类名)-->
        <servlet-name>HelloServlet</servlet-name>
        <!--servlet-class:是servlet程序的全类名 -->
        <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
        <!-- init-param:初始化参数  param-name:参数名  param-value:参数值 -->
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/test</param-value>
        </init-param>
    </servlet>
    <!--servlet-mapping标签给servlet程序配置访问地址 -->
    <servlet-mapping>
        <!--servlet-name标签的作用是告诉服务器,我当前配置的地址给那个servlet程序使用 -->
        <servlet-name>HelloServlet</servlet-name>
        <!-- url-pattern标签配置访问地址
        /在服务器解析的时候,表示地址为:http://ip:port/工程路径
        /hello  表示地址为:http://ip:port/工程路径/hello-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>

Servlet 中的代码:
package com.atguigu.servlet;

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

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

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

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

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

    @Override
    public void destroy() {

    }
}

输出结果:

注意:

7.3ServletContext类

a)什么是ServletContext?

  1. ServletContext是一个接口,它表示Servelet上下文对象
  2. 一个web工程,只有一个ServletContext对象实例
  3. ServletContext对象是一个域对象

什么是域对象:

域对象是可以像Map一样存取数据的对象,叫域对象,这里的域指的是存取数据的操作范围,整个web工程。

                         存数据             取数据                删除数据

Map                    put ()                get ()                   remove()

域对象          putAttribute()       getAttribute()      removeAttribute()

b)ServletContext 类的四个作用

1 、获取 web.xml 中配置的上下文参数 context-param
2 、获取当前的工程路径,格式 : / 工程路径
3 、获取工程部署后在服务器硬盘上的绝对路径
4 、像 Map 一样存取数据
 
ServletContext 演示代码:
package com.atguigu.servlet;

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

public class ServletContext extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取 web.xml 中配置的上下文参数 context-param
      javax.servlet.ServletContext context=  getServletConfig().getServletContext();
        System.out.println("context-param参数username的值是:"+context.getInitParameter("username"));
        System.out.println("context-param参数password的值是:"+context.getInitParameter("password"));
        //2、获取当前的工程路径,格式: /工程路径
        System.out.println("当前工程路径"+context.getContextPath());
//        3、获取工程部署后在服务器硬盘上的绝对路径
        System.out.println("工程部署的路径是"+context.getRealPath("/"));//斜杠被服务器解析为:http://ip:port/工程名/
        System.out.println("web工程下index.jsp的路径是"+context.getRealPath("/index.jsp"));
//        4、像 Map 一样存取数据
    }
}
web.xml 中的配置:
<!--context-param 是上下文参数(它属于整个 web 工程)-->
 <context-param> 
     <param-name>username</param-name>
     <param-value>context</param-value>
 </context-param> 
<!--context-param 是上下文参数(它属于整个 web 工程)-->
 <context-param> 
    <param-name>password</param-name> 
    <param-value>root</param-value> 
</context-param>
ServletContext Map 一样存取数据:
ContextServlet1 代码:
public class ContextServlet1 extends HttpServlet { 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 // 获取 ServletContext 对象 
ServletContext context = getServletContext();
 System.out.println(context); 
System.out.println("保存之前: Context1 获取 key1 的值是:"+ context.getAttribute("key1")); context.setAttribute("key1", "value1");
 System.out.println("Context1 中获取域数据 key1 的值是:"+ context.getAttribute("key1")); } }

7.4HTTP 协议

a) 什么是 HTTP 协议
什么是协议 ?
协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。
HTTP 协议中的数据又叫报文。
b) 请求的 HTTP 协议格式
客户端给服务器发送数据叫请求。
服务器给客户端回传数据叫响应。
请求又分为 GET 请求,和 POST 请求两种
 
i. GET 请求
1 、请求行
        (1) 请求的方式           GET
        (2) 请求的资源路径 [+?+ 请求参数 ]
        (3) 请求的协议的版本号       HTTP/1.1
2 、请求头 key : value 组成   不同的键值对,表示不同的含义。

ii. POST 请求
1 、请求行
      (1) 请求的方式    POST
      (2) 请求的资源路径 [+?+ 请求参数 ]
      (3) 请求的协议的版本号 HTTP/1.1
2 、请求头
       1) key : value  不同的请求头,有不同的含义
空行
3 、请求体 ===>>> 就是发送给服务器的数据
 
iii. 常用请求头的说明
Accept: 表示客户端可以接收的数据类型
Accpet-Languege: 表示客户端可以接收的语言类型
User-Agent: 表示客户端浏览器的信息
Host : 表示请求时的服务器 ip 和端口号
 
iv. 哪些是 GET 请求,哪些是 POST 请求
GET 请求有哪些:
     1 form 标签 method=get
     2 a 标签
     3 link 标签引入 css
     4 Script 标签引入 js 文件
     5 img 标签引入图片
     6 iframe 引入 html 页面
     7 、在浏览器地址栏中输入地址后敲回车
POST 请求有哪些:
     8 form 标签 method=post
c) 响应的 HTTP 协议格式
1 、响应行
     (1) 响应的协议和版本号
     (2) 响应状态码
     (3) 响应状态描述符
2 、响应头
(1) key : value 不同的响应头,有其不同含义
空行
3 、响应体
---->>>
就是回传给客户端的数据

d) 常用的响应码说明
200 表示请求成功
302 表示请求重定向(明天讲)
404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
e)MIME 类型说明
MIME HTTP 协议中数据类型。
MIME 的英文全称是 "Multipurpose Internet Mail Extensions" 多功能 Internet 邮件扩充服务。 MIME 类型的格式是“大类型 /
类型”,并与某一种文件的扩展名相对应。

 

常见的 MIME 类型:

谷歌浏览器如何查看 HTTP 协议:
火狐浏览器如何查看 HTTP 协议:

7.5.HttpServletRequest

a)HttpServletRequest 类有什么作用。

每次只要有请求进入 Tomcat 服务器, Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。
然后传递到 service 方法( doGet doPost )中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的
信息。
 
b)HttpServletRequest 类的常用方法
i. getRequestURI()        获取请求的资源路径
ii. getRequestURL()      获取请求的统一资源定位符(绝对路径)
iii. getRemoteHost()      获取客户端的 ip 地址
iv. getHeader()              获取请求头
v. getParameter()          获取请求的参数
vi. getParameterValues()        获取请求的参数(多个值的时候使用)
vii. getMethod()                       获取请求的方式 GET POST
viii. setAttribute(key, value);    设置域数据
ix. getAttribute(key);                获取域数据
x. getRequestDispatcher()      获取请求转发对象

 

常用 API 示例代码:
package com.atguigu.servlet;

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

public class RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        i. getRequestURI()        获取请求的资源路径
        System.out.println("URI"+req.getRequestURI());
//        ii. getRequestURL()      获取请求的统一资源定位符(绝对路径)
        System.out.println("URL"+req.getRequestURL());
//        iii. getRemoteHost()      获取客户端的 ip 地址
        /*** 在 IDEA 中,使用 localhost 访问时,得到的客户端 ip 地址是 ===>>> 127.0.0.1<br/>
         * * 在 IDEA 中,使用 127.0.0.1 访问时,得到的客户端 ip 地址是 ===>>> 127.0.0.1<br/>
         * * 在 IDEA 中,使用 真实 ip 访问时,得到的客户端 ip 地址是 ===>>> 真实的客户端 ip 地址<br/>
         * */
        System.out.println("客户端ip地址"+req.getRemoteHost());
//        iv. getHeader()              获取请求头
        System.out.println("请求头"+req.getHeader("User-Agent"));
//        vii. getMethod()                       获取请求的方式 GET 或 POST
        System.out.println("获取请求方式"+req.getMethod());
    }
}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
   
    <servlet>
        <servlet-name>RequestAPIServlet</servlet-name>
        <servlet-class>com.atguigu.servlet.RequestAPIServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RequestAPIServlet</servlet-name>
        <url-pattern>/request</url-pattern>
    </servlet-mapping>
</web-app>

输出结果:

c)如何获取请求参数

表单:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/06_servlet/parameterServlet" method="get">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    兴趣爱好:<input type="checkbox" name="hobby" value="cpp">c++
    <input type="checkbox" name="hobby" value="java">Java
    <input type="checkbox" name="hobby" value="js">javaScript<br/>
    <input type="submit">
</form>
</body>
</html>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <servlet>
        <servlet-name>ParameterServlet</servlet-name>
        <servlet-class>com.atguigu.servlet.ParameterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ParameterServlet</servlet-name>
        <url-pattern>/parameterServlet</url-pattern>
    </servlet-mapping>
</web-app>

java代码:

package com.atguigu.servlet;

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

public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求参数
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        String[] hobby=req.getParameterValues("hobby");
        System.out.println("用户名:"+username+"\n"+"密码:"+password);
        System.out.println("兴趣爱好:"+ Arrays.asList(hobby));
    }
}

输出结果:

doGet 请求的中文乱码解决:

d)POST 请求的中文乱码解决

e) 请求的转发
什么是请求的转发 ?
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。
 
Servlet1 代码:
package com.atguigu.servlet;

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

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数(办事的材料)查看
       String username= req.getParameter("username");
        System.out.println("在Servlet1(柜台1)中查看参数(材料):"+username);
        //给材料盖一个章,并传递给Servlet2(柜台2)去查看
        req.setAttribute("key","柜台1的章");

        //问路,Servlet2(柜台2)怎么走
       RequestDispatcher requestDispatcher= req.getRequestDispatcher("/servlet2");
       //走向Servlet2(柜台2)
        requestDispatcher.forward(req,resp);
    }
}

Servlet2 代码:

package com.atguigu.servlet;

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

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求的参数(办事的材料)查看
        String username= req.getParameter("username");
        System.out.println("在Servlet2(柜台2)中查看参数(材料):"+username);

        //查看柜台1是否有盖章
      Object key= req.getAttribute("key");
        System.out.println("柜台1是否有章"+key);
        //处理自己的业务
        System.out.println("Servlet2处理自己的业务");
    }
}

运行项目后地址栏加入?username=zzhyttt,如下:

http://localhost:8080/06_servlet/servlet1?username=zzhyttt

运行结果:
 
f) base 标签的作用

 

g)Web 中的相对路径和绝对路径
javaWeb 中,路径分为相对路径和绝对路径两种:
相对路径是:
.                      表示当前目录
..                     表示上一级目录
资源名            表示当前目录/ 资源名
 
绝对路径:     http://ip:port/工程路径 / 资源路径
 
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。
1 、绝对路径
2 base+ 相对
 
h)web / 斜杠的不同意义
web / 斜杠 是一种绝对路径。
/ 斜杠 如果被浏览器解析,得到的地址是: http://ip:port/
< a href ="/" > 斜杠 </ a >
/ 斜杠 如果被服务器解析,得到的地址是: http://ip:port/ 工程路径
1 < url-pattern >/servlet1</ url-pattern >
2 servletContext.getRealPath(“/”);
3 request.getRequestDispatcher(“/”);
 
特殊情况: response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到 http://ip:port/

7.6HttpServletResponse

a)HttpServletResponse 类的作用
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来, Tomcat 服务器都会创建一个 Response 对象传
递给 Servlet 程序去使用。 HttpServletRequest 表示请求过来的信息, HttpServletResponse 表示所有响应的信息,
我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置
 
b) 两个输出流的说明。
字节流            getOutputStream();         常用于下载(传递二进制数据)
字符流            getWriter();                      常用于回传字符串(常用)
两个流同时只能使用一个。
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
 
 
c) 如何往客户端回传数据
要求 : 往客户端回传 字符串 数据。
 
d) 响应的乱码解决
解决响应中文乱码方案一 (不推荐使用)
解决响应中文乱码方案二 (推荐)
 
e) 请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求
重定向(因为之前的地址可能已经被废弃)。
 
请求重定向的第一种方案:
            // 设置响应状态码 302 ,表示重定向,(已搬迁)
              resp.setStatus( 302 );
            // 设置响应头,说明 新的地址在哪里
             resp.setHeader( "Location" , "http://localhost:8080" );
请求重定向的第二种方案( 推荐使用 ):
           resp.sendRedirect( "http://localhost:8080" );

8、书城第二阶段-用户注册和登录

8.1JavaEE项目的三层架构

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
web 层                com.atguigu.web/servlet/controller
service 层           com.atguigu.servic                       Service 接口包       
                           com.atguigu.service.impl             Service 接口实现类
dao 持久层         com.atguigu.dao                          Dao 接口包
                           com.atguigu.dao.impl                  Dao 接口实现类
实体 bean 对象       com.atguigu.pojo/entity/domain/bean           JavaBean 类
测试包                com.atguigu.test/junit
工具类                com.atguigu.utils
 
搭建书城项目开发环境:
 
 

8.2先创建书城需要的数据库和表。

DROP DATABASE if EXISTS book;
CREATE DATABASE book;
use book;
CREATE TABLE t_user(
id INT PRIMARY KEY auto_increment,
username VARCHAR(20) not null UNIQUE,
`password` VARCHAR(32) NOT NULL,
email VARCHAR(200)
);
INSERT into t_user(`username`,`password`,`email`) VALUES ('admin','admin','admin@yun.com');
SELECT * FROM t_user;

8.3编写数据库表对应的 JavaBean 对象。

public class User { 
private Integer id; 
private String username;
 private String password; 
private String email;
无参构造;
有参构造;
get(){};
set(){};
toString(){};
}

8.4编写工具类 JdbcUtils

1 、导入需要的 jar 包(数据库和连接池需要):
druid-1.1.9.jar
mysql-connector-java-5.1.7-bin.jar
 
以下是测试需要:
hamcrest-core-1.3.jar
junit-4.12.jar
 
2 、在 src 源码目录下编写 druid .properties 属性配置文件:
username=root
password=root
url=jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
driverClassName=com.mysql.cj.jdbc.Driver

initialSize=10
maxActive=10
3 、编写 JdbcUtils 工具类:
package com.atyun.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class JdbcUtils {
    private static DataSource source;


    static {
        try {
            //读取druid.properties配置文件
            InputStream is= JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties ps=new Properties();
            ps.load(is);//从流中加载数据
            DataSource source=DruidDataSourceFactory.createDataSource(ps);//创建数据库连接池

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /*
    获取数据库连接池中的连接
     */
    public static Connection getConnection(){
        Connection conn=null;
       try {
           conn= source.getConnection();

       }catch (Exception e){
           e.printStackTrace();
       }
        return conn;
    }

    /*
    关闭连接,放回数据库连接池
     */
    public static void closeConnection(Connection conn){
        try {
            if (conn!=null){
                conn.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
4 JdbcUtils 测试
package com.atyun.test;

import com.atyun.utils.JdbcUtils;
import org.junit.Test;

public class JdbcUtilsTest {
    @Test
    public void testJdbcUtils(){
        System.out.println(JdbcUtils.getConnection());
    }
}

8.5编写 BaseDao

1、导入 DBUtils jar

commons-dbutils-1.3.jar

2、编写 BaseDao

package com.atyun.dao.impl;

import com.atyun.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public abstract class BaseDao {
    QueryRunner runner=new QueryRunner();
    private Connection conn;

    /*
    update方法用来执行insert/update/delete
    return语句:如果反回-1表示执行失败,反回其它表示影响的行数
     */
    public int update(String sql,Object...args){
        try {
            Connection conn=JdbcUtils.getConnection();
            //使用dbUtils操作数据库
           return runner.update(conn,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return -1;
    }

    /*
    查找反回一个javaBean的sql语句
    type:反回的对象类型
    sql:执行的sql语句
    args:sql对应的参数值
    <T>:反回的类型的泛型
     */
    public <T> T queryForOne(Class<T> type,String sql,Object...args)  {
        try {
            Connection conn=JdbcUtils.getConnection();
            return runner.query(conn,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return null;
    }
    /*
        查找反回多个javaBean的sql语句
        type:反回的对象类型
        sql:执行的sql语句
        args:sql对应的参数值
        <T>:反回的类型的泛型
         */
    public <T> List<T> queryForList(Class<T> type, String sql, Object...args){
        try {
            Connection conn=JdbcUtils.getConnection();
            return runner.query(conn,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return null;
    }
/*
执行反回一行一列的语句
sql:sql语句
args:sql语句的填充占位符
 */
    public  Object queryForSingleValue(String sql,Object...args){
        try {
            Connection conn= JdbcUtils.getConnection();
           return runner.query(conn,sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return null;
    }

}

8.6编写 UserDao 和测试

UserDao 接口:

package com.atyun.dao;

import com.atyun.pojo.User;

public interface UserDao {

    //根据用户名查询用户信息
    //如果反回为null,说明没有这个用户,反之亦然
    public User queryUserByName(String username);

    //根据用户和密码查询用户信息
    //如果反回null,说明用户名或者密码错误
    public User queryUserByUsernameAndPassword(String username,String password);

    //保存用户信息
    public int saveUser(User user);

}
UserDaoImpl 实现类:
package com.atyun.dao.impl;

import com.atyun.dao.UserDao;
import com.atyun.pojo.User;

public class UserDaoImpl extends BaseDao implements UserDao {
    @Override
    public User queryUserByName(String username) {
        String sql="select * from t_user where username=?";
        return queryForOne(User.class,sql,username);
    }

    @Override
    public User queryUserByUsernameAndPassword(String username, String password) {
        String sql="select * from t_user where username=? and password=?";
        return queryForOne(User.class,sql,username,password);
    }

    @Override
    public int saveUser(User user) {
        String sql="insert into t_user(username,password,email) values(?,?,?)";
       return update(sql,user.getUsername(),user.getPassword(),user.getEmail());
    }
}
UserDao 测试:
package com.atyun.test;

import com.atyun.dao.UserDao;
import com.atyun.dao.impl.UserDaoImpl;
import com.atyun.pojo.User;
import org.junit.Test;

import static org.junit.Assert.*;

public class UserDaoTest {
    UserDao userDao=new UserDaoImpl();
    @Test
    public void queryUserByName() {
        if(userDao.queryUserByName("admin11")==null){
            System.out.println("用户名可用");
        }else {
            System.out.println("用户名不可用");
        }
    }

    @Test
    public void queryUserByUsernameAndPassword() {
      if(userDao.queryUserByUsernameAndPassword("admin","admin")==null){
          System.out.println("用户名或者密码错误,登录失败");
      }else {
          System.out.println("查询成功");
      }
    }

    @Test
    public void saveUser() {
        System.out.println(userDao.saveUser(new User(null,"admin1","123454","sse234@qq.com")));
    }
}

8.7编写 UserService 和测试

UserService 接口:
package com.atyun.service;

import com.atyun.pojo.User;

public interface UserService {

    public void registUser(User user);//注册用户
    public User login(User user);//登录
    public boolean existsUsername(String username);//检查用户名是否存在,反回true表示用户名存在,反回false表示用户名可用
}
UserServiceImpl 实现类:
package com.atyun.service.impl;

import com.atyun.dao.UserDao;
import com.atyun.dao.impl.UserDaoImpl;
import com.atyun.pojo.User;
import com.atyun.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao=new UserDaoImpl();
    @Override
    public void registUser(User user) {
        userDao.saveUser(user);
    }

    @Override
    public User login(User user) {
      return userDao.queryUserByUsernameAndPassword(user.getUsername(),user.getPassword());
    }

    @Override
    public boolean existsUsername(String username) {
       if(userDao.queryUserByName(username)==null){
           return false;
       }
       return true;
    }
}
UserService 测试:
package com.atyun.test;

import com.atyun.pojo.User;
import com.atyun.service.UserService;
import com.atyun.service.impl.UserServiceImpl;
import org.junit.Test;

import static org.junit.Assert.*;

public class UserServiceTest {
UserService userService=new UserServiceImpl();
    @Test
    public void registUser() {
        userService.registUser(new User(null,"bpoip","60066","iir@qq.com"));
    }

    @Test
    public void login() {
        System.out.println(userService.login(new User(null,"yy","888",null)));
    }

    @Test
    public void existsUsername() {
        if (userService.existsUsername("admin")){
            System.out.println("用户名已经存在");
        }else {
            System.out.println("用户名可用");
        }
    }
}

8.8编写 web

8.8.1实现用户注册的功能

1.1图解用户注册的流程:
1.2 修改 regist.html regist_success.html 页面
1 、添加 base 标签
<!-- base 标签,永远固定相对路径跳转的结果 -->
< base href ="http://localhost:8080/book/" >
2 、修改 base 标签对页面中所有相对路径的影响(浏览器 F12 ,哪个报红,改哪个)
以下是几个修改的示例:
< link type ="text/css" rel ="stylesheet" href ="static/css/style.css" >
< script type ="text/javascript" src ="static/script/jquery-1.7.2.js" ></ script >
3 、修改注册表单的提交地址和请求方式
1.3 、编写 RegistServlet 程序
package com.atyun.web;

import com.atyun.pojo.User;
import com.atyun.service.UserService;
import com.atyun.service.impl.UserServiceImpl;

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

public class RegistServlet extends HttpServlet {
    private UserService userService=new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1获取请求的参数
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        String email=req.getParameter("email");
        String code=req.getParameter("code");
        //2检查验证码是否正确。。。。写死,要求验证码为abcde
        if ("abcde".equalsIgnoreCase(code)){
            if(userService.existsUsername(username)){
                //不可用,跳回注册页面
                System.out.println("用户名["+username+"]不可用");
                req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
            }else {
                //可用,保存用户信息到数据库,跳到注册成功页面
                userService.registUser(new User(null,username,password,email));
                req.getRequestDispatcher("/pages/user/regist_success.html").forward(req,resp);
            }
        }else {
            System.out.println("验证码["+code+"]错误");
            req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
        }
    }
}

8.8.2IDEA Debug 调试的使用

1.1 Debug 调试代码,首先需要两个元素:断点 + Debug 启动服务器
1 、断点,只需要在代码需要停的行的左边上单击,就可以添加和取消
2 Debug 启动 Tomcat 运行代码:
1.2 测试工具栏:

  

     让代码往下执行一行。

     可以进入当前方法体内(自己写的代码,非框架源码)

      跳出当前方法体外

      强制进入当前方法体内

     停在光标所在行(相当于临时断点)

1.3 变量窗口
变量窗口:它可以查看当前方法范围内所有有效的变量。
1.4 方法调用栈窗口
1 、方法调用栈可以查看当前线程有哪些方法调用信息
2 、下面的调用上一行的方法
其他常用调试相关按钮:
 

8.9用户登录功能的实现

1 、图解用户登录
2 、修改 login.html 页面和 login_success.html 页面
 
1 、添加 base 标签
<!-- base 标签,永远固定相对路径跳转的结果 -->
< base href ="http://localhost:8080/book/" >
2 、修改 base 标签对页面中所有相对路径的影响(浏览器 F12 ,哪个报红,改哪个)
以下是几个修改的示例:
< link type ="text/css" rel ="stylesheet" href ="static/css/style.css" >
< script type ="text/javascript" src ="static/script/jquery-1.7.2.js" ></ script >
3 、修改 login.html 表单的提交地址和请求方式
3 LoginServlet 程序
package com.atyun.web;

import com.atyun.pojo.User;
import com.atyun.service.UserService;
import com.atyun.service.impl.UserServiceImpl;

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

public class LoginServlet extends HttpServlet {
    UserService userService=new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1获取请求参数
       String username= req.getParameter("username");
       String password=req.getParameter("password");
       //2调用uerService处理业务
      User loginUser=  userService.login(new User(null,username,password,null));
      //如果等于null说明登录失败
        if (loginUser==null){
            //跳到登录页面
            System.out.println("用户名或密码错误,登录失败");
            req.getRequestDispatcher("/pages/user/login.html").forward(req,resp);
        }else {
            //登录成功跳到成功页面
            req.getRequestDispatcher("/pages/user/login_success.html").forward(req,resp);
        }
    }
}
2. 项目阶段二:用户注册和登陆的实现。
需求 1 :用户注册
需求如下:
1 )访问注册页面
2 )填写注册信息,提交给服务器
3 )服务器应该保存用户
4 )当用户已经存在 ---- 提示用户注册 失败,用户名已存在
5 )当用户不存在 ----- 注册成功
需求 2 :用户登陆
需求如下:
1 )访问登陆页面
2 )填写用户名密码后提交
3 )服务器判断用户是否存在
4 )如果登陆失败 --->>>> 返回用户名或者密码错误信息
5 )如果登录成功 --->>>> 返回登陆成功 信息

9、jsp

9.1jsp概述

1、什么是jsp,它有什么作用?

jsp的全称是java serverpages.java的服务器页面

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

因为Servlet程序回传html页面数据是一件非常繁琐的事情。开发成本和维护成本都较高

Servlet 回传 html 页面数据的代码:
public class PringHtml extends HttpServlet {
 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 // 通过响应的回传流回传 html 页面数据
 resp.setContentType("text/html; charset=UTF-8");
 PrintWriter writer = resp.getWriter();
writer.write("<!DOCTYPE html>\r\n"); 
writer.write(" <html lang=\"en\">\r\n");
 writer.write(" <head>\r\n"); 
writer.write(" <meta charset=\"UTF-8\">\r\n");
 writer.write(" <title>Title</title>\r\n"); 
writer.write(" </head>\r\n");
 writer.write(" <body>\r\n"); 
writer.write(" 这是 html 页面数据 \r\n"); 
writer.write(" </body>\r\n"); 
writer.write("</html>\r\n"); 
writer.write("\r\n"); } }
jsp 回传一个简单 html 页面的代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head> 
<title>Title</title>
 </head> 
<body>
 这是 html 页面数据 
</body> 
</html>
jsp 的小结:
     1 、如何创建 jsp 的页面 ?
输入文件名敲回车即可!!
2 jsp 如何访问:
jsp 页面和 html 页面一样,都是存放在 web 目录下。访问也跟访问 html 页面一样。
比如在 web 目录下有如下的文件:
web 目录
a.html 页面       访问地址是 =======>>>>>> http://ip:port/ 工程路径 /a.html
b.jsp 页面         访问地址是 =======>>>>>> http://ip:port/ 工程路径 /b.jsp
2.jsp 的本质是什么。
jsp 页面本质上是一个 Servlet 程序。
当我们第一次访问 jsp 页面的时候。 Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成
.class 字节码程序。我们打开 java 源文件不难发现其里面的内容是:
总结:通过翻译的 java 源代码我们就可以得到结果: jsp 就是 Servlet 程序。
大家也可以去观察翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传
给客户端。
 

9.2jsp 的三种语法

a)jsp 头部的 page 指令
jsp page 指令可以修改 jsp 页面中一些重要的属性,或者行为。
<%@ page contentType =" text/html;charset=UTF-8 " language =" java " %>
i.
language 属性                      表示 jsp 翻译后是什么语言文件。暂时只支持 java
ii. contentType 属性             表示 jsp 返回的数据类型是什么。也是源码中 response.setContentType() 参数值
iii. pageEncoding 属性         表示当前 jsp 页面文件本身的字符集。
iv. import 属性                      跟 java 源代码中一样。用于导包,导类。
======================== 两个属性是给 out 输出流使用 =============================
v. autoFlush 属性      设置当 out 输出流缓冲区满了之后,是否自动刷新冲级区。默认值是 true
vi. buffer 属性             设置 out 缓冲区的大小。默认是 8kb
======================== 两个属性是给 out 输出流使用 =============================
vii. errorPage 属性       设置当 jsp 页面运行时出错,自动跳转去的错误页面路径。
<!--
errorPage 表示错误后自动跳转去的路径 <br/>
这个路径一般都是以斜杠打头,它表示请求地址为 http://ip:port/ 工程路径 / 映射到代码的 Web 目录
-->
viii. isErrorPage 属性     设置当前 jsp 页面是否是错误信息页面。默认是 false 。如果是 true 可以 获取异常信息。
ix. session 属性             设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true
x. extends 属性              设置 jsp 翻译出来的 java 类默认继承谁。
b)jsp 中的常用脚本
 
i. 声明脚本 ( 极少使用 )
 
声明脚本的格式是: <%! 声明 java 代码 %>
作用:可以给 jsp 翻译出来的 java 类定义属性和方法甚至是静态代码块。内部类等。
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: 周红运
  Date: 2021/2/27
  Time: 21:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--练习:1、声明类属性 2、声明 static 静态代码块 3、声明类方法 4、声明内部类--%>

<%--1、声明类属性--%>
<%! 
    private  Integer id;
    private String name;
    private static Map<String,Object> map;
%>
<%--2、声明 static 静态代码块--%>
<%!
    static {
        map=new HashMap<String,Object>();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
    }
%>
<%--3、声明类方法--%>
<%!
    public int abc(){
        return 12;
    }
%>
<%--4、声明内部类--%>
<%!
    public static class A{
        private Integer id=12;
        private String abc="abc";
    }
%>
</body>
</html>
声明脚本代码翻译对照:
ii. 表达式脚本 (常用)
表达式脚本的格式是: <%= 表达式 %>
表达式脚本的作用是:在  jsp 页面上输出数据。
 
表达式脚本的特点:
1 、所有的表达式脚本都会被翻译到 _jspService() 方法中
2 、表达式脚本都会被翻译成为 out.print() 输出到页面上
3 、由于表达式脚本翻译的内容都在 _jspService() 方法中 , 所以 _jspService() 方法中的对象都可以直接使用。
4 、表达式脚本中的表达式不能以分号结束。
 
示例代码:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: 周红运
  Date: 2021/2/27
  Time: 21:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--练习:1. 输出整型 2. 输出浮点型 3. 输出字符串 4. 输出对象--%>
<%=12%>
<%=12.12%>
<%="我是字符串"%>
<%=map%>
<%=request.getParameter("username")%>
</body>
</html>
翻译对照:
 
iii. 代码脚本
代码脚本的格式是:
<%
java 语句
%>
代码脚本的作用是:可以在 jsp 页面中,编写我们自己需要的功能(写的是 java 语句)。
 
代码脚本的特点是:
1 、代码脚本翻译之后都在 _jspService 方法中
2 、代码脚本由于翻译到 _jspService() 方法中,所以在 _jspService() 方法中的现有对象都可以直接使用。
3 、还可以由多个代码脚本块组合完成一个完整的 java 语句。
4 、代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据
 
示例代码:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: 周红运
  Date: 2021/2/27
  Time: 21:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--练习:1. 代码脚本----if 语句 2. 代码脚本----for 循环语句 3. 翻译后 java 文件中_jspService 方法内的代码都可以写--%>
<%--1. 代码脚本----if 语句--%>
<%
    int i=12;
    if (i==12){
        System.out.println("国哥好帅");
    }else {
        System.out.println("国哥又骗人了");
    }
%>
<%--2. 代码脚本----for 循环语句--%>
<%
    for (int j=0;j<10;j++){
        System.out.println(j);
    }
%>
<%--3. 翻译后 java 文件中_jspService 方法内的代码都可以写--%>
<%
   String name= request.getParameter("username");
    System.out.println("用户名的请求参数是"+name);
%>
</body>
</html>
翻译之后的对比:
c)jsp 中的三种注释
i. html 注释
<!-- 这是 html 注释 -->
html 注释会被翻译到 java 源代码中。在 _jspService 方法里,以 out.writer 输出到客户端。
ii. java 注释
<%
// 单行 java 注释
/* 多行 java 注释 */
%>
java 注释会被翻译到 java 源代码中。
iii. jsp 注释
<%-- 这是 jsp 注释 --%>
jsp 注释可以注掉, jsp 页面中所有代码。
 

9.3jsp 九大内置对象

jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面成为 Servlet 源代码后,内部提供的九大对象,叫内置对象。

9.4jsp 四大域对象

四个域对象分别是:   
pageContext             (PageContextImpl 类 )              当前 jsp 页面范围内有效
request                     (HttpServletRequest 类 ) 、       一次请求内有效
session                     (HttpSession 类 ) 、                  一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)
application                (ServletContext 类 )                  整个 web 工程范围内都有效(只要 web 工程不停止,数据都在)
域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。
虽然四个域对象都可以存取数据。在使用上它们是有优先顺序的。
四个域在使用的时候,优先顺序分别是,他们从小到大的范围的顺序。
pageContext ====>>> request ====>>> session ====>>> application
scope.jsp 页面
<%--
  Created by IntelliJ IDEA.
  User: 周红运
  Date: 2021/2/28
  Time: 14:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>scope.jsp页面</h1>
<%
    pageContext.setAttribute("key","pageContext");
    request.setAttribute("key","request");
    session.setAttribute("key","session");
    application.setAttribute("key","application");
%>
    pageContest域是否有值:<%=pageContext.getAttribute("key")%><br/>
    request域是否有值:<%=request.getAttribute("key")%><br/>
    session域是否有值:<%=session.getAttribute("key")%><br/>
    application域是否有值:<%=application.getAttribute("key")%><br/>
</body>
</html>
scope2.jsp 页面
<body> 
<h1>scope2.jsp 页面</h1> 
pageContext 域是否有值:<%=pageContext.getAttribute("key")%> <br> 
request 域是否有值:<%=request.getAttribute("key")%> <br> 
session 域是否有值:<%=session.getAttribute("key")%> <br> 
application 域是否有值:<%=application.getAttribute("key")%> <br> 
</body>

9.5jsp 中的 out 输出和 response.getWriter 输出的区

response 中表示响应,我们经常用于设置返回给客户端的内容(输出)
out 也是给用户做输出使用的。
由于 jsp 翻译之后,底层源代码都是使用 out 来进行输出,所以一般情况下。我们在 jsp 页面中统一使用 out 来进行输出。避
免打乱页面输出内容的顺序。
out.write() 输出字符串没有问题
out.print() 输出任意数据都没有问题(都转换成为字符串后调用的 write 输出)
深入源码,浅出结论:在 jsp 页面中,可以统一使用 out.print() 来进行输出

9.6jsp 的常用标签

a)jsp 静态包含
示例说明:
<%--
<%@ include file=""%> 就是静态包含
file 属性指定你要包含的 jsp 页面的路径
地址中第一个斜杠 / 表示为 http://ip:port/ 工程路径 / 映射到代码的 web 目录
静态包含的特点:
1 、静态包含不会翻译被包含的 jsp 页面。
2 、静态包含其实是把被包含的 jsp 页面的代码拷贝到包含的位置执行输出。
--%>
<%@ include file =" /include/footer.jsp "%>
b)jsp 动态包含
示例说明:
<%--
<jsp:include page=""></jsp:include>
这是动态包含
page 属性是指定你要包含的 jsp 页面的路径
动态包含也可以像静态包含一样。把被包含的内容执行输出到包含位置
动态包含的特点:
1 、动态包含会把包含的 jsp 页面也翻译成为 java 代码
2 、动态包含底层代码使用如下代码去调用被包含的 jsp 页面执行输出。
JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
3 、动态包含,还可以传递参数
--%>
< jsp :include page ="/include/footer.jsp" >
< jsp :param name ="username" value ="bbj" />
< jsp :param name ="password" value ="root" />
</ jsp :include >
动态包含的底层原理:
 
c)jsp 标签 - 转发
示例说明:
<%--
<jsp:forward page=""></jsp:forward> 是请求转发标签,它的功能就是请求转发
page 属性设置请求转发的路径
--%>
< jsp :forward page ="/scope2.jsp" ></ jsp :forward >
 

9.7jsp 的练习题

练习一:在 jsp 页面中输出九九乘法口诀表
练习二: jsp 输出一个表格,里面有 10 个学生信息。
 

9.8 Listener 监听器

1、Listener监听器它是javaweb的三大组件之一。javaweb的三大组件分别是:Servlet程序、Filter过滤器、Listener监听器。
2、Listener它是JavaEE的规范,就是接口
3、监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给用户(程序)去做一些相应的处理
 
ServletContextListener 监听器
 
ServletContextListener 它可以监听 ServletContext 对象的创建和销毁。
ServletContext 对象在 web 工程启动的时候创建,在 web 工程停止的时候销毁。
监听到创建和销毁之后都会分别调用 ServletContextListener 监听器的方法反馈。
两个方法分别是:
 
如何使用 ServletContextListener 监听器监听 ServletContext 对象。
使用步骤如下:
1 、编写一个类去实现 ServletContextListener
2 、实现其两个回调方法
3 、到 web.xml 中去配置监听器
监听器实现类:
package listener;

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

public class MyServletContextListenerImpl implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext对象被创建了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext对象被销毁了");
    }
}
web.xml 中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置监听器 -->
    <listener>
        <listener-class>listener.MyServletContextListenerImpl</listener-class>
    </listener>
</web-app>

10、EL表达式&JSTL标签库

10.1EL表达式

a) 什么是 EL 表达式, EL 表达式的作用 ?
EL 表达式的全称是: Expression
Language 。是表达式语言。
EL 表达式的什么作用: EL 表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出。
因为 EL 表达式在输出数据的时候,要比 jsp 的表达式脚本要简洁很多。
<body>
    <%
        request.setAttribute("key","值");
    %>
表达式脚本输出key的值:<%=request.getAttribute("key")%><br/>
EL表达式输出key的值:${key}
</body>

EL 表达式的格式是: ${ 表达式 }
EL 表达式在输出 null 值的时候,输出的是空串。 jsp 表达式脚本输出 null 值的时候,输出的是 null 字符串。
b)EL 表达式搜索域数据的顺序
EL 表达式主要是在 jsp 页面中输出数据。
主要是输出域对象中的数据。
当四个域中都有相同的 key 的数据的时候, EL 表达式会按照四个域的从小到大的顺序去进行搜索,找到就输出。
<%--
  Created by IntelliJ IDEA.
  User: 周红运
  Date: 2021/2/28
  Time: 19:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    //往四个域中都保存了相同的key的域
    pageContext.setAttribute("key","pageContext");
    request.setAttribute("key","request");
    session.setAttribute("key","session");
    application.setAttribute("key","application");
%>
${key}

</body>
</html>
c)EL 表达式输出 Bean 的普通属性,数组属性。 List 合属性, map 集合属性
i.
需求——输出 Person 类中普通属性,数组属性。 list 集合属性和 map 集合属性。
person类:
package com.atyun.pojo;

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


public class Person {
//    i. 需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性。
    private String name;
    private String[] phones;
    private List<String> cities;
    private Map<String,Object> map;
    private int age=18;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

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

    public String[] getPhones() {
        return phones;
    }

    public void setPhones(String[] phones) {
        this.phones = phones;
    }

    public List<String> getCities() {
        return cities;
    }

    public void setCities(List<String> cities) {
        this.cities = cities;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name=" + name +
                ", phones=" + Arrays.toString(phones) +
                ", cities=" + cities +
                ", map=" + map +
                '}';
    }

    public Person() {
    }

    public Person(String name, String[] phones, List<String> cities, Map<String, Object> map) {
        this.name = name;
        this.phones = phones;
        this.cities = cities;
        this.map = map;
    }
}

JSP代码:

<body>
<%
    Person person=new Person();
    person.setName("唐三");
    person.setPhones(new String[]{"18609876789","13455674456","18799096678"});
    List<String> cities=new ArrayList<String>();
    cities.add("北京");
    cities.add("上海");
    cities.add("深圳");
    person.setCities(cities);
    Map<String,Object> map=new HashMap<>();
    map.put("key1","value1");
    map.put("key2","value2");
    map.put("key3","value3");
    person.setMap(map);
    pageContext.setAttribute("person",person);
%>
输出Persion:${person}<br/>
输出Persion的name属性:${person.name}<br/>
输出Persion的phones数组属性值:${person.phones[0]}<br/>
输出Persion的cities集合中的元素值:${person.cities}<br/>
输出Persion的List集合中个别元素值:${person.cities[0]}<br/>
输出Persion的List集合中个别元素值:${person.cities[1]}<br/>
输出Persion的Map集合:${person.map}<br/>
输出Persion中某个key的值Map集合:${person.map.key1}<br/>
输出Persion的age属性:${person.age}<br/>
</body>
d)EL 表达式——运算
语法: ${ 运算表达式 } EL 表达式支持如下运算符:
1 )关系运算
2 )逻辑运算
3 )算数运算
 
i. empty 运算
empty 运算可以判断一个数据是否为空,如果为空,则输出 true, 不为空输出 false
以下几种情况为空:
1 、值为 null 值的时候,为空
2 、值为空串的时候,为空
3 、值是 Object 类型数组,长度为零的时候
4 list 集合,元素个数为零
5 map 集合,元素个数为零
<body>
<%
//    1、值为 null 值的时候,为空
    request.setAttribute("enptyNull",null);
//    2、值为空串的时候,为空
    request.setAttribute("emptyStr","");
//    3、值是 Object 类型数组,长度为零的时候
    request.setAttribute("emptyArr",new Object[]{});
//    4、list 集合,元素个数为零
    request.setAttribute("emptyList",new ArrayList<>());
//    5、map 集合,元素个数为零
    request.setAttribute("emptyMap",new HashMap<String,Object>());
%>
${empty enptyNull}<br/>
${empty emptyStr}<br/>
${empty emptyArr}<br/>
${empty emptyList}<br/>
${empty emptyMap}<br/>
</body>

ii. 三元运算

表达式 1 ?表达式 2 :表达式 3
如果表达式 1 的值为真,返回表达式 2 的值,如果表达式 1 的值为假,返回表达式 3 的值。 示例:
${ 12 != 12 ? " 国哥帅呆 " : " 国哥又骗人啦 " }
 
iii. “ . 点运算 和 [] 中括号运算符
. 点运算,可以输出 Bean 对象中某个属性的值。
[] 中括号运算,可以输出有序集合中某个元素的值。
并且 [] 中括号运算,还可以输出 map 集合中 key 里含有特殊字符的 key 的值。
 
<body>
<%
    Map<String,Object> map=new HashMap<String, Object>();
    map.put("a.a.a","aaavalue");
    map.put("b+b+b","bbbvalue");
    map.put("c-c-c","cccvalue");
    request.setAttribute("map",map);
%>
${map['a.a.a']}<br/>
${map['b+b+b']}<br/>
${map['c-c-c']}<br/>
</body>
e)EL 表达式的 11 个隐含对象
EL 个达式中 11 个隐含对象,是 EL 表达式中自己定义的,可以直接使用。
变量                                     类型                               作用
pageContext              PageContextImpl                  它可以获取 jsp 中的九大内置对象
pageScope                Map<String,Object>              它可以获取 pageContext 域中的数据
requestScope            Map<String,Object>             它可以获取 Request 域中的数据
sessionScope            Map<String,Object>              它可以获取 Session 域中的数据
applicationScope      Map<String,Object>               它可以获取 ServletContext 域中的数据
param                        Map<String,String>               它可以获取请求参数的值
paramValues             Map<String,String[]>              它也可以获取请求参数的值,获取多个值的时候使用。
header                      Map<String,String>                它可以获取请求头的信息
headerValues           Map<String,String[]>             它可以获取请求头的信息,它可以获取多个值的情况
cookie                      Map<String,Cookie>             它可以获取当前请求的 Cookie 信息
initParam                  Map<String,String>               它可以获取在 web.xml 中配置的 <context-param> 上下文参数

 

i. EL 获取四个特定域中的属性
pageScope ====== pageContext 域
requestScope ====== Request 域
sessionScope ======Session 域
applicationScope ====== ServletContext 域
<body> 
    <% 
    pageContext.setAttribute("key1", "pageContext1"); 
    pageContext.setAttribute("key2", "pageContext2"); 
    request.setAttribute("key2", "request"); 
    session.setAttribute("key2", "session"); 
    application.setAttribute("key2", "application"); 
    %>
${ applicationScope.key2 } 
</body>
ii. pageContext 对象的使用
1. 协议:
2. 服务器 ip
3. 服务器端口:
4. 获取工程路径:
5. 获取请求方法:
6. 获取客户端 ip 地址:
7. 获取会话的 id 编号:
<body>
1. 协议:${pageContext.request.scheme}<br/>
2. 服务器 ip:${pageContext.request.serverName}<br/>
3. 服务器端口:${pageContext.request.serverPort}<br/>
4. 获取工程路径:${pageContext.request.contextPath}<br/>
5. 获取请求方法:${pageContext.request.method}<br/>
6. 获取客户端 ip 地址:${pageContext.request.remoteHost}<br/>
7. 获取会话的 id 编号:${pageContext.session.id}<br/>
</body>

iii. EL 表达式其他隐含对象的使用
param                 Map<String,String>       它可以获取请求参数的值
paramValues      Map<String,String[]>      它也可以获取请求参数的值,获取多个值的时候使用。
示例代码:
输出请求参数 username 的值:${ param.username } <br> 
输出请求参数 password 的值:${ param.password } <br> 
输出请求参数 username 的值:${ paramValues.username[0] } <br> 
输出请求参数 hobby 的值:${ paramValues.hobby[0] } <br> 
输出请求参数 hobby 的值:${ paramValues.hobby[1] } <br>
获取所有请求参数的值:${param}<br/>
header              Map<String,String>      它可以获取请求头的信息
headerValues   Map<String,String[]>    它可以获取请求头的信息,它可以获取多个值的情况
示例代码:
输出请求头【User-Agent】的值:${ header['User-Agent'] } <br> 
输出请求头【Connection】的值:${ header.Connection } <br> 
输出请求头【User-Agent】的值:${ headerValues['User-Agent'][0] } <br>
cookie     Map<String,Cookie>       它可以获取当前请求的 Cookie 信息
获取 Cookie 的名称:${ cookie.JSESSIONID.name } <br> 
获取 Cookie 的值:${ cookie.JSESSIONID.value } <br>
initParam      Map<String,String>      它可以获取在 web.xml 中配置的 <context-param> 上下文参数
web.xml 中的配置:
<context-param> 
    <param-name>username</param-name> 
    <param-value>root</param-value> 
</context-param> 
<context-param> 
    <param-name>url</param-name> 
    <param-value>jdbc:mysql:///test</param-value> 
</context-param>
示例代码:
输出&lt;Context-param&gt;username 的值:${ initParam.username } <br> 
输出&lt;Context-param&gt;url 的值:${ initParam.url } <br>

10.2JSTL 标签库(次重点****)

JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP
签库。
EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面
变得更佳简洁。
 
JSTL 由五个不同功能的标签库组成。
jsp 标签库中使用 taglib 指令引入标签库
CORE 标签库
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
XML 标签库 <%@ taglib prefix = "x" uri = "http://java.sun.com/jsp/jstl/xml" %>
FMT 标签库
<%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
SQL 标签库
<%@ taglib prefix = "sql" uri = "http://java.sun.com/jsp/jstl/sql" %>
FUNCTIONS 标签库
<%@ taglib prefix = "fn" uri = "http://java.sun.com/jsp/jstl/functions" %>
 
f) JSTL 标签库的使用步骤
1 、先导入 jstl 标签库的 jar 包。
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
2 、第二步,使用 taglib 指令引入标签库。
<%@ taglib prefix =" c " uri =" http://java.sun.com/jsp/jstl/core " %>
g)core 核心库使用
i. <c:set /> (使用很少)
作用: set 标签可以往域中保存数据
<body>
<%--i. <c:set />(使用很少)
 作用:set 标签可以往域中保存数据
 域对象.setAttribute(key,value);
  scope 属性设置保存到哪个域
  page 表示 PageContext 域(默认值)
  request 表示 Request 域
  session 表示 Session 域
  application 表示 ServletContext 域
  var 属性设置 key 是多少
  value 属性设置值
 --%>
保存之前:${requestScope.abc}
<c:set scope="request" var="abc" value="abcValue"/>
保存之后:${requestScope.abc}
</body>

ii. <c:if />
if 标签用来做 if 判断。
<body>
<%--
ii.<c:if /> 
if 标签用来做 if 判断。 
test 属性表示判断的条件(使用 EL 表达式输出)
判断为真时输出h1中的内容,为假时就不输出
--%>
<c:if test="${12==12}"><h1>12等于12</h1></c:if>    
</body>
</html>
iii. <c:choose> <c:when> <c:otherwise> 标签
作用:多路判断。跟 switch ... case .... default 非常接近
<body>
<%-- iii.<c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch ... case .... default 非常接近
choose 标签开始选择判断 when 标签表示每一种判断情况
test 属性表示当前这种判断情况的值
otherwise 标签表示剩下的情况 
<c:choose> <c:when> <c:otherwise>标签使用时需要注意的点: 
1、标签里不能使用 html 注释,要使用 jsp 注释 
2、when 标签的父标签一定要是 choose 标签 --%>
<%
    request.setAttribute("height",178);
%>
<c:choose>
    <c:when test="${requestScope.height>190}"><h2>小巨人</h2></c:when>
    <c:when test="${requestScope.height>180}"><h2>很高</h2></c:when>
    <c:when test="${requestScope.height>170}"><h2>还可以</h2></c:when>
    <c:otherwise><h2>剩下小于170的情况</h2></c:otherwise>
</c:choose>
</body>
</html>
iv. <c:forEach />
作用:遍历输出使用。
 
1. 遍历 1 10 ,输出
<body>
<%--1.遍历 1 到 10,输出
begin 属性设置开始的索引
end 属性设置结束的索引
var 属性表示循环的变量(也是当前正在遍历到的数据) for (int i = 1; i < 10; i++)
 --%>
<c:forEach begin="1" end="10" var="i">
    ${i}
</c:forEach>
</body>
2. 遍历 Object 数组
<body>

<%-- 2.遍历 Object 数组 
for (Object item: arr) 
items 表示遍历的数据源(遍历的集合) 
var 表示当前遍历到的数据 --%>
<%
    request.setAttribute("arr",new String[]{"16878987","5567678","88976786"});
%>
<c:forEach items="${requestScope.arr}" var="item">
    ${item}
</c:forEach>
</body>
</html>
3. 遍历 Map 集合
<body>
<% Map<String,Object> map = new HashMap<String, Object>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
// for ( Map.Entry<String,Object> entry : map.entrySet()) {
// } 
request.setAttribute("map", map);
%>
<c:forEach items="${requestScope.map}" var="item">
    ${item}
    <h1>${item}</h1>
    ${item.key}=${item.value}
</c:forEach>
</body>

4. 遍历 List 集合 ---list 中存放 Student 类,有属性:编号,用户名,密码,年龄, 电话信息

Student类:

public class Student {
    private Integer id;
    private String userName;
    private String password;
    private Integer age;
    private String phone;

forEach.jsp:

<body>
<%--4.遍历 List 集合---list 中存放 Student 类,有属性:编号,用户名,密码,年龄,电话信息--%>
<%
    List<Student> student=new ArrayList<Student>();
    for (int i=0;i<10;i++){
        student.add(new Student(i,"username"+i,"pass"+i,18+i,"phone"+i));
    }
    request.setAttribute("stus",student);
%>
<c:forEach items="${requestScope.stus}" var="stu">
    ${stu}<br/>
    ${stu.id}<br/>
    ${stu.userName}<br/>
</c:forEach>
</body>

forEach标签组合使用:

<body>
<table>
<c:forEach begin="2" end="7" step="2" varStatus="status" items="${requestScope.stus}" var="stu">
    <tr>
        <td>${stu.id}</td>
        <td>${stu.username}</td>
        <td>${stu.password}</td>
        <td>${stu.age}</td>
        <td>${stu.phone}</td>
        <td>${status.step}</td>
    </tr>
</c:forEach>
</table>
</body>

11、文件的上传和下载

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

11.1文件的上传介绍(*****重点)

1 、要有一个 form 标签, method=post 请求
2 form 标签的 encType 属性值必须为 multipart/form-data
3 、在 form 标签中使用 input type=file 添加上传的文件
4 、编写服务器代码( Servlet 程序)接收,处理上传的数据。
 
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼
接,然后以二进制流的形式发送给服务器

11.2文件上传,HTTP 协议的说明。

11.3commons-fileupload.jar 常用 API 介绍说明

commons-fileupload.jar 需要依赖 commons-io.jar 这个包,所以两个包我们都要引入。
 
第一步,就是需要导入两个 jar 包:
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
 
commons-fileupload.jar commons-io.jar 包中,我们常用的类有哪些?
ServletFileUpload 类,用于解析上传的数据。
FileItem 类,表示每一个表单项。
 
boolean ServletFileUpload. isMultipartContent ( HttpServletRequest request );
判断当前上传的数据格式是否是多段的格式。
 
public List<FileItem> parseRequest(HttpServletRequest request)
解析上传的数据
 
boolean FileItem .isFormField()
判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。
true 表示普通类型的表单项
false 表示上传的文件类型
 
String FileItem .getFieldName()
获取表单项的 name 属性值
 
String FileItem .getString()
获取当前表单项的值。
 
String FileItem.getName();
获取上传的文件名
 
void FileItem.write( file );
将上传的文件写到 参数 file 所指向的硬盘位置 。

 

11.4fileupload 类库的使用:

上传文件的表单:
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/09_EL_JSTL/uploadServlet" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username"/>
        头像:<input type="file" name="photo">
        <input type="submit" value="上传">
    </form>
</body>
</html>

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>UploadServlet</servlet-name>
        <servlet-class>com.atyun.servlet.UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/uploadServlet</url-pattern>
    </servlet-mapping>
</web-app>
解析上传的数据的代码:
package com.atyun.servlet;

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

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

public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1先判断上传的数据是否为多段数据(只有是多段的数据,才是文件上传的)
       if(ServletFileUpload.isMultipartContent(req)) {
           //创建FileItemFactory工厂实现类
           FileItemFactory fileItemFactory=new DiskFileItemFactory();
           //创建用于解析上传数据的工具类 ServletFileUpload
           ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
           //解析上传的数据,得到每一个表单项
           try {
               List<FileItem> list= servletFileUpload.parseRequest(req);
               //循环判断每一个表单项,是普通类型还是上传的文件
               for (FileItem fileItem:list){
                   if (fileItem.isFormField()){
                       //普通表单项
                       System.out.println("表单项的name属性值"+fileItem.getFieldName());
                       //参数UTF-8解决乱码问题
                       System.out.println("表单项的value属性值"+fileItem.getString("UTF-8"));
                   }else {
                      //上传的文件
                       System.out.println("表单项的name属性值"+fileItem.getFieldName());
                       System.out.println("上传的文件名"+fileItem.getName());
                       fileItem.write(new File("D:\\"+fileItem.getName()));
                   }
               }
           } catch (FileUploadException e) {
               e.printStackTrace();
           } catch (Exception e) {
               e.printStackTrace();
           }
       }

    }
}

11.5文件下载

download,jsp:
package com.atyun.servlet;

import org.apache.commons.io.IOUtils;

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

public class Download extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1获取要下载的文件名
        String downloadFileName="c.jpg";
        //2读取下载文件的内容(通过ServletContext对象可以读取)
        ServletContext servletContext=getServletContext();
        //获取要下载的文件类型
        String miniType=servletContext.getMimeType("/file/"+downloadFileName);
        //4在回传前,通过响应头告诉客户端返回的数据类型
        resp.setContentType(miniType);
        //5还要告诉客户端收到的数据是用于下载使用(还是使用响应头)
        //Content.Disposition响应头,表示收到的数据怎么处理
        //attachment:表示附件,表示下载使用
        //filename:表示指定下载的文件名
        //resp.setHeader("Content-Disposition","attachment;filename="+downloadFileName);

        //自己给文件起一个名字,因为有汉字,使用url编码把汉字转换格式
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("中国.jpg","UTF-8"));

        //获取输入流
        InputStream resourceAsStream=servletContext.getResourceAsStream("/file/"+downloadFileName);
        //获取响应的输出流
        OutputStream outputStream=resp.getOutputStream();
        //3把下载的文件内容回传给客户
        //读取输入流中的全部数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream,outputStream);


    }
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>UploadServlet</servlet-name>
        <servlet-class>com.atyun.servlet.UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/uploadServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>Download</servlet-name>
        <servlet-class>com.atyun.servlet.Download</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Download</servlet-name>
        <url-pattern>/download</url-pattern>
    </servlet-mapping>
</web-app>

 

下载的常用 API 说明:
response .getOutputStream();
servletContext.getResourceAsStream();
servletContext.getMimeType();
response.setContentType();
 
response.setHeader( "Content-Disposition" , "attachment; fileName=1.jpg" );
这个响应头告诉浏览器。这是需要下载的。而 attachment 表示附件,也就是下载的一个文件。 fileName= 后面,
表示下载的文件名。
 
完成上面的两个步骤,下载文件是没问题了。但是如果我们要下载的文件是中文名的话。你会发现,下载无法正确 显示出正确的中文名。
原因是在响应头中,不能包含有中文字符,只能包含 ASCII 码。
 
附件中文名乱码问题解决方案:
方案一: URLEncoder 解决 IE 和谷歌浏览器的 附件中 文名问题
如果客户端浏览器是 IE 浏览器 或者 是谷歌浏览器。我们需要使用 URLEncoder 类先对中文名进行 UTF-8 的编码
操作。
因为 IE 浏览器和谷歌浏览器收到含有编码后的字符串后会以 UTF-8 字符集进行解码显示。
 
// 把中文名进行 UTF-8 编码操作。
String str = "attachment; fileName=" + URLEncoder. encode ( " 中文 .jpg" , "UTF-8" );
// 然后把编码后的字符串设置到响应头中
response .setHeader( "Content-Disposition" , str );
 
方案二: BASE64 编解码 解决 火狐浏览器的附件中文名问
如果客户端浏览器是火狐浏览器。 那么我们需要对中文名进行 BASE64 的编码操作。

 

这时候需要把请求头 Content-Disposition: attachment; filename= 中文名
编码成为: Content-Disposition: attachment; filename==?charset?B?xxxxx?=
 
=?charset?B?xxxxx?= 现在我们对这段内容进行一下说明。
=?             表示编码内容的开始
charset     表示字符集
B              表示BASE64编码
xxxx         表示文件名BASE64编码后的内容
?=           表示编码内容的结束
 
BASE64 编解码操作:
因为火狐使用的是 BASE64 的编解码方式还原响应中的汉字。所以需要使用 BASE64Encoder 类进行编码操作。
// 使用下面的格式进行 BASE64 编码后
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode( " 中文 .jpg" .getBytes( "utf-8" )) + "?=" ;
// 设置到响应头中
response .setHeader( "Content-Disposition" , str );

 

那么我们如何解决上面两种不同编解码方式呢。我们只需要通过判断请求头中 User-Agent 这个请求头携带过来的
浏览器信息即可判断出是什么浏览器。
如下:
String ua = request .getHeader( "User-Agent" );
// 判断是否是火狐浏览器
if ( ua .contains( "Firefox" )) {
// 使用下面的格式进行 BASE64 编码后
String str = "attachment; fileName=" + "=?utf-8?B?"
+ new BASE64Encoder().encode( " 中文 .jpg" .getBytes( "utf-8" )) + "?=" ;
// 设置到响应头中
response .setHeader( "Content-Disposition" , str );
} else {
// 把中文名进行 UTF-8 编码操作。
String str = "attachment; fileName=" + URLEncoder. encode ( " 中文 .jpg" , "UTF-8" );
// 然后把编码后的字符串设置到响应头中
response .setHeader( "Content-Disposition" , str );
}
 

12、Cookie和Session

12.1Cookie

1 Cookie 饼干
a) 什么是 Cookie?
1 Cookie 翻译过来是饼干的意思。
2 Cookie 是服务器通知客户端保存键值对的一种技术。
3 、客户端有了 Cookie 后,每次请求都发送给服务器。
4 、每个 Cookie 的大小不能超过 4kb
b) 如何创建 Cookie
Servlet 程序中的代码:
c) 服务器如何获取 Cookie
服务器获取客户端的 Cookie 只需要一行代码: req.getCookies():Cookie[]
Cookie 的工具类:

Servlet 程序中的代码:
d)Cookie 值的修改
方案一:
1 、先创建一个要修改的同名(指的就是 key )的 Cookie 对象
2 、在构造器,同时赋于新的 Cookie 值。
3 、调用 response.addCookie( Cookie );

方案二:
1 、先查找到需要修改的 Cookie 对象
2 、调用 setValue() 方法赋于新的 Cookie 值。
3 、调用 response.addCookie() 通知客户端保存修改
e) 浏览器查看 Cookie
谷歌浏览器如何查看 Cookie
火狐浏览器如何查看 Cookie
f) Cookie 生命控制
Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)
setMaxAge()
正数,表示在指定的秒数后过期
负数,表示浏览器一关, Cookie 就会被删除(默认值是 -1
零,表示马上删除 Cookie

h) Cookie 练习 --- 免输入用户名登录
login.jsp 页面
LoginServlet 程序:

12.2Session 会话

i) 什么是 Session 会话 ?
1 Session 就一个接口( HttpSession )。
2 Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。
3 、每个客户端都有自己的一个 Session 会话。
4 Session 会话中,我们经常用来保存用户登录之后的信息。
 
j) 如何创建 Session 和获取 (id , 是否为新 )
如何创建和获取 Session 。它们的 API 是一样的。
request.getSession()
第一次调用是:创建 Session 会话
之后调用都是:获取前面创建好的 Session 会话对象。
isNew(); 判断到底是不是刚创建出来的(新的)
true 表示刚创建
false 表示获取之前创建
每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。
getId() 得到 Session 的会话 id 值。
 
k)Session 域数据的存取
l) Session 生命周期控制
public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长, Session
就会被销毁。
值为正数的时候,设定 Session 的超时时长。
负数表示永不超时(极少使用)
public int getMaxInactiveInterval() 获取 Session 的超时时间
public void invalidate() 让当前 Session 会话马上超时无效。
 
Session 默认的超时时长是多少!
Session 默认的超时时间长为 30 分钟。
因为在 Tomcat 服务器的配置文件 web.xml 中默认有以下的配置,它就表示配置了当前 Tomcat 服务器下所有的 Session
超时配置默认时长为: 30 分钟。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
如果说。你希望你的 web 工程,默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做
以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长。

如果你想只修改个别 Session 的超时时长。就可以使用上面的 API setMaxInactiveInterval(int interval) 来进行单独的设置。
session.setMaxInactiveInterval(int interval) 单独设置超时时长。
Session 超时的概念介绍:

示例代码:
Session 马上被超时示例:

m) 浏览器和 Session 之间关联的技术内幕
Session 技术,底层其实是基于 Cookie 技术来实现的。

 

13、JSONAJAXi18n

13.1Json

1 、什么是 JSON?
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON
采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C, C++, C#, Java, JavaScript, Perl, Python
等)。 这样就使得 JSON 成为理想的数据交换格式。
json 是一种轻量级的数据交换格式。
轻量级指的是跟 xml 做比较。
数据交换指的是客户端和服务器之间业务数据的传递格式。
 
1.1 JSON JavaScript 中的使用。
1.1.1 json 的定义
json 是由键值对组成,并且由花括号(大括号)包围。每个键由引号引起来,键和值之间使用冒号进行分隔,
多组键值对之间进行逗号进行分隔。
json 定义示例:
// json的定义
			var jsonobj={
				"key1":12,
				"key2":"abc",
				"key3":true,
				"key4":[11,"arr",false],
				"key5":{
					"key5_1":551,
					"key5_2":"key5_2value"
				},
				"key6":[{"key6_1_1":611,"key6_1_2":"key6_1_2value"},{"key6_2_1":621,"key6_2_2":"key6_2_2value"}]
			};
			//alert(typeof (jsonobj));//object  json就是一个对象
1.1.2 json 的访问
json 本身是一个对象。
json 中的 key 我们可以理解为是对象中的一个属性。
json 中的 key 访问就跟访问对象的属性一样: json 对象 .key
json 访问示例:
// json的访问
			/*alert(jsonobj.key1);//12
			alert(jsonobj.key2);//abc
			alert(jsonobj.key3);//true
			alert(jsonobj.key4);//得到数组[11,"arr",false]*/
			/*for (var i=0;i<jsonobj.key4.length;i++){
				alert(jsonobj.key4[i]);//json中数组值的遍历
			}*/
			/*alert(jsonobj.key5.key5_1);//551
			alert(jsonobj.key5.key5_2);//key5_2value*/
			/*alert(jsonobj.key6[0].key6_1_1);//611
			alert(jsonobj.key6[0].key6_1_2);//key6_1_2value*/
1.1.3 json 的两个常用方法
json 的存在有两种形式。
一种是:对象的形式存在,我们叫它 json 对象。
一种是:字符串的形式存在,我们叫它 json 字符串。
一般我们要操作 json 中的数据的时候,需要 json 对象的格式。
一般我们要在客户端和服务器之间进行数据交换的时候,使用 json 字符串。
JSON.stringify()
json 对象转换成为 json 字符串
JSON.parse()
json 字符串转换成为 json 对象
示例代码:
// json对象转字符串
			var jsonObjString=JSON.stringify(jsonobj);
			alert(jsonObjString);

			// json字符串转json对象
			var jsonobj2=JSON.parse(jsonObjString);
			alert(jsonobj2.key1);//12
1.2 JSON java 中的使用
1.2.1 javaBean json 的互转
public class JsonTest {
  //  1.2.1 javaBean和json的互转
    @Test
    public void test1(){
      Person person=new Person(1,"唐三");
      //创建gson对象实例
      Gson gson=new Gson();
     String personJsonString= gson.toJson(person);//把javaBean对象转化为json字符串
      System.out.println(personJsonString);
      //fromJson把json字符串转换回java对象
        //第一个参数是json字符串
        //第二个参数是转换回去的java对象类型
     Person person1= gson.fromJson(personJsonString,Person.class);//把json字符串转化为javaBean对象
        System.out.println(person1);

    }
}
1.2.2 List json 的互转
package com.atyun.json;

import com.atyun.pojo.Person;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;

public class PersonListType extends TypeToken<ArrayList<Person>> {
}
public class JsonTest {

    //1.2.2  list和json的互转
    @Test
    public  void test2(){
        List<Person> personList=new ArrayList<Person>();
        personList.add(new Person(1,"国哥"));
        personList.add(new Person(2,"康师傅"));
        Gson gson=new Gson();
        String personListJsonString=gson.toJson(personList);//把list转化为json字符串
        System.out.println(personListJsonString);

       List<Person> list= gson.fromJson(personListJsonString,new PersonListType().getType());
        System.out.println(list);
       Person person= list.get(0);
        System.out.println(person);
    }
}
1.2.3 map json 的互转
package com.atyun.json;

import com.atyun.pojo.Person;
import com.google.gson.reflect.TypeToken;

import java.util.HashMap;

public class PersonMapType extends TypeToken<HashMap<Integer, Person>> {
}
public class JsonTest {
    //1.2.3  map和json的互转
    @Test
    public void Test3(){
        Map<Integer,Person> personMap=new HashMap<Integer,Person>();
        personMap.put(1,new Person(1,"国哥"));
        personMap.put(2,new Person(2,"康师傅"));
        Gson gson=new Gson();
        //把map集合转化为json字符串
       String personMapJsonString= gson.toJson(personMap);
        System.out.println(personMapJsonString);

       //Map<Integer,Person> personMap1= gson.fromJson(personMapJsonString,new PersonMapType().getType());
        //转换为使用匿名内部类,方便简洁
        Map<Integer,Person> personMap1= gson.fromJson(personMapJsonString,new TypeToken<HashMap<Integer,Person>>(){}.getType());
        System.out.println(personMap1);
      Person person=  personMap1.get(1);
        System.out.println(person);
    }

}

13.2AJAX 请求

2 AJAX 请求
2.1 、什么是 AJAX 请求
AJAX 即“ A synchronous J avascript A nd X ML (异步 JavaScript XML ),是指一种创建交互式 网页 应用的网页开发
技术。
ajax 是一种浏览器通过 js 异步发起请求,局部更新页面的技术。
Ajax 请求的局部更新,浏览器地址栏不会发生变化
局部更新不会舍弃原来页面的内容
2.2 、原生 AJAX 请求的示例:
 

2.3 jQuery 中的 AJAX 请求
 
 
 

13.3i18n 国际化(了解内容)

 
 
 
 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值