目录
3.6.2函数的arguments隐形参数(只在function函数内)
9.5jsp 中的 out 输出和 response.getWriter 输出的区别
11.3commons-fileupload.jar 常用 API 介绍说明
1、HTML
1.1idea创建HTML文件
- 创建一个web工程(静态的web工程):file-->new-->project-->static web-->next-->设置project name和project location-->finish
- 在工程下创建html页面:点击工程名右键-->new-->HTML File-->设置html文件名-->Enter
- 运行:右键-->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 --> 我是<br>标签<!--输出我是<br>标签字样--> 我是 空格
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>
这种方法的缺点:
- 如果标签多了,样式多了,代码量非常庞大
- 可读性非常差
- 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的注释*/
这种方式的缺点:
- 只能在同一页面内复用代码,不能在多个页面中复用css代码
- 维护起来不方便,实际的项目中会有成千上万的页面,要到每个页面中去修改,工作量太大了
第三种:使用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是强类型。
特点:
- 交互性(它可以做的就是信息的动态交换)
- 安全性(不允许直接访问本地硬盘)
- 跨平台性(只要是可以解析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>
常见问题:
- 使用jQuery一定要引入jQuery库吗? 是,一定
- jQuery中的$到底是什么? 它是一个函数
- 怎么为按钮添加点击响应函数的? 使用jQuery查询到标签对象,使用标签对象.click(function(){});
4.2jQuery核心函数
$是jQuery的核心函数,能完成jQuery的很多功能,$()就是调用$这个函数
- 传入参数为【函数】时:表示页面加载完成之后,相当于window.οnlοad=function(){};
- 传入的参数为【html字符串】时:会帮我们创建这个html标签对象
- 传入参数为【选择器字符串】时:$("#id属性值");->id选择器,根据id查询标签对象 $("标签名");->标签名选择器,根据指定的标签名查询标签对象 $(".class属性值");->类型选择器,可以根据class属性查询标签对象
- 传入参数为【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> </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(){};的区别
他们分别是在什么时候触发?
- jQuery的页面加载完成之后是浏览器的内核解析完页面的标签创建好DOM对象之后就是马上执行
- 原生js的页面加载完成之后,除了要等浏览器内核解析完标签创建好DOM对象,还要等标签显示时需要的内容加载完成
他们触发的顺序?
- jQuery页面加载完成之后先执行
- 原生js的页面加载完成之后
他们执行的次数?
- 原生js的页面加载完成之后,只会执行最后一次的赋值函数
- 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的主要作用有:
- 用来保存数据,而且这些数据具有自我描述性
- 它还可以作为项目或者模块的配置文件
- 它还可以作为网络传输数据的格式(现在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\下,创建如下的配置文件
<!-- Context 表示一个工程上下文path 表示工程的访问路径 :/abcdocBase 表示你的工程目录在哪里--><Context path="/abc" docBase="E:\book" />
g)手托html页面到浏览器和在浏览器中输入http://ip:端口号/工程名/访问的区别
h)ROOT的工程访问,以及默认index.html页面的访问
6.6IDEA整合Tomcat服务器
6.7IDEA中动态web工程的操作
方法一:将jar包复制到lib文件夹->右键jar包->Add as Library...
方法二:
7、Servlet
7.1Servlet技术
a)什么是Servlet技术
- Servlet是JavaEE规范之一,规范就是接口
- Servlet是javaWeb三大组件之一,三大组件分别是:Servlet程序、Filter过滤器、Listener监听器
- Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送过来的请求,并响应数据给客户端
b)手动实现Servlet程序
- 编写一个类去实现Servlet接口
- 实现service方法,处理请求,并响应数据
- 到web.xml中去配置servlet程序的访问地址
- 在浏览器中运行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>
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 请求");
} }
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方法");
}
}
<?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>
72.ServletConfig类
ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类
Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用
a)ServletConfig类的三大作用
- 可以获取Servlet程序的别名servlet-name的值
- 获取初始化参数init.param
- 获取ServletConfig对象
<?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>
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?
- ServletContext是一个接口,它表示Servelet上下文对象
- 一个web工程,只有一个ServletContext对象实例
- ServletContext对象是一个域对象
什么是域对象:
域对象是可以像Map一样存取数据的对象,叫域对象,这里的域指的是存取数据的操作范围,整个web工程。
存数据 取数据 删除数据
Map put () get () remove()
域对象 putAttribute() getAttribute() removeAttribute()
b)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 一样存取数据
}
}
<!--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>
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 协议
什么是协议 ?协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。HTTP 协议中的数据又叫报文。
常见的 MIME 类型:
7.5.HttpServletRequest 类
a)HttpServletRequest 类有什么作用。
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 请求的中文乱码解决
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,如下:
7.6HttpServletResponse 类
8、书城第二阶段-用户注册和登录
8.1JavaEE项目的三层架构
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
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
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();
}
}
}
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);
}
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());
}
}
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 和测试
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表示用户名可用
}
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;
}
}
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实现用户注册的功能
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 调试的使用
让代码往下执行一行。
可以进入当前方法体内(自己写的代码,非框架源码)
跳出当前方法体外
强制进入当前方法体内
停在光标所在行(相当于临时断点)
8.9用户登录功能的实现
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);
}
}
}
9、jsp
9.1jsp概述
1、什么是jsp,它有什么作用?
jsp的全称是java serverpages.java的服务器页面
jsp的主要作用是代替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"); } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是 html 页面数据
</body>
</html>
9.2jsp 的三种语法
<%@ 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>
<%@ 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>
<%@ 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>
<!-- 这是 html 注释 -->
<%// 单行 java 注释/* 多行 java 注释 */%>
<%-- 这是 jsp 注释 --%>
9.3jsp 九大内置对象
jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面成为 Servlet 源代码后,内部提供的九大对象,叫内置对象。
9.4jsp 四大域对象
<%--
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>
<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 输出的区别
9.6jsp 的常用标签
9.7jsp 的练习题
9.8 Listener 监听器
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对象被销毁了");
}
}
<?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表达式
<body>
<%
request.setAttribute("key","值");
%>
表达式脚本输出key的值:<%=request.getAttribute("key")%><br/>
EL表达式输出key的值:${key}
</body>
<%--
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>
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>
<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. 三元运算
<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>
<body>
<%
pageContext.setAttribute("key1", "pageContext1");
pageContext.setAttribute("key2", "pageContext2");
request.setAttribute("key2", "request");
session.setAttribute("key2", "session");
application.setAttribute("key2", "application");
%>
${ applicationScope.key2 }
</body>
<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>
输出请求参数 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/>
输出请求头【User-Agent】的值:${ header['User-Agent'] } <br>
输出请求头【Connection】的值:${ header.Connection } <br>
输出请求头【User-Agent】的值:${ headerValues['User-Agent'][0] } <br>
获取 Cookie 的名称:${ cookie.JSESSIONID.name } <br>
获取 Cookie 的值:${ cookie.JSESSIONID.value } <br>
<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>
输出<Context-param>username 的值:${ initParam.username } <br>
输出<Context-param>url 的值:${ initParam.url } <br>
10.2JSTL 标签库(次重点****)
<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>
<body>
<%--
ii.<c:if />
if 标签用来做 if 判断。
test 属性表示判断的条件(使用 EL 表达式输出)
判断为真时输出h1中的内容,为假时就不输出
--%>
<c:if test="${12==12}"><h1>12等于12</h1></c:if>
</body>
</html>
<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>
<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>
<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>
<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>
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、文件的上传和下载
11.1文件的上传介绍(*****重点)
11.2文件上传,HTTP 协议的说明。
11.3commons-fileupload.jar 常用 API 介绍说明
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文件下载
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>
12、Cookie和Session
12.1Cookie
12.2Session 会话
13、JSON、AJAX、i18n
13.1Json
// 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就是一个对象
// 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*/
// json对象转字符串
var jsonObjString=JSON.stringify(jsonobj);
alert(jsonObjString);
// json字符串转json对象
var jsonobj2=JSON.parse(jsonObjString);
alert(jsonobj2.key1);//12
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);
}
}
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);
}
}
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 请求
13.3i18n 国际化(了解内容)