Java Web
HTML Hyper Text Markup Language (超文本标记语言) 简写: HTML HTML 通过标签来标记要显示的网页中的各个部分。 网页文件本身是一种文本文件, 通过在文本文件中添加标记符, 可以告诉浏览器如何显示其中的内容(如: 文字如何处理, 画 面如何安排, 图片如何显示等)
HTML 的书写规范
1 2 3 4 5 6 7 8 9 10 <!DOCTYPEhtml> <html lang ="en" > <head > <meta charset ="UTF-8" > <title > 标题</title > </head > <body > 页面主体内容 </body > </html >
HTML 标签介绍
标签的格式 <标签名>封装的数据</标签名>
注意事项
标签名大小写不敏感
标签拥有自己的属性
基本属性 :bgcolor="red"
可以修改简单的样式效果
事件属性 :onclick="alert('你好');"
可以直接设置事件响应后的代码
标签又分为单标签和双标签
单标签格式 : <标签名/>
<br/>
<hr/>
双标签格式 :<标签名>...封装的数据...</标签名>
标签的语法
标签不能嵌套
正确:<div><span>早安, 尚硅谷</span></div>
错误:<div><span>早安, 尚硅谷</div></span>
标签必须正确关闭
有文本内容的标签
正确:<div>早安, 尚硅谷</div>
错误: <div>早安, 尚硅谷
没有文本内容的标签
属性必须有值,属性值必须加 “ “
正确:<font color="blue">早安, 尚硅谷</font>
错误:<font color=blue>早安, 尚硅谷</font>
错误:<font color>早安, 尚硅谷</font>
注释不能嵌套
HTML 代码不是很严谨。有时候标签不闭合也不会报错
常用标签介绍
文档: w3cschool.CHM
front 标签 需求1:在网页上显示我是字体标签,并修改字体为 宋体,颜色为红色
1 2 3 4 5 6 7 8 9 10 <body > <font color ="red" face ="宋体" size ="7" > 我是字体标签</font > </body >
特殊字符
需求1:把 <br />
换行标签变成文本 转换成字符显示在页面上
常用特殊字符表
其他特殊字符表
1 2 3 4 5 6 7 8 9 10 11 12 <body > 我是< br> 标签<br /> 国哥好 </body >
标题标签
标题标签是 h1 到 h6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <body > <h1 align ="left" > 标题 1</h1 > <h2 align ="center" > 标题 2</h2 > <h3 align ="right" > 标题 3</h3 > <h4 > 标题 4</h4 > <h5 > 标题 5</h5 > <h6 > 标题 6</h6 > <h7 > 标题 7</h7 > </body >
超链接
在网页中所有点击之后可以跳转的内容都是超链接
普通的超链接 1 2 3 4 5 6 7 8 9 10 11 12 <body > <a href ="http://localhost:8080" > 百度</a > <br /> <a href ="http://localhost:8080" target ="_self" > 百度_self</a > <br /> <a href ="http://localhost:8080" target ="_blank" > 百度_blank</a > <br /> </body >
列表标签
无序列表、有序列表
无序列表 需求1:使用无序, 列表方式, 把东北 F4, 赵四, 刘能, 小沈阳, 宋小宝, 展示出来
1 2 3 4 5 6 7 8 9 10 11 12 13 <body > <ul type ="none" > <li > 赵四</li > <li > 刘能</li > <li > 小沈阳</li > <li > 宋小宝</li > </ul > </body >
img 标签
img 标签可以在 html 页面上显示图片
需求1:使用 img 标签显示一张美女的照片。 并修改宽高, 和边框属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <body > <img src ="1.jpg" width ="200" height ="260" border ="1" alt ="美女找不到" /> <img src ="../2.jpg" width ="200" height ="260" /> <img src ="../imgs/3.jpg" width ="200" height ="260" /> <img src ="../imgs/4.jpg" width ="200" height ="260" /> <img src ="../imgs/5.jpg" width ="200" height ="260" /> <img src ="../imgs/6.jpg" width ="200" height ="260" /> </body >
表格标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <body > <table align ="center" border ="1" width ="300" height ="300" cellspacing ="0" > <tr > <th > 1.1</th > <th > 1.2</th > <th > 1.3</th > </tr > <tr > <td > 2.1</td > <td > 2.2</td > <td > 2.3</td > </tr > <tr > <td > 3.1</td > <td > 3.2</td > <td > 3.3</td > </tr > </table > </body >
表格的跨行跨列 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <body > <table width ="500" height ="500" cellspacing ="0" border ="1" > <tr > <td colspan ="2" > 1.1</td > <td > 1.3</td > <td > 1.4</td > <td > 1.5</td > </tr > <tr > <td rowspan ="2" > 2.1</td > <td > 2.2</td > <td > 2.3</td > <td > 2.4</td > <td > 2.5</td > </tr > <tr > <td > 3.2</td > <td > 3.3</td > <td > 3.4</td > <td > 3.5</td > </tr > <tr > <td > 4.1</td > <td > 4.2</td > <td > 4.3</td > <td colspan ="2" rowspan ="2" > 4.4</td > </tr > <tr > <td > 5.1</td > <td > 5.2</td > <td > 5.3</td > </tr > </table > </body >
iframe 框架
ifarme 标签它可以在一个 html 页面上,打开一个小窗口,去加载一个单独的页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > 我是一个单独的完整的页面 <br /> <br /> <iframe src ="3.标题标签.html" width ="500" height ="400" name ="abc" > </iframe > <br /> <ul > <li > <a href ="0-标签语法.html" target ="abc" > 0-标签语法.html</a > </li > <li > <a href ="1.font 标签.html" target ="abc" > 1.font 标签.html</a > </li > <li > <a href ="2.特殊字符.html" target ="abc" > 2.特殊字符.html</a > </li > </ul > </body >
表单标签
表单就是 html 页面中,用来收集用户信息的所有元素集合.然后把这些信息发送给服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <body > <form > 用户名称: <input type ="text" value ="默认值" /> <br /> 用户密码: <input type ="password" value ="abc" /> <br /> 确认密码: <input type ="password" value ="abc" /> <br /> 性别: <input type ="radio" name ="sex" /> 男<input type ="radio" name ="sex" checked ="checked" /> 女<br /> 兴趣爱好: <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 /> <input type ="reset" value ="abc" /> <input type ="submit" /> </form > </body >
表单的格式化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <form > <h1 align ="center" > 用户注册</h1 > <table align ="center" > <tr > <td > 用户名称: </td > <td > <input type ="text" value ="默认值" /> </td > </tr > <tr > <td > 用户密码: </td > <td > <input type ="password" value ="abc" /> </td > </tr > <tr > <td > 确认密码: </td > <td > <input type ="password" value ="abc" /> </td > </tr > <tr > <td > 性别: </td > <td > <input type ="radio" name ="sex" /> 男 <input type ="radio" name ="sex" checked ="checked" /> 女 </td > </tr > <tr > <td > 兴趣爱好: </td > <td > <input type ="checkbox" checked ="checked" /> Java <input type ="checkbox" /> JavaScript <input type ="checkbox" /> C++ </td > </tr > <tr > <td > 国籍: </td > <td > <select > <option > --请选择国籍--</option > <option selected ="selected" > 中国</option > <option > 美国</option > <option > 小日本</option > </select > </td > </tr > <tr > <td > 自我评价: </td > <td > <textarea rows ="10" cols ="20" > 我才是默认值</textarea > </td > </tr > <tr > <td > <input type ="reset" /> </td > <td align ="center" > <input type ="submit" /> </td > </tr > </table > </form > </body >
表单提交的细节 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 <body > <form action ="http://localhost:8080" method ="post" > <input type ="hidden" name ="action" value ="login" /> <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 ="password" name ="password" value ="abc" /> </td > </tr > <tr > <td > 性别: </td > <td > <input type ="radio" name ="sex" value ="boy" /> 男 <input type ="radio" name ="sex" checked ="checked" value ="girl" /> 女 </td > </tr > <tr > <td > 兴趣爱好: </td > <td > <input name ="hobby" type ="checkbox" checked ="checked" value ="java" /> Java <input name ="hobby" type ="checkbox" value ="js" /> JavaScript <input name ="hobby" type ="checkbox" value ="cpp" /> C++ </td > </tr > <tr > <td > 国籍: </td > <td > <select name ="country" > <option value ="none" > --请选择国籍--</option > <option value ="cn" selected ="selected" > 中国</option > <option value ="usa" > 美国</option > <option value ="jp" > 小日本</option > </select > </td > </tr > <tr > <td > 自我评价: </td > <td > <textarea name ="desc" rows ="10" cols ="20" > 我才是默认值</textarea > </td > </tr > <tr > <td > <input type ="reset" /> </td > <td align ="center" > <input type ="submit" /> </td > </tr > </table > </form > </body >
其他标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <body > <div > div 标签 1</div > <div > div 标签 2</div > <span > span 标签 1</span > <span > span 标签 2</span > <p > p 段落标签 1</p > <p > p 段落标签 2</p > </body >
CSS CSS 是层叠样式表单 。是用于(增强)控制网页样式并允许将样式信息与网页内容分离的一种标记性语言
CSS语法规则
选择器: 浏览器根据“选择器” 决定受 CSS 样式影响的 HTML 元素(标签) 。
属性: 是你要改变的样式名, 并且每个属性都有一个值。 属性和值被冒号分开, 并 由花括号包围, 这样就组成了一个完整的样式声明(declaration) , 例如: p {color: blue}
多个声明: 如果要定义不止一个声明, 则需要用分号将每个声明分开。 虽然最后一条声明的 最后可以不加分号(但尽量在每条声明的末尾都加上分号)
注:一般每行只描述一个属性
CSS 注释:/* 注释内容 */
CSS 和 HTML 的结合方式
第一种 在标签的 style 属性上设置 “ key : value value;” ,修改标签样式
需求一:分别定义两个 div、 span 标签, 分别修改每个 div 标签的样式为: 边框 1 个像素, 实线, 红色。
1 2 3 4 5 6 7 8 <div > div 标签1 </div > <div > div 标签2 </div > <span > span 标签1</span > <span > span 标签2</span >
问题: 这种方式的缺点
如果标签多了,样式多了,代码量非常庞大
可读性非常差
CSS 代码没有复用性可言
第二种 在head标签中,使用 style 标签来定义各种自己需要的 css 样式
格式如下
1 2 3 xxx{ Key:value value; }
问题: 缺点?
只能在同一页面内复用代码,不能在多个页面中复用 css 代码
维护起来不方便,实际的项目中会有成千上万的页面,要到每个页面中去修改,工作量太大了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > <style type ="text/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 文件,再通过 link 标签引入即可复用
使用 html 的 <link rel="stylesheet" type="text/css" href="./styles.css"/>
标签 导入css 样式文件
css 文件内容
1 2 3 4 5 6 div { border : 1px solid yellow; } span { border : 1px solid red; }
html 文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > <link rel ="stylesheet" type ="text/css" href ="1.css" /> </head > <body > <div > div标签</div > <div > div标签</div > <span > span标签</span > <span > span标签</span > </body > </html >
CSS 选择器
标签名选择器
标签名选择器 可以决定哪些标签被动的使用这个样式
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 标签名选择器</title > <style type ="text/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标签</div > <div > div标签</div > <span > span标签</span > <span > span标签</span > </body > </html >
id 选择器
id选择器,可以让我们通过id 属性选择器的去使用这个样式
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > id 选择器</title > <style type ="text/css" > #id001 { color : red; font-size : 30px ; border : 1px yellow solid; } #id002 { color : green; font-size : 30px ; border : 1px yellow solid; } </style > </head > <body > <div id ="id001" > div 标签1</div > <div id ="id002" > div 标签2</div > </body > </html >
class 选择器
.class 类型选择器,可以通过 class 属性有效的选择性地区使用这个样式
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > class 选择器</title > <style type ="text/css" > .class001 { color : black; font-size : 30px ; border : 1px solid white; } .class002 { color :aqua; font-size : 24px ; border : 1px solid black; } </style > </head > <body > <div class ="class001" > div标签</div > <div class ="class002" > div标签</div > </body > </html >
组合选择器 组合选择器的格式是:
1 2 3 选择器1,选择器2,选择器n{ 属性: 值; }
组合选择器可以让多个选择器共用一个 css 样式代码
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 组合选择器</title > <style type ="text/css" > .class01 ,id01{ color :aqua; font-size :30px ; border :2px solid black; } </style > </head > <body > <div id ="id001" > div 标签</div > <div class ="class01" > div 标签2</div > </body > </html >
常用样式
字体颜色 color: red;
颜色可以写颜色名如:black,blue,red,green
颜色也可以写 rgb 值和十六进制表示值:如 rgb(255,0,0),#00F6DE,如果写十六进制值必须加 #
宽度 width: 19px;
宽度可以写像素值: 19px;
也可以写百分比值: 20% ;
高度 height: 20px;
高度可以写像素值: 19px;
也可以写百分比值:20%
背景颜色 background-color: #0F2D4C
字体样式 color: #FF0000;
字体颜色红色
font-size: 20px;
字体大小
特例 红色1像素实线边框: boder: 1px red solid;
DIV 居中: margin-left:auto;
margin-right:auto;
文本居中:text-align:center;
超链接去下划线:text-decoration:none;
表格细线:
1 2 3 4 5 6 7 8 table{ border:1px solid black; border-collapse:collpase; } td,th{ border:1px solid black; }
列表去除修饰:
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > css 常用样式</title > <style type ="text/css" > div { color : red; border : 1px solid black; width : 300px ; height : 300px ; background-color : green; font-size : 30px ; margin-left : auto; margin-right : auto; text-align : center; } table { border : 1px solid red; border-collapse : collapse; } td { border : 1px solid black; } a { text-decoration : none; } ul { list-style : none; } </style > </head > <body > <ul > <li > 111111</li > <li > 111111</li > <li > 111111</li > <li > 111111</li > </ul > <table > <tr > <td > 1.1</td > <td > 1.2</td > </tr > </table > <a href ="http://www.baidu.com" > 百度</a > <div > div标签</div > </body > </html >
JavaScript JavaScript 语言诞生主要是为了完成页面的数据验证。因此他运行在客户端,需要浏览器来解析执行 JavaScript 代码。
JavaScprit 是弱类型,Java 是强类型
JavaScript 介绍
特点
交互性:他可以做的就是信息的动态交互
安全性:不允许直接访问本地硬盘
跨平台性:只要是可以解释 JS 的浏览器都可以执行,和平台无关
JavaScript 和 HTML 代码结合的方式
第一种 只需要在 head 标签中,或者在 body 标签中,使用 script 标签来书写 JavaScript 代码
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > js和html 结合的方式</title > <script type ="text/javascript" > alert ("Hello javascript!" ); </script > </head > <body > </body > </html >
第二种 使用 script 标签引入单独的 JavaScript 文件
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 第二种 js h5 结合方式</title > <script type ="text/javascript" src ="1.js" > </script > </head > <body > </body > </html >
变量
变量是可以存放某些值的内存的命名
JavaScript 的变量类型
数值类型
number
字符串类型
string
对象类型
object
布尔类型
boolean
函数类型
function
JavaScript 里特殊的值
JavaScript 定义变量格式 var 变量名;
var 变量名 = 值 ;
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 变量</title > <script type ="text/javascript" > var i; alert (i); i = 12 ; alert (typeof (i)); i = "abc" ; var a = 12 ; var b = "abc" ; alert (a * b); </script > </head > <body > </body > </html >
alert() 弹窗,经常用于确保用户可以得到某些信息,当警告框出现后,用户需要点击确定按钮才可以继续进行操作
typeof() 是 JavaScript 中提供的一个函数:操作符返回一个字符串,表示未经计算的操作数的类型。
关系(比较)运算 等于: == 等于是简单的做字面值的比较
全等于: === 除了做字面值的比较,还会比较两个变量的数据类型
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 关系运算</title > <script type ="text/javascript" > var a = 10 ; var b = "10" ; alert (a == b); alert (a === b); </script > </head > <body > </body > </html >
逻辑运算 且运算: &&
或运算: ||
取反运算: !
在 JavaScript 语言中,所有的变量,都可以作为一个 boolean 类型的变量去使用。
**0、null、undefined、“”(空串)都认为是 false; **
且运算
第一种: 当表达式全为真的时候。 返回最后一个表达式的值。
第二种: 当表达式中, 有一个为假的时候。 返回第一个为假的表达式的值
或运算
第一种情况: 当表达式全为假时, 返回最后一个表达式的值
第二种情况: 只要有一个表达式为真。 就会把回第一个为真的表达式的值
并且 && 与运算 和 ||或运算 有短路。 短路就是说, 当这个&&或||运算有结果了之后 。 后面的表达式不再执行
数组
数组的定义方式 js 中数组的定义:
1 2 var arrayName = []; var arrayName = [1 ,'abc,true' ];
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 数组定义</title > <script type ="text/javascript" > var arr = [true ,1 ]; alert (arr.length ); arr[0 ] = 12 ; alert (arr[0 ]); alert (arr.length ); arr[2 ] = "abc" ; alert (arr.length ); alert (arr[1 ]); for (var i = 0 ;i < arr.length ;++i){ alert (arr[i]) } </script > </head > <body > </body > </html >
函数
函数的两种定义方式 function 关键字定义 格式如下
1 2 3 function funcName ( ){ }
在 JavaScript 中,如何定义带有返回值的函数:只需要在函数体中直接使用 return 语句返回值即可。
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 函数定义的方式</title > <script type ="text/javascript" > function fun ( ){ alert ("调用了 无参函数 fun()" ); } function fun2 (a,b ){ alert ("有参函数 fun2() 被调用了 a=>" + a + ",b=>" +b); } function sum (num1,num2 ){ var result = num1 + num2; return result; } alert (sum (100 ,50 )); </script > </head > <body > </body > </html >
var 定义 var 函数名 = function(形参列表){函数体}
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <!doctype html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" > <meta http-equiv ="X-UA-Compatible" content ="ie=edge" > <title > 函数定义</title > <script type ="text/javascript" > var fun = function ( ){ alert ("无参函数" ); } var fun2 = function (a,b ){ alert ("a:" + a + "b:" + b ); } fun2 (1 ,2 ); var fun3 = function (a,b ){ return a + b; } alert (fun3 (12 ,43 )); </script > </head > <body > </body > </html >
函数的 arguments 隐形参数 就是在 function 函数中不需要定义,但却可以直接用来获取所有参数的变量,称之为 隐形参数,(与 Java 中 的可变长参数一样)
public void fun (Object ...args)
可变长参数其实是一个数组
那么 js 中的隐形参数跟 Java 的可变参数一样,类似操作数组
JS 中的自定义对象 Object 形式的自定义对象 对象的定义:
var 变量名 = new Object(); // 对象实例(空对象)
变量名.属性名 = 值; // 定义一个属性
变量名.函数名 = function(){} // 定义一个函数
对象的访问:
变量名.属性/函数名();
{}形式的自定义对象 对象的定义:
1 2 3 4 5 var 变量名 = { 属性名: 值, 属性名: 值, 函数名: function ( ){} };
对象的访问:
变量名.属性/函数名();
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > {}形式的自定义对象</title > <script type ="text/javascript" > var obj = { name : "csq" , age : 18 , fun : function ( ){ alert ("name=" + this .name + "age" + this .age ); } }; obj.fun (); </script > </head > <body > </body > </html >
事件
什么是事件,事件是电脑输入设备与页面进行交互的响应。我们称之为事件
事件的注册 事件的注册又分为静态注册和动态注册两种
什么是事件的注册? 其实就是告诉浏览器,当事件响应后要执行哪些操作代码,叫事件注册或事件绑定
静态注册 通过 HTML 标签的事件属性直接赋予事件响应后 的代码,这种方式我们叫 静态注册
动态注册 是指先通过js 代码得到标签的 dom 对象,然后再 通过 dom 对象.事件名 = function(){} 这种形式赋予事件响应后的代码,叫动态注册
动态注册基本步骤
获取标签对象
标签对象.事件名 = function(){}
常用的事件
onload 加载完成事件 代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > onload 加载完成事件</title > <script type ="text/javascript" > function onload ( ) { alert ("静态注册 onload 事件" ); } window .onload = function ( ) { alert ("动态注册的 onload事件" ) } window .onload (); </script > </head > <body > </body > </html >
onclick 单击事件 代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > onclick 单击事件</title > <script type ="text/javascript" > function onclickFun ( ){ alert ("静态注册 onclick事件" ); } window .onload = function ( ){ var btnObj = document .getElementById ("btn01" ); alert (btnObj); btnObj.onclick = function ( ){ alert ("动态注册的 onclick 事件" ); } } </script > </head > <body > <button onclick ="onclickFun();" > 按钮1</button > <button id ="btn01" > 按钮2</button > </body > </html >
onblur 失去焦点事件 代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > onblur失去焦点事件</title > <script type ="text/javascript" > function onblurFun ( ){ console .log ("静态注册失去焦点事件" ) } window .onload = function ( ){ let passwordObj = document .getElementById ("password" ); passwordObj.onblur = function ( ){ console .log ("动态注册失去焦点事件" ); } } </script > </head > <body > 用户名:<input type ="text" onblur ="onblurFun();" > <br /> 密码:<input id ="password" type ="text" > <br /> </body > </html >
oncharge 内容发生改变事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > onchange内容发生改变时间</title > <script type ="text/javascript" > function onchangeFun ( ){ alert ("内容已经发生改变" ) } window .onload = function ( ){ var selObj = document .getElementById ("sel01" ); alert (selObj); selObj.onchange = function ( ){ alert ("内容已经更改2" ); } } </script > </head > <body > 请选择: <select onchange ="onchangeFun();" > <option > 1</option > <option > 2</option > <option > 3</option > </select > 请选择2: <select onchange ="onchangeFun();" > <option > 1</option > <option > 2</option > <option > 3</option > </select > </body > </html >
onsubmit 表单提交事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > function onsubmitFun ( ){ alert ("静态注册表单提交事件---发现不合法" ) return false ; } window .onload = function ( ){ var formObj = document .getElementById ("form01" ); formObj.onsubmit = function ( ){ alert ("动态注册表单提交事件---发现不合法" ); return false ; } } </script > </head > <body > <form action ="http://localhost:8080" method ="get" onsubmit ="onsubmitFun();" > <input type ="submit" value ="静态注册" /> </form > <form action ="http://localhost:8080" id ="form01" > <input type ="submit" value ="动态注册" /> </form > </body > </html >
DOM 模型
DOM 全程就是 Document Object Model 文档对象模型
换句话说,就是把文档中的标签,属性,文本,转换成对象来管理,
Document 对象 Document 对象的理解
Document 他管理了所有的 HTML 文档内容
document 他是一种树结构的文档,有层级关系
他让我们把所有的标签都对象化
我们可以通过 document 访问所有的标签对象
html 标签对象化 1 2 3 4 5 <body > <div id ="div01" > div01 </div > </body >
模拟对象化
1 2 3 4 5 6 7 class Dom { private String id; private String tagName; private Dom parentNOde; private List<Dom> children; private String innerHTML; }
Document 对象中的方法介绍 document.getElementById(elementId) 通过标签的 id 属性查找标签对象,elementId 是标签的 id 属性值
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > function onclickFun ( ){ let usernameObj = document .getElementById ("username" ); let usernameText = usernameObj.value ; let patt = /^\w{5,12}$/ ; let usernameSpanObj = document .getElementById ("usernameSpan" ); usernameSpanObj.innerHTML ="innerHTML" ; if (patt.test (usernameText)){ usernameSpanObj.innerHTML = "right" ; } else { usernameSpanObj.innerHTML ="wrong" ; } } </script > </head > <body > 用户名: <input type ="text" id ="username" value ="csq" /> <span id ="usernameSpan" style ="color:red;" > </span > <button onclick ="onclickFun()" > 校验</button > </body > </html >
document.getElementsByName(elementName) 通过标签的 name 属性 查找标签的 dom 对象,elementName 标签的 name 属性值
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > function checkAll ( ){ let hobbies = document .getElementsByName ("hobby" ); for (let i = 0 ;i < hobbies.length ;++i){ hobbies[i].checked = true ; } } function checkNo ( ){ let hobbies = document .getElementsByName ("hobby" ); for (let i = 0 ;i < hobbies.length ;++i){ hobbies[i].checked = false ; } } function checkReverse ( ){ let hobbies = document .getElementsByName ("hobby" ); for (let i = 0 ;i < hobbies.length ;++i){ hobbies[i].checked = !hobbies[i].checked ; } } </script > </head > <body > 兴趣爱好: <input type ="checkbox" name ="hobby" value ="cpp" checked ="checked" > C++ <input type ="checkbox" name ="hobby" value ="java" > Java <input type ="checkbox" name ="hobby" value ="js" > JavaScript <button onclick ="checkAll()" > 全选</button > <button onclick ="checkNo()" > 全不选</button > <button onclick ="checkReverse()" > 反选</button > </body > </html >
document.getElementsByTagName(tagName) 通过标签名查找标签 dom 对象,tagName 是标签名
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > function checkAll ( ) { let inputs = document .getElementsByTagName ("input" ); for (let i = 0 ;i < inputs.length ;++i){ inputs[i].checked = true ; } } </script > </head > <body > 兴趣爱好: <input type ="checkbox" value ="cpp" checked ="checked" > C++ <input type ="checkbox" value ="java" > Java <input type ="checkbox" value ="js" > JavaScript <br /> <button onclick ="checkAll()" > 全选</button > </body > </html >
document.createElement(tagName) 方法,通过给定的标签名,创建一个标签对象。tagName 是要创建的标签名
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > window .onload = function ( ){ let divObj = document .createElement ("div" ); let textNodeObj = document .createTextNode ("csq" ); divObj.appendChild (textNodeObj); document .body .appendChild (divObj); } </script > </head > <body > </body > </html >
注:
document 对象的是哪个查询方法,如果有 id 属性,优先使用 getElementById 方法来进行查询,如果没有 id 属性,则优先使用 getElementsByName 方法来进行查询,如果id 属性 和 name 属性都没有最后再按标签名查 getElementsByTagName
以上三个方法,一定要在页面加载完成之后执行,才能查询到标签对象
节点的常用属性和方法 节点就是标签对象
方法 通过具体的节点调用
getElementsByName() 方法,获取当前节点的指定标签名的孩子节点
appendChild(oChildNode) 方法,可以添加一个子节点,oChildNode 是要添加的孩子节点
属性 childNodes 属性,获取当前节点的所有子节点
firstChild 属性,获取当前节点的第一个节点
lastChild 属性,获取当前节点的最后一个节点
parentNode 属性,获取当前节点的父节点
nextSibling 属性,获取当前节点的下一个节点
previousSibling 属性,获取当前节点的上一个节点
className 用于获取或设置标签的 class 属性值
innerHTML 属性,表示获取/设置起始标签和结束标签中的内容
innerText 属性,表示获取/设置起始标签和结束标签中的文本
DOM 查询练习 代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > window .onload = function ( ){ document .getElementById ("btn01" ).onclick = function ( ){ let bjObj = document .getElementById ("bj" ); alert (bjObj.innerHTML ); } let btn02Ele = document .getElementById ("btn02" ); btn02Ele.onclick = function ( ){ let lis = document .getElementsByTagName ("li" ); alert (lis.length ); } let btn03Ele = document .getElementById ("btn03" ); btn03Ele.onclick = function ( ){ let genders = document .getElementsByName ("gender" ); alert (genders.length ); } let btn04Ele = document .getElementById ("btn04" ); btn04Ele.onclick = function ( ){ let lis = document .getElementById ("city" ).getElementsByTagName ("li" ); alert (lis.length ); } let btn05Ele = document .getElementById ("btn05" ); btn05Ele.onclick = function ( ){ let childLength = document .getElementById ("city" ).childNodes .length ; alert (childLength); } let btn06Ele = document .getElementById ("btn06" ); btn06Ele.onclick = function ( ){ let firstChild = document .getElementById ("phone" ).firstChild ; alert (firstChild.innerHTML ); } let btn07Ele = document .getElementById ("btn07" ); btn07Ele.onclick = function ( ){ let parentNode = document .getElementById ("bj" ).parentNode ; alert (parentNode.innerHTML ); } let btn08Ele = document .getElementById ("btn08" ); btn08Ele.onclick = function ( ){ let previousSibling = document .getElementById ("android" ).previousSibling ; alert (previousSibling.innerHTML ); } let btn09Ele = document .getElementById ("btn09" ); btn09Ele.onclick = function ( ){ let value = document .getElementById ("username" ).value ; alert (value); } let btn10Ele = document .getElementById ("btn10" ); btn10Ele.onclick = function ( ){ document .getElementById ("username" ).value = "csq" ; alert (document .getElementById ("username" ).value ); } let btn11Ele = document .getElementById ("btn11" ); btn11Ele.onclick = function ( ){ let innerText = document .getElementById ("bj" ).innerText ; alert (innerText); } } </script > </head > <body > <div id ="inner" > <p > 你喜欢哪个城市? </p > <ul id ="city" > <li id ="bj" > 北京</li > <li > 上海</li > <li > 南京</li > <li > 首尔</li > </ul > <br > <br > <p > 你喜欢哪款游戏? </p > <ul id ="game" > <li id ="lol" > LOL</li > <li > 永劫无间</li > <li > 王者荣耀</li > </ul > <br /> <br /> <p > 你手机操作系统是? </p > <ul id ="phone" > <li > IOS</li > <li id ="android" > Android</li > </ul > </div > <div class ="inner" > gender: <input type ="radio" name ="gender" value ="male" /> Male <input type ="radio" name ="gender" value ="female" /> Female <br > <br > name: <input type ="text" name ="name" id ="username" value ="abcde" /> </div > <div id ="btnlist" > <div > <button id ="btn01" > 查找#bj节点</button > </div > <div > <button id ="btn02" > 查找所有li 节点</button > </div > <div > <button id ="btn03" > 查找 name = gender 的所有节点</button > </div > <div > <button id ="btn04" > 查找#city 下所有 li 节点</button > </div > <div > <button id ="btn05" > 返回#city 的所有子节点</button > </div > <div > <button id ="btn06" > 返回#phone 的第一个子节点</button > </div > <div > <button id ="btn07" > 返回#bj 的父节点</button > </div > <div > <button id ="btn08" > 返回#android 的前一个兄弟节点</button > </div > <div > <button id ="btn09" > 返回#username 的 value 属性值</button > </div > <div > <button id ="btn10" > 设置#username 的 value 属性值</button > </div > <div > <button id ="btn11" > 返回#bj 的文本值</button > </div > </div > </body > </html >
jQuery jQuery 介绍
什么是jQuery jQuery 是 JavaScript 和 查询(Query),是辅助 JavaScript 开发的 js 类库
jQuery 核心思想 核心思想就是 write less,do more,所以他实现了很多浏览器的兼容问题
jQuery 好处 jQuery 是免费、开源的,jQuery 的语法设计可以使开发更加便捷,例如操作文档对象、选择 DOM 对象、制作动画特效、事件处理、使用 Ajax 以及其他功能
常见问题
使用 jQuery 一定要引入 jQuery 库吗
是,必须引入
jQuery 中的 $ 是什么
是一个函数
怎么为 按钮添加点击响应函数
使用 jQuery 查询标签对象
使用标签对象.click(function(){});
jQuery 核心函数
$ 是 jQuery 的核心函数,能完成 jQuery 的很多功能。$()就是 调用 $ 这个函数
jQuery对象和dom 对象区分
jQuery对象、dom 对象 Dom对象
通过 getElementById() 查询出来的标签对象是 Dom 对象
通过 getElementsByName() 查询出来的标签对象是 Dom 对象
通过 getElementsByTagName() 查询出来的是 Dom 对象
通过 createElement() 方法创建出来的对象,是 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 对象的属性和方法
jQuery对象和 dom 对象互转
dom 对象转化为 jQuery 对象
先有 dom 对象
$(dom 对象)
就可以转换成为 jQuery 对象
jQuery 对象转化为 dom 对象
先有 jQuery 对象
jQuery 对象[下标]
取出相应的 dom 对象
jQuery 选择器
基本选择器
p.myClass
表示 标签名必须是 p 标签,而且class 类型必须是 myClass 类型
层级选择器、
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
匹配所有正在执行动画效果的元素
内容过滤器
contains(text)
匹配包含给定文本的元素
empty
匹配所有不包含子元素或者文本的空元素
parent
匹配含有子元素或者文本的元素
has(selector)
匹配含有选择器所匹配的元素的元素
属性过滤器
表单过滤器
input
匹配所有 input ,textarea.select 和 button 元素
text
匹配所有文本输入框
password
匹配所有的密码输入框
radio
匹配所有的单选框
checkbox
匹配所有的复选框
submit
匹配所以的提交按钮
image
匹配所有的 img 标签
reset
匹配所有的重置按钮
button
匹配所有的 input type = butoon 按钮
file
匹配所有 input type = file 文件上传
hidden
匹配所有不可见元素 display:none 或 input type = hidden
表单对象属性过滤器
jQuery 元素筛选
eq() 获取给定索引的元素 功能跟eq()一样
first() 获取第一个元素 功能跟:first一样
last() 获取最后一个元素 功能跟last一样
filter(exp) 留下匹配的元素
is(exp) 判断是否匹配给定的选择器,只要有一个匹配就返回,tue
has(exp) 返回包含有匹配选择器的元素的元素功能跟:has一样
not(exp) 删除匹配选择器的元素 功能跟:not一样
children(exp) 返回匹配给定选择器的子元素 功能跟parent>:child一样
find(exp) 返回匹配给定选择器的后代元素 功能跟ancestor descendant一样
next() 返回当前元素的下一个兄弟元素 功能跟prev+next功能一样
nextAll() 返回当前元素后面所有的兄弟元素 功能跟prev~siblings功能一样
nextUntil() 返回当前元素到指定匹配的元素为止的后面元素
parent() 返回父元素
prev(exp) 返回当前元素的上一个兄弟元素
prevAll() 返回当前元素前面所有的兄弟元素
prevUnit(exp) 返回当前元素到指定匹配的元素为止的前面元素
siblings(exp) 返回所有兄弟元素
add() 把add匹配的选择器的元素添加到当前jquery对象中
jQuery 的属性操作
html() 他可以设置和获取起始标签和结束标签中的内容,跟dom 属性 innerHTML 一样
text() 他可以设置和获取起始标签和结束标签中的文本,跟 dom 属性 innerText 一样
val() 他可以设置和获取 表单项 的value 属性值,跟 dom 属性 value 一样
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <!DOCTYPE html > <html lang ="zh_CN" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" src ="script/jquery-1.7.2.js" > </script > <script type ="text/javascript" > $(function ( ) { $("#multiple,#single,:radio,:checkbox" ).val (["radio2" ,"checkbox1" ,"checkbox3" ,"mul1" ,"mul4" ,"sin3" ]); }); </script > </head > <body > <body > 单选: <input name ="radio" type ="radio" value ="radio1" /> radio1 <input name ="radio" type ="radio" value ="radio2" /> radio2 <br /> 多选: <input name ="checkbox" type ="checkbox" value ="checkbox1" /> checkbox1 <input name ="checkbox" type ="checkbox" value ="checkbox2" /> checkbox2 <input name ="checkbox" type ="checkbox" value ="checkbox3" /> checkbox3 <br /> 下拉多选 : <select id ="multiple" multiple ="multiple" size ="4" > <option value ="mul1" > mul1</option > <option value ="mul2" > mul2</option > <option value ="mul3" > mul3</option > <option value ="mul4" > mul4</option > </select > <br /> 下拉单选 : <select id ="single" > <option value ="sin1" > sin1</option > <option value ="sin2" > sin2</option > <option value ="sin3" > sin3</option > </select > </body > </body > </html >
attr() 可以设置和获取属性的值,不推荐操作 checked
不推荐操作 checked、readOnly、selected、disabled 等
attr()方法还可以操作 非标准属性。比如自定义属性:abc,csq
prop() 可以设置和获取属性的值
只推荐操作 checked、readOnly、selected、disabled 等
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <!DOCTYPE html > <html lang ="zh_CN" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" src ="script/jquery-1.7.2.js" > </script > <script type ="text/javascript" > $(function ( ) { $("div" ).empty (); }); </script > </head > <body > <body > <br /> 多选: <input name ="checkbox" type ="checkbox" checked ="checked" value ="checkbox1" /> checkbox1 <input name ="checkbox" type ="checkbox" value ="checkbox2" /> checkbox2 <br /> <br /> <div > 1234</div > <div > 1234</div > </body > </body > </html >
jQuery 练习
全选、全不选、反选 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 <!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" > $(document ).ready (function ( ){ $("#checkedAllBtn" ).click (function ( ){ $(":checkbox" ).prop ("checked" ,true ); }); $("#checkedNoBtn" ).click (function ( ){ $(":checkbox" ).prop ("checked" ,false ); }); $("#checkedRevBtn" ).click (function ( ){ $(":checkbox[name='items']" ).each (function ( ){ this .checked = !this .checked ; }); let allCount = $(":checkbox[name='items']" ).length ; let selectedCount = $(":checkbox[name='items']:checked" ).length ; if (allCount === selectedCount){ $("#checkedAllBox" ).prop ("checked" , true ); } else { $("#checkedAllBox" ).prop ("checked" , allCount === selectedCount); } }); $("#sendBtn" ).click (function ( ) { $(":checkbox[name='items']:checked" ).each (function ( ){ alert (this .value ); }); }); $("#checkedAllBox" ).click (function ( ){ $(":checkbox[name='items']" ).prop ("checked" ,this .checked ); }); $(":checkbox[name='items']" ).click (function ( ){ let allCount = $(":checkbox[name='items']" ).length ; let selectedCount = $(":checkbox[name='items']:checked" ).length ; if (allCount === selectedCount){ $("#checkedAllBox" ).prop ("checked" , true ); } else { $("#checkedAllBox" ).prop ("checked" , allCount === selectedCount); } }); }); </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 >
从左到右,从右到左 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <!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" > select { width : 100px ; height : 140px ; } div { width : 130px ; float : left; text-align : center; } </style > <script type ="text/javascript" src ="script/jquery-1.7.2.js" > </script > <script type ="text/javascript" > $(function ( ) { $("button:eq(0)" ).click (function ( ) { $("select:eq(0) option:selected" ).appendTo ($("select:eq(1)" )); }); $("button:eq(1)" ).click (function ( ) { $("select:eq(0) option" ).appendTo ($("select:eq(1)" )); }); $("button:eq(2)" ).click (function ( ) { $("select:eq(1) option:selected" ).appendTo ($("select:eq(0)" )); }); $("button:eq(3)" ).click (function ( ) { $("select:eq(1) option" ).appendTo ($("select:eq(0)" )); }); }); </script > </head > <body > <div id ="left" > <select multiple ="multiple" name ="sel01" > <option value ="opt01" > 选项1</option > <option value ="opt02" > 选项2</option > <option value ="opt03" > 选项3</option > <option value ="opt04" > 选项4</option > <option value ="opt05" > 选项5</option > <option value ="opt06" > 选项6</option > <option value ="opt07" > 选项7</option > <option value ="opt08" > 选项8</option > </select > <button > 选中添加到右边</button > <button > 全部添加到右边</button > </div > <div id ="rigth" > <select multiple ="multiple" name ="sel02" > </select > <button > 选中删除到左边</button > <button > 全部删除到左边</button > </div > </body > </html >
动态添加、删除表格记录 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 <!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 ( ){ let deleteFun = function ( ){ let $trObj = $(this ).parent ().parent (); let name = $trObj.find ("td:first" ).text (); if (confirm ("你确定要删除 " + name + "吗" )){ $trObj.remove (); } return false ; } $("#addEmpButton" ).click (function ( ){ let name = $("#empName" ).val (); let email = $("#email" ).val (); let salary = $("#salary" ).val (); let $trObj = $("<tr>" + "<td>" + name + "</td>" + "<td>" + email + "</td>" + "<td>" + salary + "</td>" + "<td><a href=\"deleteEmp?id=002\">Delete</a></td>" + "</tr>" ); $trObj.appendTo ($("#employeeTable" )); $trObj.find ("a" ).click (deleteFun); }); $("a" ).click (deleteFun); }); </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 ="deleteEmp?id=001" > Delete</a > </td > </tr > <tr > <td > Jerry</td > <td > jerry@sohu.com</td > <td > 8000</td > <td > <a href ="deleteEmp?id=002" > Delete</a > </td > </tr > <tr > <td > Bob</td > <td > bob@tom.com</td > <td > 10000</td > <td > <a href ="deleteEmp?id=003" > 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 >
事件 图片跟随 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <!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 (event ){ if (event.type == "mouseover" ){ $("#showBig" ).show (); } else if (event.type == "mousemove" ){ console .log (event); $("#showBig" ).offset ({ left :event.pageX + 10 , top :event.pageY + 10 }); } else if (event.type == "mouseout" ){ $("#showBig" ).hide (); } }); }); </script > </head > <body > <img id ="small" src ="img/small.jpg" /> <div id ="showBig" > <img src ="img/big.jpg" > </div > </body > </html >
dom 的增删改
内部插入 appendTo() a.appendTo(b)
把a 插入到 b 子元素末尾,称为最后一个元素
prependTo() a.preepend(b)
把 a 插到 b 所有子元素前面,成为第一个元素
外部插入 insertAfter() a.insertAfter(b)
得到 ba
insertBefore() a.insertBefore(b)
得到 ab
替换 replaceWith() a.replaceWith(b)
用 b 替换 a
replaceAll() a.replacerAll(b)
用 a 替换掉所有的 b
删除 remove() a.remove();
删除 a 标签
empty() a.empty();
清空 a 标签里的内容
CSS 样式操作
addClass() 添加样式
removeClass() 删除样式
toggleClass() 有就删除,没有就添加
offSet() 获取和设置元素的坐标
jQuery 动画
基本动画 show() 将隐藏的元素显示
hide() 将可见的元素隐藏
toggle() 可见就隐藏,不可见就显示
以上动画方法都可以添加参数
第一个参数就是动画 执行的时长,以毫秒为单位
第二个参数就是动画的回调参数(动画完成之后自动调用的函数)
淡入淡出动画 fadeIn() 淡入(慢慢可见)
fadeOut() 淡出(慢慢消失)
fadeTo() 在指定的时长内慢慢的将透明度修改到指定的值。 0:透明 1:完成可见 0.5:半透明
fadeToggle() 淡入/淡出 切换
动画练习 品牌展示
需求: 1.点击按钮的时候, 隐藏和显示卡西欧之后的品牌。 2.当显示全部内容的时候, 按钮文本为“显示精简品牌” 然后, 小三角形向上。 所有品牌产品为默认颜色。 3.当只显示精简品牌的时候, 要隐藏卡西欧之后的品牌, 按钮文本为“显示全部品牌” 然后小三形向下。 并且把 佳能, 尼康的品牌颜色改为红色(给 li 标签添加 promoted 样式即可)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > <html xmlns ="http://www.w3.org/1999/xhtml" > <head > <meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" /> <title > 品牌展示练习</title > <style type ="text/css" > * { margin : 0 ; padding : 0 ; } body { font-size : 12px ; text-align : center; } a { color : #04D ; text-decoration : none; } a :hover { color : #F50 ; text-decoration : underline; } .SubCategoryBox { width : 600px ; margin : 0 auto; text-align : center; margin-top : 40px ; } .SubCategoryBox ul { list-style : none; } .SubCategoryBox ul li { display : block; float : left; width : 200px ; line-height : 20px ; } .showmore , .showless { clear : both; text-align : center; padding-top : 10px ; } .showmore a , .showless a { display : block; width : 120px ; margin : 0 auto; line-height : 24px ; border : 1px solid #AAA ; } .showmore a span { padding-left : 15px ; background : url (img/down.gif ) no-repeat 0 0 ; } .showless a span { padding-left : 15px ; background : url (img/up.gif ) no-repeat 0 0 ; } .promoted a { color : #F50 ; } </style > <script type ="text/javascript" src ="script/jquery-1.7.2.js" > </script > <script type ="text/javascript" > $(function ( ) { $("li:gt(5):not(:last)" ).hide (); $("div div a" ).click (function ( ){ $("li:gt(5):not(:last)" ).toggle (); if ($("li:gt(5):not(:last)" ).is (":hidden" )){ $("div div a span" ).text ("显示全部品牌" ); $("div div" ).removeClass (); $("div div" ).addClass ("showmore" ); $("li:contains('索尼')" ).removeClass ("promoted" ); } else { $("div div a span" ).text ("显示精简品牌" ); $("div div" ).removeClass (); $("div div" ).addClass ("showless" ); $("li:contains('索尼')" ).addClass ("promoted" ); } return false ; }); }); </script > </head > <body > <div class ="SubCategoryBox" > <ul > <li > <a href ="#" > 佳能</a > <i > (30440) </i > </li > <li > <a href ="#" > 索尼</a > <i > (27220) </i > </li > <li > <a href ="#" > 三星</a > <i > (20808) </i > </li > <li > <a href ="#" > 尼康</a > <i > (17821) </i > </li > <li > <a href ="#" > 松下</a > <i > (12289) </i > </li > <li > <a href ="#" > 卡西欧</a > <i > (8242) </i > </li > <li > <a href ="#" > 富士</a > <i > (14894) </i > </li > <li > <a href ="#" > 柯达</a > <i > (9520) </i > </li > <li > <a href ="#" > 宾得</a > <i > (2195) </i > </li > <li > <a href ="#" > 理光</a > <i > (4114) </i > </li > <li > <a href ="#" > 奥林巴斯</a > <i > (12205) </i > </li > <li > <a href ="#" > 明基</a > <i > (1466) </i > </li > <li > <a href ="#" > 爱国者</a > <i > (3091) </i > </li > <li > <a href ="#" > 其它品牌相机</a > <i > (7275) </i > </li > </ul > <div class ="showmore" > <a href ="more.html" > <span > 显示全部品牌</span > </a > </div > </div > </body > </html >
jQuery 事件操作
$function(){};
和 window.onload(){}
区别什么时候触发
jQuery 的页面加载完成之后是浏览器的内核解析完页面的标签创建好 dom 对象之后就会马上执行
原生 js 的页面加载完成之后,除了要等浏览器内核解析完标签创建好 dom 对象,还要等标签显示时需要的内容加载完成
触发的顺序
jQuery 页面加载完成之后先执行
原生 js 的页面加载完成之后
执行的次数
原生 js 的页面加载完成之后,只会执行最后一次的赋值函数
jQuery 的页面加载完成之后是全部把注册的 function 函数,依次顺序执行
jQuery 其他事件处理方法 click() 他可以绑定单击事件,以及触发单击事件
mouseover() 鼠标移入事件
mouseout() 鼠标移除事件
bind() 可以给元素一次性绑定一个或多个事件
one() 使用上跟 bind() 一样。但是one ()绑定的事件只会响应一次
unbind() 跟 bind() 相反的操作,解除事件的绑定
live() 也是用来绑定事件,他可以用来绑定选择器匹配的所有元素的事件。哪怕这个元素是后面动态创建出来的也有效
事件的冒泡 事件的冒泡是指,父子元素同时监听同一个元素,当触发子元素的时候,同一个事件也被传递到了父元素的事件里去响应
如何阻止事件冒泡 在子元素事件函数体中,return false;
可以阻止事件的冒泡传递
JavaScript 事件对象
事件对象,是封装有触发的事件信息的一个 js 对象
我们重点关心的是 怎么拿到这个 js 事件对象,以及使用
获取 JavaScript 事件对象 在给元素绑定事件对象的时候,在事件的 function(event) 参数列表中添加一个参数,这个参数名,我们习惯取名为 event ,这个event 就是 JavaScript 传递参数事件处理函数的事件对象
JavaScript 获取事件对象 1 2 3 4 5 window .onload = function ( ){ document .getElementById ("areaDiv" ).onclick () = function (event ){ console .log (event); } }
jQuery 获取事件对象 1 2 3 4 5 $(function ( ){ $("#areaDiv" ).click (function (event ){ console .log (event); }); });
bind 对多个事件绑定同一个函数 1 2 3 4 5 6 7 $("area" ).bind ("mouseover mouseout" ,function (event ){ if (event.type == "mouseover" ){ console .log ("鼠标移入" ); } else if (event.type == "mouseout" ){ console .log ("鼠标移出" ); } });
XML xml 是可扩展的标记性语言
xml 的作用
用来保存数据,而且这些数据有自我描述性
他还可以作为项目或者模块的配置文件
还可以作为网络传输数据的格式(现在 json 为主)
xml 语法
文档声明 1 2 <?xml version="1.0" encoding="UTF-8" ?>
<?xml 要连在一起写,要不会报错
属性
version - 版本号
encoding - xml 文件编码
standalone=”yes/no” - 表示这个 xml 文件是否是独立的 xml 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?xml version="1.0" encoding="UTF-8" ?> <!-- <?xml version="1.0" encoding="UTF-8 ?> 以上内容就是 xml 文件的声明 version="1.0" version 表示 xml的版本 encoding="UTF-8 encoding 表示文件本身的编码 --> <books> <!-- books 表示多个图书信息--> <book sn="SN122323232"> <!-- 表示 一个图书信息 sn 表示图书序列号--> <name>时间简史</name> <!-- name 表示书名--> <author>霍金</author> <!-- author 表示作者--> <price>100</price> <!-- price 表示价格 --> </book> <book sn="SN3244324234"> <name>java从入门到放弃</name> <author>ss</author> <price>100</price> </book> </books>
xml 注释 HTML 和 xml 注释一样
<!-- 注释 -->
元素(标签) 什么是 xml 元素 xml 元素是从(且包括)开始标签直到(且包括)结束标签的部分
元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性
xml 命名规则
名称可以包含字母、数字以及其他的字符
名称不能以数字或者标点符号开始
名称不能包含空格
xml 中的元素(标签)也分成单标签和双标签
xml 属性 xml 的标签属性 和 html 的标签属性是非常相似的,属性可以提供元素的额外信息
在标签上可以书写属性
一个标签可以书写多个属性。每个属性的值必须使用 引号 引起来 。 规则和标签的书写规则一致
XML 元素可以在开始标签中包含属性,类似 HTML
属性(Attribute) 提供关于元素的额外信息
xml 语法规则
所有 xml 元素都必须有关闭标签(也就是闭合)
XML 标签对大小写敏感
xml 必须正确地嵌套
xml 文档必须有根元素
根元素就是顶级元素,没有父标签的元素叫做顶级元素,根元素是没有父标签的顶级元素,而且是唯一一个才行
xml 的属性值必须加 引号
xml 中的特殊字符
文本区域(CDATA区)
CDATA 语法可以告诉 xml 解析器,我 CDATA 里的文本内容,只是纯文本内容,不需要 xml 语法解析
CDATA 格式:
<![CDATA[这里可以把你输入的字符原样提示,不会解析 xml]]>
xml 解析技术
xml 可扩展的标记语言
不管是 html 还是 xml 文件 他们都是标记型文档,都可以使用 w3c 组织指定的 dom 技术来解析
xml 文档对象模型定义访问和操作 XML 文档的标准方法
DOM 将 xml 文档作为一个树形结构,而树叶被定义为节点
document 对象表示的是整个文档(可以是 HTML 文档,也可以是 xml 文档)
dom4j 解析技术
由于 dom4j 不是 sun 公司的技术,而属于第三方公司的技术,我们需要使用 dom4j 就需要 dom4j 官网下载 dom4j 的 jar 包
Dom4j 类库的使用 dom4j 编程步骤
先加载 xml 文件创建 Document 对象
通过 Document 对象拿到 根元素
通过 根元素.elements(“标签名”); 可以返回一个集合,这个集合里放着,所有你指定的标签名的元素对象
找到你想要修改、删除的子元素,进行相应的操作
保存到硬盘上
步骤
先创建 SAXReader 对象,这个对象,用于读取 xml 文件,并创建 document
通过 document 对象,拿到 xml 的根元素对象
通过根元素对象,获取所有的 book 标签对象
遍历每个 book 标签对象,然后获取到 book 标签对象内的每一个元素,再通过 getText() 方法拿到起始标签和结束标签之间的文本内容
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 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 getDocument () throws Exception { SAXReader reader = new SAXReader (); Document document = reader.read("src/books.xml" ); System.out.println(document); } @Test public void readXML () throws Exception { SAXReader reader = new SAXReader (); Document document = reader.read("src/books.xml" ); Element root = document.getRootElement(); List<Element> books = root.elements("book" ); for (Element book : books) { Element nameElement = book.element("name" ); Element priceElement = book.element("price" ); Element authorElement = book.element("author" ); System.out.println("书名:" + nameElement.getText() + " 价格:" + priceElement.getText() + " 作者:" + authorElement.getText()); } } }
Tomcat JavaWeb 的概念
什么是 JavaWeb javaweb 是指所有通过 Java 语言编写可以通过浏览器访问的程序的总称,叫 Javaweb
JavaWeb 是基于请求和响应来开发的
什么是请求 请求是指客户端给服务器发送数据,叫请求 request
什么是响应 响应是指服务器给客户端回传数据,叫响应 response
请求和响应的关系 请求和响应是成对出现的,有请求就有响应
Web 资源的分类
web 资源按实现的技术和呈现的效果的不同,又分为静态资源和动态资源两种
常用的 Web 服务器
Tomcat:Apache 组织提供的一种 Web 服务器, 提供对 jsp 和 Servlet 的支持。 它是一种轻量级的 javaWeb 容器(服务 器) , 也是当前应用最广的 JavaWeb 服务器(免费)
Jboss: 是一个遵从 JavaEE 规范的、 开放源代码的、 纯 Java 的 EJB 服务器, 它支持所有的 JavaEE 规范(免费)
GlassFish: 由 Oracle 公司开发的一款 JavaWeb 服务器, 是一款强健的商业服务器, 达到产品级质量(应用很少)
Resin: 是 CAUCHO 公司的产品, 是一个非常流行的服务器, 对 servlet 和 JSP 提供了良好的支持, 性能也比较优良, resin 自身采用 JAVA 语言开发(收费, 应用比较多)
WebLogic: 是 Oracle 公司的产品, 是目前应用最广泛的 Web 服务器, 支持 JavaEE 规范, 而且不断的完善以适应新的开发要求, 适合大型项目(收费, 用的不多, 适合大公司)
Tomcat 服务器和 Servlet 版本的对应关系
当前企业常用的版本 7.* 8.*
Tomcat版本
Servlet/JSP版本
JavaEE版本
运行环境
4.1
2.3/1.2
1.3
JDK 1.3
5.0
2.4/2.0
1.4
JDK 1.4
5.5/6.0
2.5/2.1
5.0
JDK 5.0
7.0
3.0/2.2
6.0
JDK 6.0
8.0
3.1/2.3
7.0
JDK 7.0
Servlet 程序从 2.5 版本就是现在世面使用最多的版本(xml 配置)
到了Servlet 3.0 之后,就是注解版本的 Servlet 使用
Tomcat 的使用
Servlet Servlet 技术
什么是 Servlet
Servlet 就是 JavaEE 规范之一。规范就是接口
Servlet 就是 JavaWeb 三大组件之一。三大组件分别是
Servlet 程序
Filter 过滤器
Listener 监听器
Servlet 是运行在服务器上的一个 Java 小程序,他可以接收客户端发送来的请求,并响应数据给客户端
手动实现 Servlet 程序
编写一个类去实现 Servlet 接口
实现 service 方法,处理请求,并相应数据
到 web.xml 中去配置 Servlet 程序的访问地址
Servlet 程序代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package com.csqservlet.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 ; } @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("helloServlet 被访问了" ); } @Override public String getServletInfo () { return null ; } @Override public void destroy () { } } <!-- servlet 标签给 Tomcat 服务器配置 servlet 程序 --> <servlet> <!-- servlet-name 标签 :给servlet程序起一个别名 (一般是类名)--> <servlet-name>helloServlet_</servlet-name> <!-- servlet-class 标签: 是 servlet 程序的全类名 --> <servlet-class>com.csqservlet.servlet_.helloServlet_</servlet-class> </servlet> <!-- servlet-mapping 标签:给 servlet 程序配置访问地址--> <servlet-mapping> <!-- servlet-name 标签:告诉服务器,我当前配置的地址 给哪个 servlet 程序使用--> <servlet-name>helloServlet_</servlet-name> <!-- url-pattern 标签:配置访问地址 / 斜杠在服务器解析的时候,表示地址为 http: /hello 表示地址为:http: --> <url-pattern>/abc</url-pattern> </servlet-mapping>
url 地址到 servlet 程序的访问
Servlet 的生命周期
执行 servlet 构造器方法
执行 init 初始化方法
执行 service 方法
执行 destroy 销毁方法
第一、二步是在第一次访问的时候创建 servlet 程序会调用
第三步每次访问都会调用
第四步在 web 工程停止的时候调用
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package com.cs7eric.servlet;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;@WebServlet(name = "helloServlet", value = "/hello-servlet") public class HelloServlet implements Servlet { public HelloServlet () { System.out.println("HelloServlet 的构造器" ); } @Override public void init (ServletConfig servletConfig) throws ServletException { System.out.println("HelloServlet 的init 方法" ); } @Override public ServletConfig getServletConfig () { return null ; } @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("service 被访问了!!" ); } @Override public String getServletInfo () { return null ; } @Override public void destroy () { } }
get 和 post 请求的分发请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package com.cs7eric.servlet;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;@WebServlet(name = "helloServlet", value = "/hello-servlet") public class HelloServlet implements Servlet { public HelloServlet () { System.out.println("HelloServlet 的构造器" ); } @Override public void init (ServletConfig servletConfig) throws ServletException { System.out.println("HelloServlet 的init 方法" ); } @Override public ServletConfig getServletConfig () { return null ; } @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("3 service == Hello Servlet 被访问了" ); HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; String method = httpServletRequest.getMethod(); if ("GET" .equals(method)){ doGet(); } else if ("POST" .equals(method)){ doPost(); } System.out.println("service 被访问了!!" ); } public void doGet () { System.out.println("get 请求" ); System.out.println( "get 请求" ); } public void doPost () { System.out.println("doPost请求" ); System.out.println("doPost请求" ); } @Override public String getServletInfo () { return null ; } @Override public void destroy () { } }
通过继承 HttpServlet 实现Servlet 程序 一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序
编写一个类去继承 HttpServlet 类
根据业务需要重写 doGet 或 doPost 方法
到 web.xml 中的 配置 servlet 程序的访问地址
servlet 类代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.cs7eric.servlet;import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;public class HelloServlet3 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("get 请求" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("post 请求" ); } }
web.xml 配置代码 1 2 3 4 5 6 7 8 <servlet > <servlet-name > HelloServlet3</servlet-name > <servlet-class > com.cs7eric.servlet.HelloServlet3</servlet-class > </servlet > <servlet-mapping > <servlet-name > HelloServlet3</servlet-name > <url-pattern > /hello3</url-pattern > </servlet-mapping >
Servlet 类 的继承体系
ServletConfig 类
ServletConfig 类从类名上看,就知道是 Servlet 程序的配置信息类
Servlet 程序 和 ServletConfig 对象都是由 Tomcat 创建,我们负责使用
Servlet程序默认是第一次访问的时候创建的,ServletConfig 是每个 Servlet程序创建时,就创建一个对应的 ServletConfig 对于旋风
ServletConfig 类的三大作用
可以获取Servlet 程序的别名 servlet-name 的值
获取初始化参数 init-parm
获取 ServletContext 对象
web.xml 中的配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <servlet > <servlet-name > HelloServlet</servlet-name > <servlet-class > com.cs7eric.servlet.HelloServlet</servlet-class > <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 程序 1 2 3 4 5 6 7 8 9 10 11 12 13 @Override public void init (ServletConfig servletConfig) throws ServletException { super .init(servletConfig); System.out.println("HelloServlet 的init 方法" ); System.out.println("----------------------------------" ); System.out.println("HelloServlet 程序的别名:" + servletConfig.getServletName()); System.out.println("初始化参数 username 的值:" + servletConfig.getInitParameter("username" )); System.out.println("初始化参数 url 的值:" + servletConfig.getInitParameter("url" )); System.out.println(servletConfig.getServletContext()); }
ServletContext 类
什么是 ServletContext
ServletContext 是一个接口,他表示 Servlet 上下文对象
一个 web 工程,只有一个 ServletContext 对象实例
ServletContext 对象是一个域对象
ServletContext 是在 web 工程部署启动的时候创建,在 web 工程停止的时候销毁
什么是域对象
域对象,是可以像 Map 一样存取数据的对象,叫做域对象
这里的域指的是 存取数据的操作范围,整个 web 工程
存数据
取数据
删除数据
Map
put()
get()
remove()
域对象
setAttribute()
getAttribute()
removeAttribute()
ServletContext 类的四个作用
获取 web.xml 中配置的上下文参数 context-param
获取当前的工程路径,格式:/工程路径
获取工程部署后在服务器硬盘上的绝对路径
像 Map 一样存取数据
获取参数 Servlet 程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { javax.servlet.ServletContext context = getServletConfig().getServletContext(); String username = context.getInitParameter("username" ); System.out.println("context-param 参数 username 的值是:" + username); System.out.println("context-param 参数 password 的值是:" + context.getInitParameter("password" )); System.out.println("当前工程路径:" + context.getContextPath()); System.out.println("工程部署的路径是:" + context.getRealPath("/" )); System.out.println("工程 css 目录的绝对路径是" + context.getRealPath("/css" )); System.out.println("工程下 img 目录下 1.png的绝对路径:" + context.getRealPath("/imgs/1.png" )); }
web.xml 文件 1 2 3 4 5 6 7 8 9 <context-param > <param-name > username</param-name > <param-value > context</param-value > </context-param > <context-param > <param-name > password</param-name > <param-value > root</param-value > </context-param >
像 Map 一样存取数据 ServletContext3 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.cs7eric.servlet; import javax.servlet.*;import javax.servlet.ServletContext;import javax.servlet.http.*;import java.io.IOException;public class ServletContext3 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 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" )); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
ServletContext2 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.cs7eric.servlet; import javax.servlet.*;import javax.servlet.ServletContext;import javax.servlet.http.*;import java.io.IOException;public class ServletContext2 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); System.out.println(context); System.out.println("Context2 中获取域数据 key1的值是:" + context.getAttribute("key1" )); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
HTTP 协议
什么是 HTTP 协议 什么是协议 协议是指双方,或者多方,相互约定好,大家都需要遵守的规则,叫协议
HTTP 协议 客户端与服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。
HTTP 协议中的数据又叫 报文
请求的 HTTP 协议格式 客户端给服务器发送数据叫请求
服务器给客户端发送数据叫响应
请求又分为 GET 请求和 POST 请求两种
GET 请求
请求行
请求的方式 GET
请求的资源路径 [+ ? + 请求参数]
请求的协议的版本号 HTTP/1.1
请求头
key :value 组成 不同的键值对,表示不同的含义
POST 请求
请求行
请求的方式 POST
请求的资源路径 [ + ? + 请求参数]
请求的协议版本号 HTTP/1.1
请求头
请求体 就是发送给服务器的数据
常用请求头的说明
Accept:表示客户端可以接收的数据类型
Accept-Languege : 表示客户端可以接收的语言类型
User-Agent : 表示客户端浏览器的信息
Host :表示请求时的 服务器的 ip 和端口号
GET / POST 请求 GET 请求
form 标签 method=get
a 标签
link 标签引入 css
Script 标签 引入 js 文件
img 标签引入图片
iframe 引入 HTML 页面
在浏览器地址栏中输入地址后敲回车
POST 请求
form 标签 method=post
响应的 HTTP 协议格式
响应行
响应头
响应体 就是回传给客户端的数据
常用的响应码
200
表示请求成功
302
表示请求重定向
404
表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
500
表示服务器已经收到请求了,但是服务器内部错误(代码错误)
MIME 类型说明 MIME是 HTTP 协议中的数据类型
全称是: Multipurpose Internet Mail Extensions 多功能 Internet 邮件扩充服务。MIME 类型的格式是 ” 大类型/小类型“,并与某一种文件的扩展名相对应
常见的MIME 类型
文件
MIME 类型
超文本标记语言文本
.html, .htm text/html
普通文本
.txt text/plain
RTF 文本
.rtf application/rtf
GIF 图形
.gif image/gif
JPEG 图形
.jpeg, .jpg image/jpeg
au 声音文件
.au audio/basic
MIDI 音乐文件
mid,.midi audio/midi audio/x-midi
RealAudio 音乐文件
.ra, .ram audio/x-pn-realaudio
MPEG 文件
.mpg,.mpeg video/mpeg
AVI 文件
.avi video/x-msvideo
GZIP 文件
.gz application/x-gzip
TAR 文件
.tar application/x-tar
HttpServletRequest 类
HttpServletRequest 类的作用 每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中,然后传递到 service 方法(doGet 和 doPost) 中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息
HttpServletRequest 的常用方法
getRequestURI()
获取请求的资源路径
getRequestURL()
获取请求的统一资源定位符(绝对路径)
getRomoteHost()
获取客户端的 IP 地址
getHeader()
获取请求头
getParameter()
获取请求的参数
getParameterValues()
获取请求的参数(多个值的时候使用)
getMethodA()
获取请求的方式 GET 或者 POST
setAttribute(key,value)
设置域数据
getAttribute(key)
获取域数据
getRequestDispatcher()
获取请求转发对象
常用 API 代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package com.cs7eric.servlet2; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;public class RequestAPIServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("URI:" + request.getRequestURI()); System.out.println("URL:" + request.getRequestURL()); System.out.println("客户端地址:" + request.getRemoteHost()); System.out.println("请求头 User-agent:" + request.getHeader("User-agent" )); System.out.println("请求的方式:" + request.getMethod()); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
如何获取请求参数 GET java 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.cs7eric.servlet2; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;import java.util.Arrays;public class ParameterServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username" ); String password = request.getParameter("password" ); String[] hobbies = request.getParameterValues("hobby" ); System.out.println("用户名:" + username); System.out.println("密码:" + password); System.out.println("兴趣爱好" + Arrays.asList(hobbies)); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
html 页面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <form action ="http://localhost:8088/servlet2_war/parameterServlet" method ="get" > 用户名:<input type ="text" name ="username" > <br /> 密码: <input type ="password" 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" > JS <input type ="submit" > </form > </body > </html >
doGet 请求的中文乱码解决 1 2 3 4 5 6 String username = request.getParameter("username" ); username = new String (username.getBytes("iso-8859-1" ),"UTF-8" );
POST html 页面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <form action ="http://localhost:8088/servlet2_war/parameterServlet" method ="get" > 用户名:<input type ="text" name ="username" > <br /> 密码: <input type ="password" 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" > JS <input type ="submit" > </form > </body > </html >
POST 请求的中文乱码解决 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8" ); System.out.println("--------------- doPost---------------" ); String username = request.getParameter("username" ); String password = request.getParameter("password" ); String[] hobbies = request.getParameterValues("hobby" ); System.out.println("用户名:" + username); System.out.println("密码:" + password); System.out.println("兴趣爱好" + Arrays.asList(hobbies)); }
请求转发 服务器收到请求后,从一个资源跳转到另一个资源的操作叫做请求转发
Servlet1 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package com.cs7eric.servlet2; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;public class Servlet1 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username" ); System.out.println("在 Servlet1 (柜台 1) 中查看参数(材料) :" + username ); request.setAttribute("key1" ,"柜台一的章" ); RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2" ); requestDispatcher.forward(request,response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
Servlet 2 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.cs7eric.servlet2; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;public class Servlet2 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username" ); System.out.println("在 Servlet 2 (柜台2) 中查看材料" + username); Object key1 = request.getAttribute("key1" ); System.out.println("Servlet 1 (柜台 1) 是否有章" + key1); System.out.println("Servlet 2 处理自己的业务" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
base 标签 base 标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转
c.html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <base href ="http://localhost:8088/servlet2_war/a/b/" > </head > <body > 这是 a 下的 b 下的 c.html 页面<br /> <a href ="../../index.jsp" > 跳回首页</a > <br /> </body > </html >
Web 中的相对路径和绝对路径 在JavaWeb 中,路径分为相对路径和绝对路径两种
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径
绝对路径
base + 相对
web 中 / 斜杠的不同意义 在 web 中 / 斜杠是一种绝对路径
/ 斜杠 如果被浏览器解析,得到的地址是 : http://ip:port/
<a href="/"> 斜杠 <a/>
/ 斜杠如果被服务器解析,得到的地址是 :http://ip:port/工程路径
<url-pattern>/servlet<url-pattern/>
servletContext.getReallPath("/");
request.getRequestDispatcher("/");
特殊情况: response.sendRediect("/"); 将斜杠发送给服务器解析。得到 http://ip:port/
HttpServletResponse 类
HttpServletResponse 类的作用 HttpServletResponse 类 和 HttpServletRequest 类一样,每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所以响应信息
如果我们需要设置返回客户端的信息,都可以通过 HttpServletResponse 对象来进行设置
两个输出流的说明
字节流 getOutputStream(); 常用于下载(传递二进制数据)
字符流 getWriter(); 常用于回传字符串(常用)
两个流同时只能使用一个
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错
如何往客户端回传数据 要求:往客户端回传 字符串 数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.cs7eric.servlet2; import javax.servlet.*;import javax.servlet.http.*;import java.io.IOException;import java.io.PrintWriter;public class ResponseIOServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter writer = response.getWriter(); writer.write("response's context" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
响应的乱码解决 方案一(不推荐使用) 1 2 3 4 response.setCharacterEncoding("UTF-8" ); response.setHeader("Context-Type" ,"text/html;charset=UTF-8" );
方案二(推荐) 1 2 3 response.setContentType("text/html;charset=UTF-8" );
请求重定向 请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址,你去新地址访问,叫请求重定向(因为之前的地址可能已经被废弃)
请求重定向的第一种方案 1 2 3 4 response.setStatus(302 ); response.setHeader("Location" ,"http://localhost:8088" );
请求重定向的第二种方案(推荐使用) 1 response.sendRedirect("http://loacalhost:8088" );
JSP 为什么学习 JSP 技术
什么是 JSP JSP (全称 Java Server Pages)是由 Sun 公司专门为了解决动态生成 HTML 文档的技术
Servlet 程序输出 HTML 页面 在学习 jsp 技术之前,如果我们要往 客户端 输出一个 页面,我们可以使用Servlet 程序来实现。
但是通过 Servlet 程序 输出简单的 HTML 页面都非常不方便,如果我们要输出一个复杂页面的时候,就更加的困难,而且不利于页面的维护和调试,所以 SUN 公司推出一种叫做 jsp 的 动态页面技术帮助我们实现对页面的输出繁琐工作
jsp 页面的访问千万不能像 HTML 一样。托到浏览器 中。只能通过浏览器访问 Tomcat 服务器再访问 jsp 页面
如何访问 jsp 文件 jsp 页面和 HTML 页面一样,都是存放在 web 目录下,访问也跟 HTML 一样
比如: 在 web 目录下有如下的文件
web 目录
a.html 页面 访问地址就是 ——————–》 http://ip:port/工程路径/a.html
b.jsp 页面 访问地址就是———————-》 http://ip:port/工程路径/b.jsp
jsp 的本质 jsp 页面本质上是一个 Servlet 程序
当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 Java 源文件,并且对它编译成为 .class 字节码程序。当我们 打开 Java 源文件不难发现其里面的内容是
我们跟踪源代码发现,HttpJspBase 类。它直接继承了 HttpServlet 类,也就是说,jsp 翻译出来的 Java 类,它间接继承了 HttpServlet 类,也就是说,翻译出来的是一个 Servlet 程序
总结:通过翻译的 Java 源代码,我们就可以得到结果: jsp 就是 Servlet 程序
观察 翻译出来的 Servlet 源码,不难发现。其底层实现,也是通过 输出流。把 HTML 页面 数据回传给客户端
JSP 语法
jsp 头部的 page 指令 jsp 的 page 指令可以修改 jsp 页面中一些重要的属性或者 行为
1 <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
language 属性 表示 jsp 翻译后是什么语言文件。暂时只支持 Java
contextType 属性 表示 jsp 返回的数据类型是什么,也是 源码中的 response.setContextType() 参数值
pageEncoding 属性 表示当前 jsp 页面文件本身的字符集
import 属性 跟Java 源码一样,用于导包、导类
out 输出流使用
autoFlash 属性 设置当 out 输出流缓冲区满了之后,是否自动刷新缓冲区。默认值为 true;
buffer 属性 设置 out 缓冲区的大小,默认是 8kb
缓冲区溢出错误
java.io.IOException:Error:JSP Buffer overflow
errorPage 属性 设置当 jsp 页面运行出错,自动跳转去的错误页面路径
errorPage 表示 错误后自动跳转的路径,这个路径一般都是以斜杠打头,他表示请求地址为 http://ip:port/工程路径/
映射到 代码的 web 目录
isErrorPage 属性 设置当前jsp 页面是否是错误信息页面,默认是 false,如果是 true,可以获取异常信息
session 属性 设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true
extends 属性 设置 jsp 翻译出来的 Java 类默认继承谁、
jsp 中常用的脚本 声明脚本(极少使用) 声明脚本的格式是<% 声明 Java 代码%>
作用:可以给 翻译出来的 Java 类 定义属性和方法甚至是 静态代码块,内部类等
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <%-- 1. 声明类属性 --%> <%! private Integer id; private String name; private String phone; private static Map<Integer,String> map; %> <%-- 2. 声明 static 静态代码块 --%> <%! static { map = new HashMap <Integer,String>(); map.put(1 ,"csq" ); map.put(2 ,"cym" ); map.put(3 ,"rbb" ); } %> <%-- 3. 声明类方法 --%> <%! public int add () { return 1 ; } %> <%-- 4. 声明内部类 --%> <%! public static class A { private Integer id = 0 ; private String abc = "abc" ; } %>
表达式脚本(常用) 表达式脚本的格式是 :<%= 表达式 %>
表达式脚本的作用是:在 jsp 页面上输出数据
表达式脚本的特点
所有的表达式脚本都会被翻译到 _jspService() 中
表达式脚本都会被翻译成为 out.print() 输出到页面上
由于表达式脚本翻译的内容都在 _jspService() 方法中,所有 jspService() 方法中的对象都可以直接使用
表达式脚本中的表达式 不能以分好结束
1 2 3 4 5 <%=12 %> <br> <%=12.12 %> <br> <%="我是字符串" %> <br> <%=map%> <br> <%=request.getParameter("username" )%>
代码脚本 代码脚本的格式是:
代码脚本的作用是:可以在 jsp 页面中,编写我们自己需要的功能(写的是 Java语句)
代码脚本的特点
代码脚本翻译之后都在 jspService() 方法中
代码脚本由于被翻译到 _jspService() 方法中,所以在方法中的现有对象都可以直接使用
还可以由多个 代码脚本组合完成一个完整的 Java语句
代码脚本还可以和表达式脚本一起使用,在 jsp页面上输出数据
jsp 中 的三个注释 HTML 注释 <!-- 这是 HTML 注释 -->
HTML 注释会被翻译到 Java 源代码中,在 _jspService() 方法中,以 out.print() 输出到客户端
Java 注释
Java 注释会被翻译到 Java 源码中
jsp 注释 <%-- 这是 jsp 注释--%>
jsp 注释可以注掉,jsp 页面中的所有代码
jsp 九大内置对象
jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面成为 Servlet 源码之后,内部提供的 九大对象,叫 内置对象
request 请求对象
response 响应对象
pageContext jsp 的上下文对象
session 会话对象
application ServletContext 对象
config ServletConfig 对象
out jsp 输出流对象
page 指向当前 jsp 的对象
exception 异常对象
jsp 四大域对象
四个域对象分别是
pageContext (PageContextImpl 类) 当前 jsp 页面范围内有效
request ( HttpServletRequest 类) 一次请求内有效
session (HttpSession 类) 一次会话范围内有效(打开浏览器访问服务器,知道关闭浏览器)
application (ServletContext 类) 整个web 工程范围内都有效(只要 web 工程不停止,数据都在)
域是可以像 Map 一样存取数据的对象,四个域对象功能一样,不同的是 他们对数据的存取翻译
pageContext —> request —> session —> application
jsp out 输出和 response.getWriter
response 中表示响应,我们经常用于设置返回 客户端的内容(输出)
out 也是给用户输出使用的
当jsp 页面中所有代码执行完成之后会做一下两个操作
执行 out.flush() 操作,会把 out 缓冲区中的数据追加写入到 response 缓冲区 末尾
会执行 response 的刷新操作,把全部数据写给客户端
由于 jsp 翻译之后,底层源码都是使用 out 来进行输出,所以一般情况下,我们在jsp 页面中统一使用 out 来进行输出。避免扰乱页面输出内容的顺序
深入源码,浅出结论 : 在 jsp 页面中,可以统一使用 out.print() 来进行输出
jsp 常用标签
静态包含
就是静态包含
file 属性指定你要包含的 jsp 页面的路径
地址中的 第一个 斜杠 / 表示 http://ip:port/工程路径/ 映射到代码的 web 目录
静态包含的特点
静态包含 不会翻译被包含的 jsp 页面
静态包含其实是把 被包含的 jsp 页面的代码 拷贝 到包含的位置 执行输出
jsp 动态包含 1 <jsp:include page="" ></jsp:include>
这是 动态包含
page 属性是指定你要包含的 jsp 页面的 路径
动态包含也可以像动态包含一样。把被包含的内容执行输出到包含位置
动态包含的特点
动态包含会把包含的 jsp 页面也翻译成为 Java 代码
动态包含底层代码使用如下代码去掉用被包含的 jsp 页面 执行输出
JspRnutimeLibrary.include(request,response,"/include/footer.jsp",out,false);
动态包含,还可以传递参数
1 2 3 4 <jsp:include page="/include/footer.jsp" > <jsp:param name="username" value="bbj" /> <jsp:param name="password" value="root" /> </jsp:include>
动态包含的底层原理
jsp 标签-转发 1 <jsp:forward page="" ></jsp:forward>
这是请求转发标签,它的功能就是请求转发
page 属性设置请求转发的路径
练习
jsp 输出一个表格,里面有十个 学生信息
searchStudentServlet 程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package com.cs7eric.jsp.servlet;import com.cs7eric.jsp.pojo.Student;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.ArrayList;import java.util.List;public class searchStudentServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Student> list = new ArrayList <Student>(); for (int i = 0 ; i < 10 ; i++) { int t = i + 1 ; list.add(new Student (t,"name" +t,"phone" +t,t+18 )); } request.setAttribute("list" ,list); request.getRequestDispatcher("showStudent.jsp" ).forward(request, response); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
showStudent.jsp 页面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <%@ page import ="com.cs7eric.jsp.pojo.Student" %> <%@ page import ="java.util.List" %><%-- Created by IntelliJ IDEA. User: CSQ-PC Date: 2022 /11 /3 Time: 20 :20 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> table{ border:1px blue solid; width:600px; border-collapse:collapse; } td,th{ border:1px blue solid; } </style> </head> <body> <% List<Student> stuList = (List<Student>) request.getAttribute("list" ); %> <table> <tr> <td>编号</td> <td>姓名</td> <td>年龄</td> <td>电话</td> <td>操作</td> </tr> <%for (Student student : stuList){%> <tr> <td><%=student.getId() %>></td> <td><%=student.getName() %></td> <td><%=student.getAge()%>></td> <td><%=student.getPhone()%>></td> <td>删除、修改</td> </tr> <%}%> </table> </body> </html>
Listenser 监听器
Listener 监听器是 JavaWeb 的 三大组件之一。Java 的三大组件分别是:Servlet 程序、Fliter 过滤器、Listener 监听器
Listener它是 JavaEE 的规范,就是 接口
监听器的作用是:监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理
ServletContextListener 监听器 ServletContextListener 它可以监听ServletContext 对象的创建和销毁
ServletContext 对象在 web 工程启动的时候创建,在 web 工程停止的时候 销毁
监听到 创建和销毁之后都会分别调用 ServletContextListener 监听器的方法去反馈
两个方法分别是:
Listener.java 1 2 3 4 5 6 7 8 9 10 11 12 public class Listener implements ServletContextListener , HttpSessionListener, HttpSessionAttributeListener { @Override public void contextInitialized (ServletContextEvent sce) { } @Override public void contextDestroyed (ServletContextEvent sce) { } }
web.xml 配置 1 2 3 <listener > <listener-class > com.cs7eric.jsp.listener.Listener</listener-class > </listener >
EL 表达式 EL 表达式介绍
EL 表达式的全称是 Expression Language 。是 表达式语言
EL 表达式介绍 EL表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出
因为 EL 表达式在输出数据的时候,要 比 jsp 的表达式脚本简洁很多
1 2 3 4 5 6 <% request.setAttribute("key" ,"值" ); %> 表达式脚本输出的key 值是: <%=request.getAttribute("key" )==null ?"" :request.getAttribute("key" )%> <br> EL 表达式输出key 的值是 :${key}
EL 表达式格式
EL 表达式在输出 null 值得时候,输出的是空串。jsp 表达式脚本输出 null 值的 时候,输出的是 null 字符串
EL 表达式搜索域数据的顺序
EL 表达式主要实在 jsp 页面中输出数据
主要是输出域对象中的数据
当四个域中都有相同的 key 的数据的时候,EL 表达式会按照四个域的从小到大的顺序去搜索,找到就输出
1 2 3 4 5 6 7 8 9 10 <body> <% request.setAttribute("key" ,"request" ); session.setAttribute("key" ,"session" ); application.setAttribute("key" ,"application" ); pageContext.setAttribute("key" ,"pageContext" ); %> ${ key } </body>
EL 表达式输出属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <body> <% Person person = new Person (); person.setName("cs7eric" ); person.setPhones(new String []{"123" ,"456" ,"789" }); List<String> cities = new ArrayList <String>(); cities.add("北京" ); cities.add("南京" ); person.setCities(cities); Map<String,Object> map = new HashMap <String,Object>(); map.put("key1" ,"value1" ); map.put("key2" ,"value2" ); map.put("key3" ,"value3" ); person.setMap(map); pageContext.setAttribute("person" ,person); %> 输出 person:${person} <br> 输出 person 的 name 属性: ${person.name} <br> 输出person 的phones 属性: ${person.phones[2 ]} <br> 输出person 的cities集合中元素值 :${person.cities} <br> 输出person 的LIst 集合中个别元素值 :${person.cities[2 ]} 输出person 的Map 集合:${person.map} <br> 输出person 的Map 集合个别元素值:${person.map.key3} <br> 输出 person 的 age 属性: ${person.age} <br> </body>
EL 表达式-运算
语法:
关系运算
关系运算符
说 明
范 例
结果
== 或 eq
等于
${ 5 == 5 } 或 ${ 5 eq 5 }
true
!= 或 ne
不等于
${ 5 !=5 } 或 ${ 5 ne 5 }
false
< 或 lt
小于
${ 3 < 5 } 或 ${ 3 lt 5 }
true
> 或 gt
大于
${ 2 > 10 } 或 ${ 2 gt 10 }
false
<= 或 le
小于等于
${ 5 <= 12 } 或 ${ 5 le 12 }
true
>= 或 ge
大于等于
${ 3 >= 5 } 或 ${ 3 ge 5 }
false
逻辑运算
逻辑运算符
说 明
范 例
结果
&& 或 and
与运算
${ 12 == 12 && 12 < 11 } 或 ${ 12 == 12 and 12 < 11 }
false
|| 或 or
或运算
${ 12 == 12 || 12 < 11 } 或 ${ 12 == 12 or 12 < 11 }
true
! 或 not
取反运算
${ !true } 或 ${not true }
false
算数运算
算数运算符
说 明
范 例
结果
+
加法
${ 12 + 18 }
30
-
减法
${ 18 - 8 }
10
*
乘法
${ 12 * 12 }
144
/ 或 div
除法
${ 144 / 12 }
或
% 或 mod
取模
${ 144 % 10 }
或
empty 运算 empty 运算可以判断一个数据是否为空,如果为空,则输出 true,不空 则为 false
以下几种情况为空
值为 null 值 的时候,为空
值为空串的时候,为空
值是 Object 类型数组,长度为 0 的时候
list 集合,元素个数为 0
map 集合,元素个数为 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <body> <% request.setAttribute("emptyNull" ,null ); request.setAttribute("emptyStr" ,"" ); request.setAttribute("emptyArr" ,new Object []{}); List<Object> list = new ArrayList <>(); request.setAttribute("emptyList" ,list); Map<String,Object> map = new HashMap <String,Object>(); request.setAttribute("emptyMap" ,map); %> ${empty emptyNull} <br> ${empty emptyStr} <br> ${empty emptyArr} <br> ${empty emptyList} <br> ${empty emptyMap} <br> </body>
三元运算 表达式 1? 表达式 2: 表达式 3 如果表达式 1 的值为真, 返回表达式 2 的值, 如果表达式 1 的值为假, 返回表达式 3 的值。
” . “ 点运算 和 [] 中括号运算符 .点运算, 可以输出 Bean 对象中某个属性的值。 []中括号运算, 可以输出有序集合中某个元素的值。 并且[]中括号运算, 还可以输出 map 集合中 key 里含有特殊字符的 key 的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <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>
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,Object>
他可以获取请求参数的值
paramValues
Map<String,Object[]>
他可以获取请求参数的值,获取多个值的时候使用
header
Map<String,Object>
他可以获取请求头的信息
headerValues
Map<String,Object[]>
他可以获取请求头的信息,他可以获取多个值的情况
cookie
Map<String,Cookie>
他可以获取当前请求的 cookie 信息
initParam
Map<String,String>
他可以获取在 web.xml 中配置的 上下文参数
EL 获取四个特定域中的属性
pageScope ————– pageContext 域
requestScope ————– request 域
sessionScope ————– session 域
application ————– ServletContext 域
pageContext 对象的使用
协议
服务器 ip
服务器端口
获取工程路径
获取请求方法
获取客户端 IP 地址
获取 会话 的 ID 编号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <body> <%-- request.getScheme() 它可以获取请求的协议 request.getServerName() 获取请求的服务器 ip 或域名 request.getServerPort() 获取请求的服务器端口号 getContextPath() 获取当前工程路径 request.getMethod() 获取请求的方式(GET 或 POST) request.getRemoteHost() 获取客户端的 ip 地址 session.getId() 获取会话的唯一标识 --%> <% pageContext.setAttribute("req" ,request); %> <%=request.getScheme() %> <br> 1. 协议 :${req.scheme} <br>2. 服务器 ip: ${req.serverName} <br>3. 服务器端口: ${req.serverPort} <br>4. **获取工程路径**: ${req.contextPath} <br>5. 获取请求方法: ${req.method} <br>6. 获取客户端 IP 地址 ${req.remoteHost} <br>7. 获取 会话 的 ID 编号 ${pageContext.session.id} <br></body>
EL 表达式其他隐含对象的使用
1 2 3 4 5 6 7 8 9 <body> 输出请求参数 username 的值:${param.username} <br> 输出请求参数 password 的值:${param.password} <br> 输出请求参数 username 的值:${paramValues.username[0 ]} <br> 输出请求参数 hobby 的值:${paramValues.hobby[0 ]} <br> 输出请求参数 hobby 的值:${paramValues.hobby[1 ]} <br> </body>
1 2 3 输出 请求头【User-Agent】的值:${header['User-Agent' ]} <br> 输出 请求头【Connection】的值:${header.Connection} <br> 输出 请求头【User-Agent】的值:${headerValues['User-Agent' ][0 ]} <br>
1 2 输出 < Context-param > username 的值:${initParam.username} <br> 输出 < Context-param > url 的值: ${initParam.url} <br>
JSTL 标签库 JSTL 标签库 全称是 JSP Standard Tag Library ,JSP 标准标签库。是一个不断完善的开源的 JSP 标签库
EL 表达式只要是为了 替换 jsp 中的表达式脚本,而标签库则是为了 替换代码脚本。这样使得整个 jsp 页面变得简洁
JSTL 组成
JSTL 由五个功能不同的标签库组成
在 jsp 标签库中使用 taglib 指令引入标签库
1 2 3 4 5 6 7 8 9 10 CORE 标签库 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> XML 标签库 <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %> FMT 标签库 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> SQL 标签库 <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> FUNCTIONS 标签库 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
JSTL 标签库的使用步骤
先导入 jstl 标签库的 jar 包
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
使用 taglib 指令引入标签库
core 核心库使用
<c:set/>
set 标签可以往域中保存数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <%-- <c:set /> 作用:set 标签可以往域中保存数据 域对象.setAttribute() scope 属性设置保存到哪个域 page 表示 pageContext 域 request 表示 Request 域 session 表示 Session 域 application 表示 ServletContext 域 var 属性设置 key 是多少 value 属性设置值 --%> 保存之前:${sessionScope.abc} <br> <c:set scope="session" var ="abc" value="sessionValue" /> 保存之后:${sessionScope.abc} <br>
<c:if />
if标签 用来做 if 判断
1 2 3 4 5 6 7 8 9 10 11 <%-- <c:if /> if 标签用来做 if 判断 test 属性 表示判断的条件(用 EL 表达式输出) --%> <c:if test="${12 == 12}" > <h1>12 等于 12 </h1> </c:if > <c:if test="${12 != 12}" > <h2>不等于</h2> </c:if >
<c:choose><c:when><c:otherwise>
多路判断。跟 switch…case…default 非常相近
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <%-- 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" ,180 ); %> <c:choose> <c:when test="${requestScope.height > 190}" > <h1>小巨人</h1> </c:when> <c:when test="${requestScope.height > 180}" > <h1>很高</h1> </c:when> <c:otherwise> <c:choose> <c:when test="${requestScope.height >160}" > <h1>大于160 </h1> </c:when> <c:otherwise> 其他小于160 </c:otherwise> </c:choose> </c:otherwise> </c:choose>
<c:foreach/>
遍历输出使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 <%@ page import ="java.util.Map" %> <%@ page import ="java.util.HashMap" %> <%@ page import ="com.cs7eric.el_jstl.pojo.Person" %> <%@ page import ="java.util.List" %> <%@ page import ="java.util.ArrayList" %> <%@ page import ="com.cs7eric.el_jstl.pojo.Student" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: CSQ-PC Date: 2022 /11 /4 Time: 15 :00 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> table{ border:1px blue solid; width:600px; border-collapse:collapse; } td,th{ border:1px blue solid; } </style> </head> <body> <%--1. 遍历 1 到 10 , 输出 begin 属性设置开始的索引 end 属性设置结束的索引 var 属性表示循环的变量(也是当前正在遍历到的数据) for (int i = 1 ; i < 10 ; i++) --%> <table border="1" > <c:forEach begin="1" end="10" var ="i" > <tr> <td>第${i} 行</td> </tr> </c:forEach> </table> ------------------------------------- <br> <% request.setAttribute("arr" ,new String []{"123" ,"234" ,"456" }); %> <c:forEach items="${requestScope.arr}" var ="item" > ${item} <br> </c:forEach> --------------------------------------- <br> <% Map<String,String> map = new HashMap <String,String>(); map.put("1" ,"11" ); map.put("2" ,"12" ); map.put("3" ,"13" ); request.setAttribute("map" ,map); %> <c:forEach items="${requestScope.map}" var ="entry" > <h1>${entry.key} == ${entry.value}</h1> </c:forEach> ------------------------------------------------------ <br> <% List<Student> stuList = new ArrayList <Student>(); for (int i = 0 ; i < 10 ; i++) { stuList.add(new Student (i,18 +i,"name" +i,"110" +i)); } request.setAttribute("stuList" ,stuList); %> <table> <tr> <th>id</th> <th>年龄</th> <th>名字</th> <th>电话</th> <th>操作</th> </tr> <c:forEach begin="1" end="10" varStatus="status" items="${requestScope.stuList}" var ="stu" > <tr> <td>${stu.id}</td> <td>${stu.age}</td> <td>${stu.name}</td> <td>${stu.phone}</td> <td>${status.index}</td> </tr> </c:forEach> </table> </body> </html>
文件的上传与下载 文件的上传和下载,是非常常见的功能,很多的系统中,或者软件中都经常使用文件的上传和下载
文件的上传
文件上传的介绍
要有一个 form 标签,method=post 请求
form 标签的 encType 属性值必须为 multipart/form-data 值
在 form 标签中使用 input type=file 添加上传的文件
编写服务器代码(Servlet 程序) 接受,处理上传的数据
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段) 的形式进行拼接,然后以二进制流的形式发送服务器
文件上传,HTTP 协议的说明
commons-fileupload.jar 常用 API 说明 commons-fileipload.jar 需要依赖 commons-io.jar 这个包,所以两个包都要引入
引入以下两个 jar 包
commons-fileupload.jar
commons-io.jar
ServletFileUpload 类 用于解析上传的数据
FileItem类 表示每一个表单项
boolean ServletFileUpload.isMutipartContent(HttpServletRequest rquest) 判断当前上传的数据格式是否是多段的格式
public List <FileItem > parseRequest(HttpServletRequest request) 解析上传的数据
判断当前这个表单项,是否是普通的表单项。还是上传的文件类型
true:表示普通类型的表单项
false:表示上传的文件类型
String FileItem.getFieldName() 获取表单项的 name 属性值
String FileItem.getString() 获取当前表单项的值
String FileItem.getName() 获取上传的文件名
void FileItem.write(File) 将上传的文件 写到参数 file 所指向所写硬盘位置
文件上传操作 上传文件的表单 upload.jsp 1 2 3 4 5 <form action="Http://localhost:8088/file/uploadServlet" method="post" encType="multipart/form-data" > 用户名:<input type="text" name="username" /> <br> 头像 :<input type="file" name="photo" > <br> <input type="submit" value="上传" > </form>
Servlet 程序 uploadServlet.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (ServletFileUpload.isMultipartContent(request)){ FileItemFactory fileItemFactory = new DiskFileItemFactory (); ServletFileUpload servletFileUpload = new ServletFileUpload (fileItemFactory); servletFileUpload.setHeaderEncoding("UTF-8" ); try { List<FileItem> list = servletFileUpload.parseRequest(request); for (FileItem fileItem : list){ if (fileItem.isFormField()){ System.out.println("表单项的 name 属性值:" + fileItem.getFieldName()); System.out.println("表单项的 value 值:" + fileItem.getString("UTF-8" )); } else { System.out.println("表单的 name 属性值:" + fileItem.getFieldName()); System.out.println("上传的文件名:" + fileItem.getName()); fileItem.write(new File ("e:\\" + fileItem.getName())); } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
文件下载
常用 API 说明
response.getOutputStream()
servletContext.getResourceAsStream()
servletContext.getMimeType()
response.getContentType()
response.setHeader(“Content-Disposition”,”attachment;fileName=1.jpg);
这个响应头告诉浏览器,这是需要下载的,而 **attachment **表示附件,也就是下载的一个文件, fileName=后面 表示下载的文件名
完成上面的两个步骤,下载文件是没问题了,但是如果我们要下载的文件 是中文名的话,下载无法显示出正确的中文名
原因是 在响应头中,不能包含有中文字符,只能包含 ASCII 码
文件下载示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String downloadFileName = "abc.png" ; String str = "attachment;fileName" + URLEncoder.encode(downloadFileName,"UTF-8" ); response.setHeader("Content-Disposition" ,str); ServletContext servletContext = getServletContext(); String mimeType = servletContext.getMimeType("/file/" + downloadFileName); response.setContentType(mimeType); System.out.println(downloadFileName); InputStream resourceStream = servletContext.getResourceAsStream("/file/" + downloadFileName); OutputStream outputStream = response.getOutputStream(); IOUtils.copy(resourceStream,outputStream); }
Cookie 与 Session Cookie
Cookie 是服务器通知客户端保存键值对的一种技术,客户端有了 Cookie 后,每次请求都发送给服务器,每个Cookie的大小不能超过 4kb
如何创建 Cookie
1 2 3 4 5 6 7 8 9 10 11 12 protected void createCookie (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie ("key1" , "value1" ); resp.addCookie(cookie); Cookie cookie1 = new Cookie ("key2" , "value2" ); resp.addCookie(cookie1); resp.getWriter().write("Cookie 创建成功" ); }
服务器如何获取 Cookie 服务器获取 Cookie,只需要一行代码\
TODO 图片
Cookie 工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 protected void getCookies (HttpServletRequest req, HttpServletResponse resp) throws IOException { Cookie[] cookies = req.getCookies(); for (Cookie cookie : cookies){ resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "]<br/>" ); Cookie iWantCookie = CookieUtils.findCookie("key1" ,cookies); if (iWantCookie != null ){ resp.getWriter().write("找到了需要的Cookie" ); } }
Cookie 值 的修改 方案一
先创建一个要修改的同名(指的就是 key) 的Cookie 对象
在构造器,同时赋予 新的 Cookie 值
调用 response.addCookie(Cookie)
1 2 Cookie cookie = new Cookie ("key1" ,"value1" );response.addCookie(cookie);
方案二
先查找到需要修改的 Cookie 对象
调用 setValue() 方法赋予新的 Cookie 值
调用 response.addCookie() 通知客户端保存修改
1 2 3 4 5 6 7 8 Cookie cookie = CookieUtils.findCookie("key2" ,req.getCookies());if (cookie != null ){ cookie.setValue("newValue2" ); response.addCookie(cookie); }
浏览器查看 Cookie F12 - Application
Cookie 生命控制 Cookie的生命控制指的是 如何管理 Cookie 什么时候被销毁
setMaxAge()
正数:表示在指定的秒数后会过期
负数:表示浏览器一关,Cookie 就会删除(默认值是 - 1)
0:表示马上删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 protected void life3600 (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = new Cookie ("life3600" , "life3600" ); cookie.setMaxAge(60 * 60 ); resp.addCookie(cookie); resp.getWriter().write("已经创建了一个存活一小时的Cookie" ); } protected void deleteNow (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie cookie = CookieUtils.findCookie("key4" , req.getCookies()); if (cookie != null ) { cookie.setMaxAge(0 ); resp.addCookie(cookie); resp.getWriter().write("key4的Cookie已经被删除" ); } }
Cookie 有效路径 Path 的设置 Cookie 的 path 属性 可以有效的过滤哪些 Cookie 可以发送给服务器,哪些不发
path 属性 是通过请求的地址来进行有效的过滤
CookieA path=/工程路径/
CookieB path=/工程路径/abc
请求地址如下
Cookie 练习——免输入用户名登录
login.jsp 页面 1 2 3 4 5 <form action="http://localhost:8088/cookie_session/loginServlet" method="get" > <input type="text" name="username" value="${cookie.username.value}" > <br> <input type="password" name="password" > <input type="submit" value="登录" > </form>
LoginServlet.java 程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username" ); String password = request.getParameter("password" ); if ("cs7eric" .equals(username) && "C020611." .equals(password)){ Cookie cookie = new Cookie ("username" ,username); cookie.setMaxAge(60 * 60 * 24 * 7 ); response.addCookie(cookie); System.out.println("Success" ); } else { System.out.println("Failed" ); } }
Session 会话
什么是 Session 会话
Session 就是一个接口(HttpSession)
Session 就是会话,它是用来维护一个客户端和服务器之间关联的一种技术
每个客户端都有自己的一个 Session 会话
Session 会话中,我们经常用来保存用户登录之后的信息
如何创建 Session 和获取(ID号是否为新) 如何创建和获取— 他们的 API 是一样的
request.getSession()
第一次调用是:创建 Session 会话
之后调用都是:获取前面创建好的 Session 会话对象
isNew(); 判断是不是刚创建的(新的)
true:表示刚创建
false:表示获取之前创建
每个会话都会有一个身份证号,也就是 ID 值。而且这个ID 值是唯一的
getId()
获得Seesion 会话 的 ID 值
Session 域数据的存取 1 2 3 4 5 6 7 8 9 10 protected void setAttribute (HttpServletRequest req, HttpServletResponse resp) throws IOException { req.getSession().setAttribute("key1" ,"value1" ); resp.getWriter().write("已经往 Session 保存了数据" ); } protected void getAttribute (HttpServletRequest req, HttpServletResponse resp) throws IOException { Object attribute = req.getSession().getAttribute("key1" ); resp.getWriter().write("从 Session 域中取出的数据是" + attribute); }
Session 生命周期控制 public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长。Session就会被销毁
值为整数的时候,设定Session 的超时时长
负数表示永不超时(极少使用)
public int getMaxInactiveInterval() 获取 Session 超时的时间
public void invalidate() 让当前 Session 会话马上超时无效
Session 默认的超时时长是 30 分钟
因为在 Tomcat服务器的配置文件 web.xml 中默认有以下的配置,它就代表了当前 Tomcat 服务器下所有的 Session超时配置默认时长为 :30分钟
1 2 3 <session-config > <session-timeout > 30</session-timeout > </session-config >
如果说,你希望你的 web 工程,默认的 Session 的超时时长为其他时间,你可以在你自己的 web.xml 配置文件中做以上的配置,就可以修改你的 web 工程所有的 Session 的 默认时长
如果你想只修改个别 Session 的超时时长,就可以使用上面的 API setMaxInactiveInterval(int interval)
Session 超时的概念介绍
浏览器和 Session 之间关联的技术内幕 Session技术,底层其实是基于 Cookie 技术来实现的
Fliter 过滤器 Fliter 过滤器是 JavaWeb 的三大组件之一。三大组件分别是 Servlet 程序、Listener 监听器、Fliter 过滤器
Fliter 简介
Fliter 过滤器是 JavaWeb 的三大组件之一。三大组件分别是 Servlet 程序、Listener 监听器、Fliter 过滤器
Fliter 过滤器它是 JavaEE 的规范,也就是接口
Fliter 过滤器它的作用是:拦截请求 ,过滤响应
应用场景
权限检查
日记操作
事务管理
….
初体验 要求: 在你的 web 工程下, 有一个 admin 目录。 这个 admin 目录下的所有资源(html 页面、 jpg 图片、 jsp 文件、 等等) 都必 须是用户登录之后才允许访问。
思考: 根据之前我们学过内容。 我们知道, 用户登录之后都会把用户登录的信息保存到 Session 域中。 所以要检查用户是否 登录, 可以判断 Session 中否包含有用户登录的信息即可
Fliter 工作流程
fliter代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpSession session = httpServletRequest.getSession(); Object user = session.getAttribute("user" ); if (user == null ){ request.getRequestDispatcher("/login.jsp" ).forward(request,response); return ; } else { chain.doFilter(request, response); } }
web.xml 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <filter > <filter-name > AdminFilter</filter-name > <filter-class > com.cs7eric.filter_.AdminFilter</filter-class > </filter > <filter-mapping > <filter-name > AdminFilter</filter-name > <url-pattern > /admin/*</url-pattern > </filter-mapping >
filter 过滤器的使用步骤
编写一个类去实现 Filter 接口
实现过滤方法 doFilter()
到 web.xml 中去配置 filter 的拦截路径
Filter 的生命周期
Filter 的生命周期包含几个方法
构造方法
init 初始化方法
1,2 在 web 工程启动的时候执行(Filter 已经创建)
doFilter()过滤方法
第三步,每次拦截到请求,会执行
destory 销毁方法
第四步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)
FilterConfig 类
FilterConfig 类 见名知意,他是 Filter 过滤器的配置文件类
Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息
FilterConfig 类的作用 获取 Filter 过滤器的配置内容
获取 Filter 的名称 filter-name 的内容
获取 在 Filter中 配置的 init-param 初始化参数
获取 ServletContext 对象
Java 代码 1 2 3 4 5 6 7 8 9 10 11 public void init (FilterConfig config) throws ServletException { System.out.println("Filter 的init初始化" ); System.out.println("filter-name:" + config.getFilterName()); System.out.println("init-param username:" + config.getInitParameter("username" )); System.out.println("init-param url:" + config.getInitParameter("url" )); System.out.println(config.getServletContext()); }
FilterChain 过滤器链
Filter 过滤器
Chain 链,链条
FilterChain 就是过滤器链(多个过滤器如何一起工作)
多个Filter 过滤器执行的特点
所有 Filter 和 目标资源默认都执行在同一个线程中
多个 Filter 共同执行的时候,他们都是使用 同一个 Request 对象
FilterChain.doFilter () 方法的作用
执行下一个 filter 过滤器(如果有 Filter)
执行目标资源 (没有 Filter )
在多个 Filter 过滤器执行的时候,他们执行的顺序是由他们在 web.xml 中 从上到下 配置的顺序决定
Filter 的拦截路径
精确匹配 1 <url-pattern > /target.jsp</url-pattern >
以上配置的路径,表示请求地址必须为 http://ip:port/工程路径/target.jsp
目录匹配 1 <url-pattern > /admin/*</url-pattern >
以上的配置路径,表示请求地址必须为 :http://ip:port/工程路径/admin/ *
后缀名匹配 1 <url-pattern > *.html</url-pattern >
以上的配置路径,表示请求地址必须以.html 结尾 才会被拦截
Fliter 过滤器只关心请求的地址会不会被拦截,不关心请求的资源是否存在
ThreadLoacal ThreadLocal 的作用
可以解决多线程的数据安全问题
它可以给当前线程关联一个数据(可以是普通变量、对象、数组、集合)
ThreadLocal 的特点
ThreadLoacal 可以为当前线程关联一个数据(他可以像map 一样存取数据,key 为当前线程)
每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例
每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型
ThreadLocal 中保存数据,在线程销毁后,会由 JVM 虚拟自动释放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public class OrderService { public void createOrder () { String name = Thread.currentThread().getName(); System.out.println("OrderService 当前线程[" + name + "]中保存的数据是: " + ThreadLocalTest.threadLocal.get()); new OrderDao ().saveOrder(); } } public class OrderDao { public void saveOrder () { String name = Thread.currentThread().getName(); System.out.println("OrderDao 当前线程[" + name + "]中保存的数据是: " + ThreadLocalTest.threadLocal.get()); } } public class ThreadLocalTest { public static ThreadLocal<Object> threadLocal = new ThreadLocal <Object>(); private static Random random = new Random (); public static class Task implements Runnable { @Override public void run () { Integer i = random.nextInt(1000 ); String name = Thread.currentThread().getName(); System.out.println("线程[" +name+"]生成的随机数是: " + i); threadLocal.set(i); try { Thread.sleep(3000 ); } catch (InterruptedException e) { e.printStackTrace(); } new OrderService ().createOrder(); Object o = threadLocal.get(); System.out.println("在线程[" +name+"]快结束时取出关联的数据是: " + o); } } public static void main (String[] args) { for (int i = 0 ; i < 3 ; i++){ new Thread (new Task ()).start(); } } }
使用 Filter 和 ThreadLocal 组合管理事务
使用 ThreadLocal 来确保 所有 dao 操作都在一个 Connection 连接对象中完成
JDBCUtils 工具类的修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 private static DruidDataSource dataSource;private static ThreadLocal<Connection> conns = new ThreadLocal <Connection>();static { try { Properties properties = new Properties (); InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties" ); properties.load(inputStream); dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection () { Connection conn = conns.get(); if (conn == null ){ try { conn = dataSource.getConnection(); conns.set(conn); conn.setAutoCommit(false ); } catch (SQLException e) { e.printStackTrace(); } } return conn; } public static void commitAndClose () { Connection connection = conns.get(); if (connection != null ){ try { connection.commit(); } catch (SQLException e) { e.printStackTrace(); } finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } conns.remove();; } public static void rollbackAndClose () { Connection connection = conns.get(); if (connection != null ){ try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } conns.remove(); }
BaseDAO 修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 public abstract class BaseDAO { private QueryRunner queryRinner = new QueryRunner (); public int update (String sql,Object ...params) { Connection conn = JDBCUtils.getConnection(); try { return queryRinner.update(conn,sql,params); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException (e); } } public <T> T queryForOne (Class<T> type,String sql,Object ...params) { Connection conn = JDBCUtils.getConnection(); try { return queryRinner.query(conn,sql,new BeanHandler <T>(type),params); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException (e); } } public <T> List<T> queryForList (Class<T> type, String sql, Object ...params) { Connection conn = JDBCUtils.getConnection(); try { return queryRinner.query(conn,sql,new BeanListHandler <T>(type),params); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException (e); } } public Object getForSingleValue (String sql,Object...params) { Connection conn = JDBCUtils.getConnection(); try { return queryRinner.query(conn, sql, new ScalarHandler (), params); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException (e); } } }
使用 Filter 过滤器统一给所有的 Service 方法加上 try-catch,来进行实现的管理 原理分析图
按上面的分析示意,那么就可以使用一个 Filter 一次性,统一地给所有的 XxxService.xxx() 方法都统一加上 try-catch() 来实现事务的管理
Filter 代码 1 2 3 4 5 6 7 8 9 10 11 @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { try { chain.doFilter(request, response); JDBCUtils.commitAndClose(); } catch (Exception e) { JDBCUtils.rollbackAndClose(); e.printStackTrace(); } }
web.xml 配置 1 2 3 4 5 6 7 8 <filter > <filter-name > TransactionFilter</filter-name > <filter-class > com.cs7eric.book.filter.TransactionFilter</filter-class > </filter > <filter-mapping > <filter-name > TransactionFilter</filter-name > <url-pattern > /*</url-pattern > </filter-mapping >
把 BaseServlet 中的一场抛给 Filter 过滤器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8" ); String action = request.getParameter("action" ); try { Method method = this .getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class); method.invoke(this ,request,response); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException (e); } }
错误信息页面 将所有异常都交给 Tomcat,让 Tomcat 展示友好的错误信息页面
在 web.xml 中我们可以通过错误信息页面配置来进行管理
1 2 3 4 5 6 7 8 <error-page > <error-code > 500</error-code > <location > /pages/error/error500.jsp</location > </error-page > </web-app >
JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。有同时也易于机器解析和生成。JSON 采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C,C++,C#,Java,JavaScript,Perl,Python等),这样就使得 JSON 成为理想的数据交换格式
json 是一种轻量级的数据交换格式
轻量级指的是跟 xml 相比
数据交换指的是客户端和服务器之间业务数据的传递格式
JSON 在 JavaScript 中的使用
JSON的定义 json 是由键值对组成,并且由花括号(大括号)包围,每个键由引号引起来,键和值之间使用冒号进行分割
JSON 定义实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var jsonObj = { "key1" : 12 , "key2" : "abc" , "key3" : true , "key4" : [ 11 , "arr" , false ] , "key5" : { "key5_1" : 551 , "key5_2" : "key5_2_value" } , "key6" : [ { "key6_1_1" : 6611 , "key6_1_2" : "key6_1_2_value" } , { "key6_2_1" : 6621 , "key6_2_2" : "key6_2_2_value" } ] } ;
JSON 的访问 JSON 本身是一个对象
JSON 中的 key 我们可以理解为是对象中 的一个属性
JSON 中的 key 访问就跟访问对象的属性一样:JSON对象.key
JSON 访问实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 alert (typeof (jsonObj));alert (jsonObj.key1 ); alert (jsonObj.key2 ); alert (jsonObj.key3 ); alert (jsonObj.key4 );for (var i = 0 ; i < jsonObj.key4 .length ; i++) { alert (jsonObj.key4 [i]); } alert (jsonObj.key5 .key5_1 );alert (jsonObj.key5 .key5_2 );alert ( jsonObj.key6 );var jsonItem = jsonObj.key6 [0 ];alert ( jsonItem.key6_1_2 );
JSON 的两个常用方法 JSON 的存在有两种形式
对象的形式存在,我们叫他 JSON 对象
JSON.stringify() 把 json 对象转换为 json 字符串
一般我们要操作 JSON 中的数据的时候,需要 JSON 对象的格式
字符串的形式存在 ,我们叫他 JSON 字符串
JSON.parse() 把 json 字符串转换为 JSON 对象
一般我们要在客户端和服务器之间进行数据交换的时候,使用 JSON 字符串
示例代码 1 2 3 4 5 6 7 var jsonObjString = JSON .stringify (jsonObj); alert (jsonObjString)var jsonObj2 = JSON .parse (jsonObjString);alert (jsonObj2.key1 );alert (jsonObj2.key2 );
JSON 在 Java 中的应用
JavaBean 和 JSON 互转 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Test public void test1 () { Person person = new Person (1 ,"国哥好帅!" ); Gson gson = new Gson (); String personJsonString = gson.toJson(person); System.out.println(personJsonString); Person person1 = gson.fromJson(personJsonString, Person.class); System.out.println(person1); }
List 和 JSON 互转 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void test2 () { List<Person> personList = new ArrayList <>(); personList.add(new Person (1 , "国哥" )); personList.add(new Person (2 , "康师傅" )); Gson gson = new Gson (); String personListJsonString = gson.toJson(personList); 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); }
map 和 JSON 互转 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void test3 () { Map<Integer,Person> personMap = new HashMap <>(); personMap.put(1 , new Person (1 , "国哥好帅" )); personMap.put(2 , new Person (2 , "康师傅也好帅" )); Gson gson = new Gson (); String personMapJsonString = gson.toJson(personMap); System.out.println(personMapJsonString); PersonMapType().getType()); Map<Integer,Person> personMap2 = gson.fromJson(personMapJsonString, new TypeToken <HashMap<Integer,Person>>(){}.getType()); System.out.println(personMap2); Person p = personMap2.get(1 ); System.out.println(p); }
AJAX 请求 AJAX 即 Asynchronous JavaScript And XML (异步 JavaScript 和 XML),是指一种创建交互式 网页应用的网页开发技术
AJAX 介绍
ajax 是一种 浏览器 通过 js 异步发起请求,局部更新页面的技术
Ajax 请求的局部更新,浏览器地址不会发生变化
局部更新不会舍弃原来页面的内容
原生 AJAX 请求的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html > <head > <meta http-equiv ="pragma" content ="no-cache" /> <meta http-equiv ="cache-control" content ="no-cache" /> <meta http-equiv ="Expires" content ="0" /> <meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" > <title > Insert title here</title > <script type ="text/javascript" > function ajaxRequest ( ) { var xmlhttprequest = new XMLHttpRequest (); xmlhttprequest.open ("GET" ,"http://localhost:8080/16_json_ajax_i18n/ajaxServlet?action=javaScriptAjax" ,true ); xmlhttprequest.onreadystatechange = function ( ){ if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200 ) { alert ("收到服务器返回的数据:" + xmlhttprequest.responseText ); var jsonObj = JSON .parse (xmlhttprequest.responseText ); document .getElementById ("div01" ).innerHTML = "编号:" + jsonObj.id + " , 姓名:" + jsonObj.name ; } } xmlhttprequest.send (); alert ("我是最后一行的代码" ); } </script > </head > <body > <button onclick ="ajaxRequest()" > ajax request</button > <button onclick ="ajaxRequest()" > ajax request</button > <button onclick ="ajaxRequest()" > ajax request</button > <button onclick ="ajaxRequest()" > ajax request</button > <button onclick ="ajaxRequest()" > ajax request</button > <div id ="div01" > </div > <table border ="1" > <tr > <td > 1.1</td > <td > 1.2</td > </tr > <tr > <td > 2.1</td > <td > 2.2</td > </tr > </table > </body > </html >
jQuery 中的 AJAX 请求
$.ajax
方法
url 表示请求的地址
type 表示请求的类型 GET 或 POST 请求
data 表示发送给服务器的数据
name=value&name=value
{key:value}
success 请求成功 ,响应的回调函数
dataType 响应的数据类型
text 表示纯文本
xml 表示 xml 数据
json 表示 json 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $(function ( ){ $("#ajaxBtn" ).click (function ( ){ $.ajax ({ url :"http://localhost:8080/16_json_ajax_i18n/ajaxServlet" , data :{action :"jQueryAjax" }, type :"GET" , success :function (data ) { $("#msg" ).html (" ajax 编号:" + data.id + " , 姓名:" + data.name ); }, dataType : "json" }); });
$.get 方法 和 $.post 方法
url 请求的 url 地址
data 发送的数据
callback 成功的回调函数
type 返回的数据类型
1 2 3 4 5 6 7 8 $("#getBtn" ).click (function ( ){ $.get ("http://localhost:8080/16_json_ajax_i18n/ajaxServlet" ,"action=jQueryGet" ,function (data ) { $("#msg" ).html (" get 编号:" + data.id + " , 姓名:" + data.name ); },"json" ); });
1 2 3 4 5 6 7 8 $("#postBtn" ).click (function ( ){ $.post ("http://localhost:8080/16_json_ajax_i18n/ajaxServlet" ,"action=jQueryPost" ,function (data ) { $("#msg" ).html (" post 编号:" + data.id + " , 姓名:" + data.name ); },"json" ); });
$.getJSON 方法
url 请求的地址
data 发送给服务器的数据
callback 成功的回调函数
1 2 3 4 5 6 $("#getJSONBtn" ).click (function ( ){ $.getJSON ("http://localhost:8080/16_json_ajax_i18n/ajaxServlet" ,"action=jQueryGetJSON" ,function (data ) { $("#msg" ).html (" getJSON 编号:" + data.id + " , 姓名:" + data.name ); }); });
serialize() 表单序列化
serialize() 可以把表单中所有表单项的内容都获取到,并以 name=value&name=value 的形式进行拼接
1 2 3 4 5 6 7 $("#submit" ).click (function ( ){ $.getJSON ("http://localhost:8080/16_json_ajax_i18n/ajaxServlet" ,"action=jQuerySerialize&" + $("#form01" ).serialize (),function (data ) { $("#msg" ).html (" Serialize 编号:" + data.id + " , 姓名:" + data.name ); }); });
i18n 国际化
国际化(Internationalization) 指的是同一个网站可以支持多种不同的语言, 以方便不同国家, 不同语种的用户访问。
关于国际化我们想到的最简单的方案就是为不同的国家创建不同的网站, 比如苹果公司, 他的英文官网是:http://www.apple.com 而中国官网是 http://www.apple.com/cn
苹果公司这种方案并不适合全部公司, 而我们希望相同的一个网站, 而不同人访问的时候可以根据用户所在的区域显示 不同的语言文字, 而网站的布局样式等不发生改变。
于是就有了我们说的国际化, 国际化总的来说就是同一个网站不同国家的人来访问可以显示出不同的语言。 但实际上这 种需求并不强烈, 一般真的有国际化需求的公司, 主流采用的依然是苹果公司的那种方案, 为不同的国家创建不同的页 面。 所以国际化的内容我们了解一下即可。
国际化的英文 Internationalization, 但是由于拼写过长, 老外想了一个简单的写法叫做 I18N, 代表的是 Internationalization 这个单词, 以 I 开头, 以 N 结尾, 而中间是 18 个字母, 所以简写为 I18N。 以后我们说 I18N 和国际化是一个意思。