一、 网页的构成
1.1 网页
浏览器中显示的内容,浏览器是网页的展示器。编写好的网页,放在浏览器中即可运行。编写网页我们使用的就是HTML语言。
1.2 网页的构成
摘要 | 说明 |
---|---|
结构(HTML) | HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片、视频等。 |
表现(CSS) | CSS样式是表现。就像网页的外衣。比如,标题字体、颜色变化,或为标题加入背景图片、边框等。所有这些用来改变内容外观的东西称之为表现。 |
行为(JavaScript / jQuery) | JavaScript是用来实现网页上的特效效果。如:鼠标滑过弹出下拉菜单。或鼠标滑过表格的背景颜色改变。还有购物网站中图片的轮换。可以这么理解,有动画的,有交互的一般都是用JavaScript来实现的 |
二、 HTML简介
- HTML 是用来描述网页的一种语言。
- HTML 指的是超文本标记语言 (Hyper Text Markup Language)
- 超文本就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素
- HTML 不是一种编程语言,而是一种标记语言 (markup language)
- 标记语言是一套标记标签 (markup tag),由一组<>包围的关键字
- HTML网页的后缀名一般为.html
- HTML 使用标记标签来描述网页
- HTML文件的基本结构
- 为HTML页面中的根标签,所有的HTML网页中的标签都在中。
- 这里标签用于定义文档的头部,它是所有头部元素的容器。头部元素有、、、 等标签。
- 在和标签之间的内容是网页的主要内容,如、、、等网页内容标签,在这里的标签中的内容会在浏览器中显示出来。
三、 HTML语法
- 标签的语法
- 标签由英文尖括号 < 和 > 括起来,如:
- html中的标签一般都是成对出现的,分开始标签和结束标签。结束标签比开始标签多一个 / ,..;还有一些是自结束标签,如:
- 标签与标签之间是可以嵌套的,但先后顺序必须保持一致,如:里嵌套,那么必须放在的前面。如: ..
- 注释是不可以嵌套的,如: —>
- HTML标签不区分大小写,和是一样的,但万维网联盟(W3C)建议小写。
- 元素模型
四、 HTML的常用标签
4.1 标题标签
…
…
…
…
…
…
- 默认占用浏览器的一整行,并且前后要空一行
4.2 段落标签
两个黄鹂鸣翠柳
是否还没女朋友
- 段落标签也会独占浏览器的一行,而且前后还会空出一行。
- 使用空的段落标记 去插入一个空行是个坏习惯。用
标签代替它!
4.3 换行标签
4.4 无序列表
- 网页
- 新闻
- 视频
- 贴吧
4.5有序列表
- 单身久了,坐地铁女孩蹭下肩膀,你连你们的孩子叫什么名字都想好了
- 太久没接吻,吃个鸭舌都能感到温柔
- 太久没牵手,拿着泡椒凤爪心都会颤抖
4.6 图片标签
<img alt=”“ src=”” title=””/>
- alt:图片无法显示时显示的描述性文字
- src:图片的地址(或路径)。这里分为相对路径和绝对路径。
- width和height:设置图片的宽度和高度
使用相对路径查找目标资源心得
- 目标文件与当前文件在同一目录下,直接查找使用。
- 目标文件与当前文件不在同一目录下,先找目标文件父包,再找目标文件
- 如:父包也不与当前文件在同包下,将父包当成目标文件,继续找父包的父包。以此类推,找到WebContent根目录为止。
补充内容:html中的相对路径与绝对路径
相对路径:以当前文件所在的路径为基准
. 表示当前文件所在目录
.. 表示上一级目录
资源名 表示当前目录下的资源 ./资源名 ./可以省略
使用../返回上一级
绝对路径:
盘符:\文件名 =====>>>> 错误(真实路径)
http://ip:port/工程名/资源名 ===>>> 正确
比如:http://localhost:8080/img/13.jpg
4.7 超链接
- href:指向一个链接地址
- target:定义被链接的文档在何处显示。
- 值为”_self”时在向当前窗口打开新的网页(默认)
- 值为”_blank”时在新的窗口打开
4.8 转义字符
- 当显示页面时,浏览器会移除源代码中多余的空格和空行。所有连续的空格或空行都会被算作一个空格。即,HTML 代码中的所有连续的空行(换行)也被显示为一个空格。
- 在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签。
- 如果想表示多个空格,需要使用如下的转义字符。
说明1:如需显示小于号,我们必须这样写:< 或 <
说明2:使用实体名而不是数字的好处是,名称易于记忆。不过坏处是,浏览器也许并不支持所有实体名称(对实体数字的支持却很好)。
4.9 div标签
- div是html中最灵活最重要的元素,div就像一个容器,里面可以装很多内容。本身没有特殊的语义。
- 它是块级元素,会占用网页的一行。
- Div的主要作用:可以通过调整自己的样式来完成网页的复杂布局
- 它可以把一些独立的逻辑部分(如网页中独立的栏目版块)划分出来
补充说明:
块级元素:各占据一行,垂直方向排列。块级元素从新行开始结束接着一个断行。width、height、padding、margin有效。
内联元素:在一条直线上排列,都是同一行的,水平方向排列。设置width、height、padding、margin无效。
五、 HTML中的表格
5.1 HTML中的表格
其中: - 标记这是一个表格 - 表示表格的一行 -
表示表格的一列
- 跨列合并单元格用 colspan 属性
- 跨行合并单元格用 rowspan 属性
- 常用属性
- border :设置表格边框
- width:设置表格的宽度,单位px
- height:设置表格的高度,单位px
- align:设置表格的对齐方式
举例: ## 六、 HTML中的表单 ### 6.1 生活中的表单 表单类似生活中的单据,票据,申请表之类的东西,生活中我们经常会填写很多表单,比如入职申请表,入学登记表,员工信息表等。 ### 6.2 表单中的常用标签 #### 1. 表单标签 - action表示表单填写完成要提交给的地方。就像我们把入职申请表填写完成后要交给部门经理一样。 - 提交的方式分为:get 或 post - get:是将所有的提交的数据显示在地址栏,长度会有一些限制 - post:将要提交的数据放在请求体中,在url表单里面没有任何数据 #### 2. 文本输入框 #### 3. 密码输入框 #### 4. 单选框 性别:男 女 #### 5. 复选框 6. 下拉列表#### 7. 重置按钮 #### 8. 提交按钮 #### 9. 普通按钮 # 第二章 CSS HTML页面实在太丑了,怎么破?! ## 一、 CSS简介 CSS全称为“层叠样式表 (Cascading Style Sheets)”,它主要是用于定义HTML元素(或内容)在浏览器内的显示样式,如文字大小、颜色、字体、边框、位置等。 ## 二、 CSS基本语法 ### 2.1 基本格式 - CSS样式由选择符(选择器)和声明组成,而声明又由属性和值组成,如下图所示: - 格式为: 选择器 { 样式名:样式值; 样式名:样式值; ………… } ### 2.2 语法说明 - 属性 (property) 是你希望改变的属性,并且每个属性都有一个值。属性和值被冒号分开,并由花括号包围,这样就组成了一个完整的样式声明(declaration),例如:p {color: blue} - 多个声明:如果要定义不止一个声明,则需要用英文分号”;”将每个声明分开。虽然最后一条声明的最后可以不加分号,但尽量在每条声明的末尾都加上分号 - 每行最好只描述一个属性 - CSS对大小写不敏感,但建议使用小写。不过存在一个例外:class 和 id 名称对大小写是敏感的。 - CSS注释:/注释内容/ ### 2.3 CSS样式编写位置 方式一:写在标签的style属性中: 字体大小用px表示 落霞与孤鹜齐飞 方式二:写在html头的style标签中(style标签一般写在head标签与title标签之间): 方式三:写在外部的css文件中,然后通过link标签引入外部的css文件 其中,style.css定义如下: @charset “UTF-8”; / 这是css与html结合使用的第三种方式 / div { border: 1px solid red; } span { border: 1px solid green; } 说明:当同一个 HTML 元素被不止一个样式定义时,会使用哪个样式呢? 优先级按照上述讲的三种方式依次降低。内联样式(在 HTML 元素内部)拥有最高的优先权。 ## 三、 选择器的分类 选择器:浏览器根据“选择器”确定受CSS样式影响的HTML元素。 ### 分类1:标签选择器 按照标签名选中相应的元素。如上图的p。 p { color:red; } ### 分类2:类选择器 按照元素的类名选中相应的元素,使用.class值 .class属性值{ } 举例: 青春正好 编程趁早 .foot { color:red; } ### 分类3:ID选择器 按照元素的id选中相应的元素,使用#id值 #id属性值{ } 举例: 大家好 #abc {color:red; } # 第三章 JavaScript ## 一、 JavaScript起源 ### 1.1 起源 - N年前 - 拨号上网,网速很慢,数据提交到服务器端验证,体验很差 - 于是,就有人在想:能不能让这些数据在浏览器端验证呢? - 20世纪90年代 - 1995年,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。Netscape在最初将其脚本语言命名为LiveScript。 - 后来Netscape与Sun合作,网景公司管理层希望它外观看起来像Java,因此取名为JavaScript。 - JavaScript是一门客户端脚本语言,主要运行在浏览器中,浏览器中负责运行JavaScript脚本代码的程序叫JavaScript引擎。 - 五彩缤纷的现在 - 时至今日JavaScript已经不仅仅局限于表单验证,网页上很多炫丽动感的特效都有它的功劳 ### 1.2 Java与JavaScript的关系 没有关系,只是语法类似! ### 1.3 特性 ##### ① 脚本语言 JavaScript是一种解释型的脚本语言。不同于C、C++、Java等语言先编译后执行, JavaScript不会产生编译出来的字节码文件,而是在程序的运行过程中对源文件逐行进行解释。 ##### ② 基于对象 JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。但是面向对象的三大特性:『封装』、『继承』、『多态』中,JavaScript能够实现封装,可以模拟继承,不支持多态,所以它不是一门面向对象的编程语言。 ##### ③ 弱类型 JavaScript中也有明确的数据类型,但是声明一个变量后它可以接收任何类型的数据,并且会在程序执行过程中根据上下文自动转换类型。 ##### ④ 事件驱动 JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。 ##### ⑤ 跨平台性 JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提是机器上的浏览器支持JavaScript脚本语言。目前JavaScript已被大多数的浏览器所支持。 ### 1.4 HelloWorld 对应的代码实现如下: ## 二、基本语法 JavaScript需要包括在 说明:一般声明在head标签中,与style标签有点像。 - 方式二:写在外部的.js文件中。然后通过script标签的src属性引入。 - 这里的文件路径,可以是相对路径,也可以是绝对路径。 说明:type属性 :默认值 text/javascript可以不写,不写也是这个值。 src属性:当需要引入一个外部的js文件时,使用该属性指向文件的地址。 特别注意:方式一和方式二不要同时使用。一旦同时使用,会默认执行方式二中js文件中的js代码。 ### 2.2 变量 #### 2.2.1 JavaScript的数据类型 - 基本数据类型 - 数值类型:number - 字符串类型:string - 布尔类型:boolean - 其他值与boolean的转换规则: - 0、null、undefined、“”(空串)在运算时,都认为是false - undefined型(Undefined) - 对象类型: - 函数对象:Function - 数组对象:Array - 使用typeof 判断,结果是Object - 一般对象:Object #### 2.2.2 变量的声明 - 使用var定义即可。比如:var num = 65; var name = “马大云”; - 变量声明时不需要指定类型,可以接受所有的数据类型。 #### 2.2.3 变量的赋值 - 变量在赋值过程中可以接受不同类型的值。比如:var x = 123; x = “atguigu.com”; - 没有赋值的变量,默认为undefined - 使用typeof(变量名),判断变量的类型 - JS中每一条语句以分号(;)结尾。如果不写分号,浏览器会自动添加,但是会消耗一些系统资源。 ### 2.3 数组 #### 2.3.1 数组的定义 - 定义一个空数组:var arr = [] 或 var arr=new Array(); - 定义一个非空数组:var arr1 = [“Tom”,”atguigu.com”,true]; #### 2.3.2 数组的调用 - 数组的角标是从0开始的,直接通过角标进行调用。比如: alert(arr[0]); #### 2.3.3 数组的遍历 var arr = [10,20]; for(var i = 0;i < arr.length;i++){ alert(arr[i]); } ### 2.4 函数 #### 2.4.1 函数声明与调用 - 使用function关键字 - 不需要指定返回值。如果函数有返回值,只需要在函数体内直接使用return语句返回需要的值即可。 - 不需要指定形参类型(因为js所有类型都使用var来声明) - 函数在js中也是一种对象,可以将函数的引用赋值给变量 - 方式一: - 声明格式: - function 函数名(形参列表){ 函数体 } - 举例: - function sum(n, m) { return n + m; } - 调用:函数名(参数)。 - var result = sum(1,2); alert(result);//3 - 方式二:匿名函数 - 声明格式: - var 变量名 = function(形参列表){ 函数体; } - 举例1: - var add = function(a,b){ return a+b; } - 举例2: - var info = function(){ alert(“美好的事情即将发生“); } - 调用:变量名(实参值) - var result = add(1,2); alert(result); info(); ### 2.5 对象 #### 2.5.1 对象的创建与调用 - 方式一:使用new Object()创建 - 格式 - var 变量名 = new Object();//创建一个空的对象实例 变量名.属性名 = 值;//给创建的对象添加一个属性 变量名.函数名 = function(){}; //给创建的对象添加一个函数 - 对象的访问(即:属性或函数的调用) - 变量名.属性; 变量名.函数名(); - 举例 - //对象的定义 var obj = new Object(); alert(typeof(obj)); //声明属性和函数 obj.name = “Tom”; obj.study = function() { alert(“好好学习,天天向上”); }; //调用属性 alert(obj.name); //调用函数 obj.study(); - 方式二:使用{}创建 json格式 - 格式 - var 变量名 = { //定义一个空对象 属性名1:值1, //声明属性1 属性名2:值2, //声明属性2 函数名:function(){} //声明函数 }; - 对象的访问(即:属性或函数的调用) - 变量名.属性; 变量名.函数名(); - 举例 - //对象的定义 var obj = { name:”zhangchunsheng”, age:18, work:function(){ alert(“我在工作中…”); } }; alert(typeof(obj)); alert(obj.name); obj.study(); #### 2.9.2 函数也是对象 - 在JavaScript中,函数也作为一种数据类型存在,而且是引用数据类型,函数名就是指向其内存空间地址的引用。 var a = function() { return 2; }; var b = a; a.age = 18; alert(b.age); //18 #### 2.9.3 this关键字的使用 - 在JavaScript函数中,this关键字指向的是调用当前函数的对象。 - 举例1: - var obj = { name:”Tom”, age:18, study:function(){ alert(“好好学习,天天向上”); }, info:function(){ alert(“name : “ + this.name + “, age = “ + this.age); } }; alert(obj.name); obj.study(); obj.info(); ## 三、 JSON(最重点) ### 3.1 JSON格式的用途 在开发中凡是涉及到『跨平台数据传输』,JSON格式一定是首选。 ### 3.2 JSON格式的说明 - JSON数据两端要么是{},要么是[] - {}定义JSON对象 - []定义JSON数组 - JSON对象的格式是: {key:value,key:value,…,key:value} - JOSN数组的格式是: [value,value,…,value] - key的类型固定是字符串 - value的类型可以是: - 基本数据类型 - 引用类型:JSON对象或JSON数组 正因为JSON格式中value部分还可以继续使用JSON对象或JSON数组,所以JSON格式是可以『多层嵌套』的,所以JSON格式不论多么复杂的数据类型都可以表达。 //json的格式: {key:value,key:value} var person1 = { “name”:”张三疯”, “age”:189, “address”:”武当山” } //其实JSON对于前端而言,就是一个对象 //console.log(person1.name) var person2 = { “name”:”张三疯”, “age”:189, “address”:”武当山”, “wife”:{ “name”:”小花”, “age”:18, “address”:”武当山下的小村庄” } } //console.log(person2.wife.name) var person3 = { “name”:”张三疯”, “age”:189, “address”:”武当山”, “wife”:{ “name”:”小花”, “age”:18, “address”:”武当山下的小村庄” }, “sons”:[ { “name”:”奥巴马”, “age”:1, “address”:”武当山” }, { “name”:”奥拉夫”, “age”:2, “address”:”少林寺” } ] } //json数组的格式: [{key:value,key:value},{key:value,key:value}] //var personList = [person1,person2] ### 3.3 JSON对象和JSON字符串互转 - JSON对象转JSON字符串 var jsonObj = {“stuName”:”tom”,”stuAge”:20}; var jsonStr = JSON.stringify(jsonObj); console.log(typeof jsonObj); // object console.log(typeof jsonStr); // string - JSON字符串转JSON对象 jsonObj = JSON.parse(jsonStr); console.log(jsonObj); // {stuName: “tom”, stuAge: 20} ## 四、 DOM DOM是Document Object Model的缩写,意思是『文档对象模型』——将HTML文档抽象成模型,再封装成对象方便用程序操作。 这是一种非常常用的编程思想:将现实世界的事物抽象成模型,这样就非常容易使用对象来量化的描述现实事物,从而把生活中的问题转化成一个程序问题,最终实现用应用软件协助解决现实问题。而在这其中『模型』就是那个连通现实世界和代码世界的桥梁。 ### 4.1 DOM树的概念 浏览器把HTML文档从服务器上下载下来之后就开始按照『从上到下』的顺序『读取HTML标签』。每一个标签都会被封装成一个『对象』。 而第一个读取到的肯定是根标签html,然后是它的子标签head,再然后是head标签里的子标签……所以从html标签开始,整个文档中的所有标签都会根据它们之间的『父子关系』被放到一个『树形结构』的对象中。 这个包含了所有标签对象的整个树形结构对象就是JavaScript中的一个可以直接使用的内置对象:document。 例如,下面的标签结构: 会被解析为: ### 4.2 各个组成部分的类型 整个文档中的一切都可以看做Node。各个具体组成部分的具体类型可以看做Node类型的子类。 其实严格来说,JavaScript并不支持真正意义上的『继承』,这里我们借用Java中的『继承』概念,从逻辑上来帮助我们理解各个类型之间的关系。 | 组成部分 | 节点类型 | 具体类型 | | —- | —- | —- | | 整个文档 | 文档节点 | Document | | HTML标签 | 元素节点 | Element | | HTML标签内的文本 | 文本节点 | Text | | HTML标签内的属性 | 属性节点 | Attr | | 注释 | 注释节点 | Comment | ### 4.3 DOM操作 由于实际开发时基本上都是使用JavaScript的各种框架来操作,而框架中的操作方式和我们现在看到的原生操作完全不同,所以下面罗列的API仅供参考,不做要求。 #### 4.3.1 在整个文档范围内查询元素节点 | 功能 | API | 返回值 | | —- | —- | —- | | 根据id值查询 | document.getElementById(“id值”) | 一个具体的元素节 | | 根据标签名查询 | document.getElementsByTagName(“标签名”) | 元素节点数组 | | 根据name属性值查询 | document.getElementsByName(“name值”) | 元素节点数组 | | 根据类名查询 | document.getElementsByClassName(“类名”) | 元素节点数组 | #### 4.3.2 在具体元素节点范围内查找子节点 | 功能 | API | 返回值 | | —- | —- | —- | | 查找子标签 | element.children | 返回子标签数组 | | 查找第一个子标签 | element.firstElementChild | 标签对象 | | 查找最后一个子标签 | element.lastElementChild | 节点对象 | #### 4.3.3 查找指定元素节点的父节点 | 功能 | API | 返回值 | | —- | —- | —- | | 查找指定元素节点的父标签 | element.parentElement | 标签对象 | #### 4.3.4 查找指定元素节点的兄弟节点 | 功能 | API | 返回值 | | —- | —- | —- | | 查找前一个兄弟标签 | node.previousElementSibling | 标签对象 | | 查找后一个兄弟标签 | node.nextElementSibling | 标签对象 | #### 4.3.5 属性操作 | 需求 | 操作方式 | | —- | —- | | 读取属性值 | 元素对象.属性名 | | 修改属性值 | 元素对象.属性名=新的属性值 | #### 4.3.6 标签体的操作 | 需求 | 操作方式 | | —- | —- | | 获取或者设置标签体的文本内容 | element.innerText | | 获取或者设置标签体的内容 | element.innerHTML | #### 4.3.7 DOM增删改操作 | API | 功能 | | —- | —- | | document.createElement(“标签名”) | 创建元素节点并返回,但不会自动添加到文档中 | | document.createTextNode(“文本值”) | 创建文本节点并返回,但不会自动添加到文档中 | | element.appendChild(ele) | 将ele添加到element所有子节点后面 | | parentEle.insertBefore(newEle,targetEle) | 将newEle插入到targetEle前面 | | parentEle.replaceChild(newEle, oldEle) | 用新节点替换原有的旧子节点 | | element.remove() | 删除某个标签 | | element.innerHTML | 读写HTML代码 | ## 五 JavaScript的事件驱动 ### 5.1 事件的概念 - HTML 事件是发生在 HTML 元素上的“事情”, 是浏览器或用户做的某些事情 - 事件通常与函数配合使用,这样就可以通过发生的事件来驱动函数执行。 ### 5.2 常见事件 | 属性 | 此事件发生在何时… | | —- | —- | | onclick | 当用户点击某个对象时调用的事件句柄。 | | ondblclick | 当用户双击某个对象时调用的事件句柄。 | | onchange | 域的内容被改变。 | | onblur | 元素失去焦点。 | | onfocus | 元素获得焦点。 | | onload | 一张页面或一幅图像完成加载。 | | onsubmit | 确认按钮被点击;表单被提交。 | | onkeydown | 某个键盘按键被按下。 | | onkeypress | 某个键盘按键被按住。 | | onkeyup | 某个键盘按键被松开。 | | onmousedown | 鼠标按钮被按下。 | | onmouseup | 鼠标按键被松开。 | | onmouseout | 鼠标从某元素移开。 | | omouseover | 鼠标移到某元素之上。 | | onmousemove | 鼠标被移动。 | ### 5.3 事件绑定的方式 #### 5.3.1 普通函数方式 说白了设置标签的属性 <标签 属性=”js代码,调用函数”></标签> #### 5.3.2 匿名函数方式 #### 5.3.3 事件的使用介绍 - 点击事件 - 需求: 没点击一次按钮 弹出hello… - 获得焦点(onfocus)和失去焦点(onblur) - 需求:给输入框设置获得和失去焦点 var ipt = document.getElementById(“ipt”); //绑定获取焦点事件 ipt.onfocus = function () { console.log(“获取焦点了…”) } //绑定失去焦点事件 ipt.onblur = function () { console.log(“失去焦点了…”) } - 内容改变(onchange) - 需求: 给select设置内容改变事件
//给输入框绑定键盘按键按下和抬起事件 ipt.onkeyup = function () {
//给输入框绑定鼠标移入事件 第四章 Vue1. Vue的简介1.1 Vue的作者介绍在为AngularJS工作之后,Vue的作者尤雨溪开Vue.js。他声称自己的思路是提取Angular中自己喜欢的部分,构建出一款相当轻量的框架。 1.2 Vue的官网介绍Vue (读音 /vjuː/,类似于view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。 2. 准备Vue.js环境
3. Vue的入门案例
<!DOCTYPE html> {{message}} 4. 声明式渲染4.1 概念4.1.1 声明式『声明式』是相对于『编程式』而言的。
4.1.2 渲染上图含义解释:
4.2 案例讲解HTML代码 {{message}} vue代码 // 1.创建一个JSON对象,作为new Vue时要使用的参数 var argumentJson = {
// 2.创建Vue对象,传入上面准备好的参数 4.3 查看声明式渲染的响应式效果通过验证Vue对象的『响应式』效果,我们看到Vue对象和页面上的HTML标签确实是始终保持着关联的关系,同时看到Vue在背后确实是做了大量的工作。 5. 绑定元素属性5.1 基本语法5.2 案例代码HTML代码
6 双向数据绑定6.1 提出问题
6.2 案例代码HTML代码
扩展:
实际开发中,要考虑到用户在输入数据时,有可能会包含前后空格。而这些前后的空格对我们程序运行来说都是干扰因素,要去掉。在v-model后面加上.trim修饰符即可实现。 7 条件渲染根据Vue对象中,数据属性的值来判断是否对HTML页面内容进行渲染。 7.1 v-ifHTML代码 ifVue代码 var app = new Vue({ “el”:”#app”, “data”:{ “flag”:true } }); 7.2 v-if和v-elseHTML代码 if/elseVue代码 var app02 = new Vue({ “el”:”#app02”, “data”:{ “flag”:true } }); 7.3 v-showHTML代码 v-showVue代码 var app03 = new Vue({ “el”:”#app03”, “data”:{ “flag”:true } }); 8 列表渲染8.1 迭代一个简单的数组HTML代码
Vue代码 var app01 = new Vue({ “el”:”#app01”, “data”:{ “fruitList”: [ “apple”, “banana”, “orange”, “grape”, “dragonfruit” ] } }); 8.2 迭代一个对象数组HTML代码
Vue代码 var app = new Vue({ “el”:”#app”, “data”:{ “employeeList”:[ { “empId”:11, “empName”:”tom”, “empAge”:111, “empSubject”:”java” }, { “empId”:22, “empName”:”jerry”, “empAge”:222, “empSubject”:”php” }, { “empId”:33, “empName”:”bob”, “empAge”:333, “empSubject”:”python” } ] } }); 9 事件驱动9.1 案例一: 字符串顺序反转HTML代码 {{message}}
9.2 案例二:获取鼠标移动时的坐标信息HTML代码 {{position}} Vue代码 var app = new Vue({ “el”:”#app”, “data”:{ “position”:”暂时没有获取到鼠标的位置信息” }, “methods”:{ “recordPosition”:function(event){ this.position = event.clientX + “ “ + event.clientY; } } }); 扩展: v-on:事件名=”函数”可以简写成@事件名=”函数” 9.3 取消控件的默认行为9.3.1 控件默认行为
本来控件的默认行为是天经地义就该如此的,但是如果我们希望点击之后根据我们判断的结果再看是否要跳转,此时默认行为无脑跳转的做法就不符合我们的预期了。 9.3.2 取消方式调用事件对象的preventDefault()方法。 JavaScript代码: document.getElementById(“submitBtn”).onclick = function() { console.log(“我点击了一个表单提交按钮”); event.preventDefault(); } 9.4 阻止事件冒泡
点击里面的div同时也等于点击了外层的div,此时如果两个div上都绑定了单击响应函数那么就都会被触发: document.getElementById(“outterDiv”).onclick = function() { console.log(“外层div的事件触发了”); } document.getElementById(“innerDiv”).onclick = function() {
9.5 Vue事件修饰符对于事件修饰符,Vue官网的描述是: 9.5.1 取消控件的默认行为控件的默认行为指的是:
实现这个需求使用的Vue事件修饰符是:.prevent 9.5.2 取消事件冒泡实现这个需求使用的Vue事件修饰符是:.stop 10 侦听属性10.1 提出需求尊姓:{{firstName}} 大名:{{lastName}} 尊姓: 大名: 全名:{{fullName}} 在上面代码的基础上,我们希望firstName或lastName属性发生变化时,修改fullName属性。此时需要对firstName或lastName属性进行『侦听』。 具体来说,所谓『侦听』就是对message属性进行监控,当firstName或lastName属性的值发生变化时,调用我们准备好的函数。 ##### 10.2 Vue代码 在watch属性中声明对firstName和lastName属性进行『侦听』的函数: var app = new Vue({ “el”:”#app”, “data”:{ “firstName”:”jim”, “lastName”:”green”, “fullName”:”jim green” }, “watch”:{ “firstName”:function(inputValue){ this.fullName = inputValue + “ “ + this.lastName; }, “lastName”:function(inputValue){ this.fullName = this.firstName + “ “ + inputValue; } } }); #### 11 Vue的生命周期 ##### 11.1 概念 在我们各种语言的编程领域中,『生命周期』都是一个非常常见的概念。一个对象从创建、初始化、工作再到释放、清理和销毁,会经历很多环节的演变。比如我们在JavaSE阶段学习过线程的生命周期,今天学习Vue对象的生命周期,将来还要学习Servlet、Filter等Web组件的生命周期。 ##### 11.2 Vue对象的生命周期 images ##### 2.13.3 生命周期钩子函数 Vue允许我们在特定的生命周期环节中通过钩子函数来加入我们的代码。 {{message}} new Vue({ “el”:”#app”, “data”:{ “message”:”hello” }, “methods”:{ “changeValue”:function(){ this.message = “new hello”; } }, // 1.实例创建之前 “beforeCreate”:function(){ console.log(“beforeCreate:”+this.message); }, // 2.实例创建完成 “created”:function(){ console.log(“created:”+this.message); }, // 3.数据挂载前 “beforeMount”:function(){ console.log(“beforeMount:”+document.getElementById(“content”).innerText); }, // 4.数据已经挂载 “mounted”:function(){ console.log(“mounted:”+document.getElementById(“content”).innerText); }, // 5.数据更新前 “beforeUpdate”:function(){ console.log(“beforeUpdate:”+document.getElementById(“content”).innerText); }, // 6.数据更新之后 “updated”:function(){ console.log(“updated:”+document.getElementById(“content”).innerText); } }); ## 第五章 XML ### 1. 内容讲解 #### 1.1 配置文件 ##### 1.1.1 配置文件的作用 配置文件是用于给应用程序提供配置参数以及初始化设置的一些有特殊格式的文件 ##### 1.1.1 常见的配置文件类型 1. properties文件,例如druid连接池就是使用properties文件作为配置文件 1. XML文件,例如Tomcat就是使用XML文件作为配置文件 1. YAML文件,例如SpringBoot就是使用YAML作为配置文件 1. json文件,通常用来做文件传输,也可以用来做前端或者移动端的配置文件 #### 1.2 properties文件 ##### 1.2.1 文件示例 atguigu.jdbc.url=jdbc:mysql://192.168.198.100:3306/mybatis1026 atguigu.jdbc.driver=com.mysql.jdbc.Driver atguigu.jdbc.username=root atguigu.jdbc.password=atguigu ##### 1.2.2 语法规范 - 由键值对组成 - 键和值之间的符号是等号 - 每一行都必须顶格写,前面不能有空格之类的其他符号 #### 1.3 XML文件 ##### 1.3.1 文件示例 <?xml version=”1.0” encoding=”UTF-8”?> xsi:schemaLocation=”http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd” version=”4.0”> ##### 1.3.2 概念介绍 XML是eXtensible Markup Language的缩写,翻译过来就是可扩展标记语言。所以很明显,XML和HTML一样都是标记语言,也就是说它们的基本语法都是标签。 可扩展 可扩展三个字表面上的意思是XML允许自定义格式。但是别美,这不代表你可以随便写。 在XML基本语法规范的基础上,你使用的那些第三方应用程序、框架会通过设计『XML约束』的方式『强制规定』配置文件中可以写什么和怎么写,规定之外的都不可以写。 XML基本语法这个知识点的定位是:我们不需要从零开始,从头到尾的一行一行编写XML文档,而是在第三方应用程序、框架已提供的配置文件的基础上修改。要改成什么样取决于你的需求,而怎么改取决于XML基本语法和具体的XML约束。 ##### 1.3.3 XML的基本语法 - XML文档声明 这部分基本上就是固定格式,要注意的是文档声明一定要从第一行第一列开始写 <?xml version=”1.0” encoding=”UTF-8”?> - 根标签 根标签有且只能有一个。 - 标签关闭 - 双标签:开始标签和结束标签必须成对出现。 - 单标签:单标签在标签内关闭。 - 标签嵌套 - 可以嵌套,但是不能交叉嵌套。 - 注释不能嵌套 - 标签名、属性名建议使用小写字母 - 属性 - 属性必须有值 - 属性值必须加引号,单双都行 看到这里大家一定会发现XML的基本语法和HTML的基本语法简直如出一辙。其实这不是偶然的,XML基本语法+HTML约束=HTML语法。在逻辑上HTML确实是XML的子集。 <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd"> 从HTML4.01版本的文档类型声明中可以看出,这里使用的DTD类型的XML约束。也就是说http://www.w3.org/TR/html4/loose.dtd这个文件定义了HTML文档中可以写哪些标签,标签内可以写哪些属性,某个标签可以有什么样的子标签。 ##### 1.3.4 XML的约束(稍微了解) 将来我们主要就是根据XML约束中的规定来编写XML配置文件,而且会在我们编写XML的时候根据约束来提示我们编写, 而XML约束主要包括DTD和Schema两种。 - DTD - Schema Schema约束要求我们一个XML文档中,所有标签,所有属性都必须在约束中有明确的定义。 下面我们以web.xml的约束声明为例来做个说明: xsi:schemaLocation=”http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd” version=”4.0”> | 属性名 | 作用 | | —- | —- | | xmlns | 指出当前XML文档约束规则的名称空间在哪里 我们就是通过这个属性来引用一个具体的名称空间 | | xmlns:xsi | 指出xmlns这个属性是在哪个约束文档中被定义的 | | xsi:schemaLocation | 语法格式:在xsi名称空间下引用schemaLocation属性 配置含义:指定当前XML文档中所用到的约束文档本身的文件的地址 | ##### 1.3.5 XML解析(重点) ###### 1.3.5.1 XML解析的作用 用Java代码读取xml中的数据 ###### 1.3.5.2 XML的两种解析方式 1. DOM解析:将文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为一些对象。 - 优点:因为在内存中会形成dom树,程序员可以以面向对象的方式操作XML文件,写代码就非常方便,可以对dom树进行增删改查。 - 缺点:dom树非常占内存,解析速度慢。所以一般解析体积较大的XML文件的时候不会采用DOM解析 2. SAX解析:逐行读取,基于事件驱动,解析一行释放一行,内存占用非常小 建议:一般会采用DOM解析方式来解析XML,除非是解析体积很大的XML文件才会采用SAX解析 ###### 1.3.5.3 常见的XML解析器 在使用Java代码解析XML的时候,我们通常不会直接使用JDK内置的原生的DOM或者SAX解析XML,因为代码实在是太复杂了。一些公司和组织已经封装好了优秀的XML解析器,我们通常会使用第三方XML解析器来解析XML 1. JAXP: sun公司提供的解析。支持dom和sax。(不常用) 1. JDOM 1. DOM4J(常用) ###### 1.3.5.4 DOM4J的使用步骤 1. 导入jar包 dom4j.jar 1. 创建解析器对象(SAXReader) 1. 解析xml 获得Document对象 1. 获取根节点RootElement 1. 获取根节点下的子节点 ###### 1.3.5.5 DOM4J的API介绍 1. 创建SAXReader对象 SAXReader saxReader = new SAXReader(); 1. 解析XML获取Document对象: 需要传入要解析的XML文件的字节输入流 Document document = reader.read(inputStream); 1. 获取文档的根标签 Element rootElement = documen.getRootElement() 1. 获取标签的子标签 //获取所有子标签 List //获取指定标签名的子标签 List ###### 1.3.5.6 XPATH的使用介绍 1. XPATH的作用: 使用规则匹配直接查找xml文件中的指定节点 1. XPATH的使用步骤: 1. 引入dom4j和xpath的jar包 1. 创建解析器对象 1. 解析xml 获得document对象 1. 使用document对象调用方法,根据路径规则查找节点 3. XPATH的API: - selectSingleNode(“路径规则”): 根据路径规则,查找满足条件的第一个节点 - selectNodes(“路径规则”): 根据路径规则,查找满足条件的所有节点 4. XPATH的路径规则的编写: 见附件资料 ## 第六章 Tomcat(最重要) ### 1. Web服务器 - Web服务器通常由硬件和软件共同构成。 - 硬件:电脑,提供服务供其它客户电脑访问 - - - 软件:电脑上安装的服务器软件,安装后能提供服务给网络中的其他计算机,将本地文件映射成一个虚拟的url地址供网络中的其他人访问。 - Web服务器主要用来接收客户端发送的请求和响应客户端请求。 - 常见的JavaWeb服务器: - Tomcat(Apache):当前应用最广的JavaWeb服务器 - JBoss(Redhat红帽):支持JavaEE,应用比较广EJB容器 –> SSH轻量级的框架代替 - GlassFish(Orcale):Oracle开发JavaWeb服务器,应用不是很广 - Resin(Caucho):支持JavaEE,应用越来越广 - Weblogic(Orcale):要钱的!支持JavaEE,适合大型项目 - Websphere(IBM):要钱的!支持JavaEE,适合大型项目 ### 2 Tomcat服务器 #### 2.1 Tomcat简介 Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。 #### 2.2 Tomcat下载 - Tomcat官方网站:http://tomcat.apache.org/ - 安装版:需要安装,一般不考虑使用。 - 解压版: 直接解压缩使用,我们使用的版本。 - 因为tomcat服务器软件需要使用java环境,所以需要正确配置JAVA_HOME。 #### 2.3 Tomcat的版本 - 版本:企业用的比较广泛的是7.0和8.0的。授课我们使用8.0。 - tomcat6以下都不用了,所以我们从tomcat6开始比较: - tomcat6 支持servlet2.5、jsp2.1、el - tomcat7 支持servlet3.0、jsp2.2、el2.2、websocket1.1 - tomcat8 支持servlet3.1、jsp2.3、el3.0、websocket1.1 - tomcat9 支持servlet4.0、jsp2.3、el3.0、websocket1.1 #### 2.4 安装 解压apache-tomcat-8.5.27-windows-x64.zip到非中文无空格目录中 #### 2.5 配置 启动Tomcat前,需要配置JAVA_HOME的环境变量 #### 2.6 启动 在命令行中运行catalina run或者 Tomcat解压目录下双击startup.bat 启动Tomcat服务器,在浏览器地址栏访问如下地址进行测试 http://localhost:8080 如果启动失败,查看如下的情况: 情况一:如果双击startup.bat后窗口一闪而过,请查看JAVA_HOME是否配置正确。 startup.bat会调用catalina.bat,而catalina.bat会调用setclasspath.bat,setclasspath.bat会使用JAVA_HOME环境变量,所以我们必须在启动Tomcat之前把JAVA_HOME配置正确。 情况二:如果启动失败,提示端口号被占用,则将默认的8080端口修改为其他未使用的值,例如8989等。 【方法】 打开:解压目录\conf\server.xml,找到第一个Connector标签,修改port属性 web服务器在启动时,实际上是监听了本机上的一个端口,当有客户端向该端口发送请求时,web服务器就会处理请求。但是如果不是向其所监听的端口发送请求,web服务器不会做任何响应。例如:Tomcat启动监听了8989端口,而访问的地址是http://localhost:8080,将不能正常访问。 #### 2.7 在IDEA中创建Tomcat 在IDEA中配置好Tomcat后,可以直接通过IDEA控制Tomcat的启动和停止,而不用再去操作startup.bat和shutdown.bat。 ① 点击File—>Settings 或者直接点击图标 接着: 接着: ### 3 动态Web工程部署与测试 #### 3.1 创建动态Web工程 接着: #### 3.2 开发项目目录结构说明 - src:存放Java源代码的目录。 - web:存放的是需要部署到服务器的文件 - WEB-INF:这个目录下的文件,是不能被客户端直接访问的。 - lib:用于存放该工程用到的库。粘贴过来以后 - web.xml:web工程的配置文件,完成用户请求的逻辑名称到真正的servlet类的映射。 - 凡是客户端能访问的资源(.html或 .jpg)必须跟WEB-INF在同一目录,即放在Web根目录下的资源,从客户端是可以通过URL地址直接访问的。 #### 3.3 tomcat实例的基础设置 由于每次创建项目随之创建的tomcat实例名字都类似,所以建议修改一下tomcat实例的名称 在如下界面进行基础设置 2.11 导入现有的Module 如果你想把老师发给你的module导入自己的project中运行起来,可以参考下面的操作: 做下面操作前,需要把要导入的module复制到project目录下。 # 第七章 HTTP协议 ## 一、 HTTP协议简介 - HTTP 超文本传输协议 (HTTP-Hypertext transfer protocol),是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过十几年的使用与发展,得到不断地完善和扩展。它是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。 - 客户端与服务端通信时传输的内容我们称之为报文。HTTP协议就是规定报文的格式。 - HTTP就是一个通信规则,这个规则规定了客户端发送给服务器的报文格式,也规定了服务器发送给客户端的报文格式。实际我们要学习的就是这两种报文。客户端发送给服务器的称为”请求报文“,服务器发送给客户端的称为”响应报文“。 - 类比于生活中案例:① 毕业租房,签署租房协议,规范多方需遵守的规则。②与远方的朋友的写信。信封的规范。 - 实际互联网: - 客户端 与 服务端进行通信。比如:用户 —-> 访问京东(就是一个数据传输的过程),数据传输需要按照一种协议去传输。就如,用户给服务器写信;服务器给用户回信。有格式:协议。HTTP协议规定通信规则。规定互联网之间如何传输数据。 - 信:报文。 - 写信:用户给服务器写信,用户给服务器发请求。把发的请求所有数据,请求报文 - 回信:服务器回信给用户,回给浏览器。把服务器响应浏览器的所有数据,响应报文 ## 二、 HTTP协议的发展历程 - 超文本传输协议的前身是世外桃源(Xanadu)项目,超文本的概念是泰德·纳尔森(Ted Nelson)在1960年代提出的。进入哈佛大学后,纳尔森一直致力于超文本协议和该项目的研究,但他从未公开发表过资料。1989年,蒂姆·伯纳斯·李(Tim Berners Lee)在CERN(欧洲原子核研究委员会 = European Organization for Nuclear Research)担任软件咨询师的时候,开发了一套程序,奠定了万维网(WWW = World Wide Web)的基础。1990年12月,超文本在CERN首次上线。1991年夏天,继Telnet等协议之后,超文本转移协议成为互联网诸多协议的一分子。 - 当时,Telnet协议解决了一台计算机和另外一台计算机之间一对一的控制型通信的要求。邮件协议解决了一个发件人向少量人员发送信息的通信要求。文件传输协议解决一台计算机从另外一台计算机批量获取文件的通信要求,但是它不具备一边获取文件一边显示文件或对文件进行某种处理的功能。新闻传输协议解决了一对多新闻广播的通信要求。而超文本要解决的通信要求是:在一台计算机上获取并显示存放在多台计算机里的文本、数据、图片和其他类型的文件;它包含两大部分:超文本转移协议和超文本标记语言(HTML)。HTTP、HTML以及浏览器的诞生给互联网的普及带来了飞跃。 ## 三、 HTTP协议的会话方式 - 浏览器与服务器之间的通信过程要经历四个步骤 - 浏览器与WEB服务器的连接过程是短暂的,每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接。 - 浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应对。 ## 四、 HTTP1.0和HTTP1.1的区别 在HTTP1.0版本中,浏览器请求一个带有图片的网页,会由于下载图片而与服务器之间开启一个新的连接;但在HTTP1.1版本中,允许浏览器在拿到当前请求对应的全部资源后再断开连接,提高了效率。 ## 五、 不同浏览器监听HTTP操作 ### 5.1 Chrome中F12可查看 ### 5.4 FireFox中F12可查看 ## 六、 报文 ### 6.1 报文格式 - 报文: - 请求报文:浏览器发给服务器 - 响应报文:服务器发回给浏览器 ### 6.2 请求报文 #### 6.2.1 报文格式 (4部分) - 请求首行(请求行); - 请求头信息(请求头); - 空行; - 请求体; #### 6.2.2 GET请求 1、由于请求参数在请求首行中已经携带了,所以没有请求体,也没有请求空行 2、请求参数拼接在url地址中,地址栏可见[url?name1=value1&name2=value2],不安全 3、由于参数在地址栏中携带,所以由大小限制[地址栏数据大小一般限制为4k],只能携带纯文本 4、get请求参数只能上传文本数据 5、没有请求体。所以封装和解析都快,效率高, 浏览器默认提交的请求都是get请求[比如:① 地址栏输入url地址回车,②点击超链接a , ③ form表单默认方式…] - 请求首行 GET /05_web_tomcat/login_success.html?username=admin&password=123213 HTTP/1.1 请求方式 访问的服务器中的资源路径?get请求参数 协议版本 - 请求头 Host: localhost:8080 主机虚拟地址 Connection: keep-alive 长连接 Upgrade-Insecure-Requests: 1 请求协议的自动升级[http的请求,服务器却是https的,浏览器自动会将请求协议升级为https的] User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36 - 用户系统信息 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 - 浏览器支持的文件类型 Referer: http://localhost:8080/05_web_tomcat/login.html - 当前页面的上一个页面的路径[当前页面通过哪个页面跳转过来的]: 可以通过此路径跳转回上一个页面, 广告计费,防止盗链 Accept-Encoding: gzip, deflate, br - 浏览器支持的压缩格式 Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 - 浏览器支持的语言 #### 6.2.3 POST请求 - POST请求要求将form标签的method的属性设置为post 1、POST请求有请求体,而GET请求没有请求体。 2、post请求数据在请求体中携带,请求体数据大小没有限制,可以用来上传所有内容[文件、文本] 3、只能使用post请求上传文件 4、post请求报文多了和请求体相关的配置[请求头] 5、地址栏参数不可见,相对安全 6、post效率比get低 - 请求首行 POST /05_web_tomcat/login_success.html HTTP/1.1 - 请求头 Host: localhost:8080 Connection: keep-alive Content-Length: 31 -请求体内容的长度 Cache-Control: max-age=0 -无缓存 Origin: http://localhost:8080 Upgrade-Insecure-Requests: 1 -协议的自动升级 Content-Type: application/x-www-form-urlencoded -请求体内容类型[服务器根据类型解析请求体参数] User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Referer: http://localhost:8080/05_web_tomcat/login.html Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 Cookie:JSESSIONID- - 请求空行 - 请求体:浏览器提交给服务器的内容 username=admin&password=1232131 ### 6.3 响应报文 #### 6.3.1 报文格式(4部分) - 响应首行(响应行); - 响应头信息(响应头); - 空行; - 响应体; #### 6.3.2 具体情况 - 响应首行: - HTTP/1.1 200 OK 说明:响应协议为HTTP1.1,响应状态码为200,表示请求成功; - 响应头: - Server: Apache-Coyote/1.1 服务器的版本信息 Accept-Ranges: bytes ETag: W/“157-1534126125811” Last-Modified: Mon, 13 Aug 2018 02:08:45 GMT Content-Type: text/html 响应体数据的类型[浏览器根据类型解析响应体数据] Content-Length: 157 响应体内容的字节数 Date: Mon, 13 Aug 2018 02:47:57 GMT 响应的时间,这可能会有8小时的时区差 - 响应空行 - 响应体 - <!DOCTYPE html> 恭喜你,登录成功了… #### 6.3.3 响应码 响应码对浏览器来说很重要,它告诉浏览器响应的结果。比较有代表性的响应码如下: - 200:请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中; - 404:请求的资源没有找到,说明客户端错误的请求了不存在的资源; - - - 500:请求资源找到了,但服务器内部出现了错误; - - - 302:重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location,它指定了新请求的URL地址; 除此之外,其它一些响应码如下: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 详细分解: 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码。 代码 说明 100 (继续) 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。 2xx (成功) 表示成功处理了请求的状态代码。 代码 说明 200 (成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。 201 (已创建) 请求成功并且服务器创建了新的资源。 202 (已接受) 服务器已接受请求,但尚未处理。 203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。 205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。 206 (部分内容) 服务器成功处理了部分 GET 请求。 3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。 代码 说明 300 (多种选择) 针对请求,服务器可执行多种操作。服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 301 (永久移动) 请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。 302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。 304 (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。 305 (使用代理) 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。 307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。 代码 说明 400 (错误请求) 服务器不理解请求的语法。 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 403 (禁止) 服务器拒绝请求。 404 (未找到) 服务器找不到请求的网页。 405 (方法禁用) 禁用请求中指定的方法。 406 (不接受) 无法使用请求的内容特性响应请求的网页。 407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。 408 (请求超时) 服务器等候请求时发生超时。 409 (冲突) 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。 410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。 411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。 412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。 415 (不支持的媒体类型) 请求的格式不受请求页面的支持。 416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。 417 (未满足期望值) 服务器未满足”期望”请求标头字段的要求。 5xx(服务器错误) 这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。 代码 说明 500 (服务器内部错误) 服务器遇到错误,无法完成请求。 501 (尚未实施) 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。 HttpWatch状态码Result is 200 - 服务器成功返回网页,客户端请求已成功。 302 - 对象临时移动。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 304 - 属于重定向。自上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。 401 - 未授权。请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 404 - 未找到。服务器找不到请求的网页。 2xx - 成功。表示服务器成功地接受了客户端请求。 3xx - 重定向。表示要完成请求,需要进一步操作。客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。 4xx - 请求错误。这些状态代码表示请求可能出错,妨碍了服务器的处理。 5xx - 服务器错误。表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。 # 第八章 Servlet组件 ## 一、 我们为什么需要Servlet? ### 1.1 Web应用基本运行模式 - 生活中的例子 - Web应用运行模 ### 1.2 Web服务器中Servlet作用举例 - 举例一:插入数据 - 举例二:查询数据 通过网页驱动服务器端的Java程序。在网页上显示Java程序返回的数据。 ## 二、 什么是Servlet? 如果把Web应用比作一个餐厅,Servlet就是餐厅中的服务员——负责接待顾客、上菜、结账。 - 从广义上来讲,Servlet规范是Sun公司制定的一套技术标准,包含与Web应用相关的一系列接口,是Web应用实现方式的宏观解决方案。而具体的Servlet容器负责提供标准的实现。 - 从狭义上来讲,Servlet指的是javax.servlet.Servlet接口及其子接口,也可以指实现了Servlet接口的实现类。 - Servlet(Server Applet)作为服务器端的一个组件,它的本意是“服务器端的小程序”。 - Servlet的实例对象由Servlet容器负责创建; tomcat—>web容器 (包括servlet容器和其他容器) - Servlet的方法由容器在特定情况下调用; - Servlet容器会在Web应用卸载时销毁Servlet对象的实例。 ## 三、 如何使用Servlet? ### 3.1 操作步骤 - 复习:使用一个接口的传统方式: - 创建一个类实现接口 - new 实现类的对象 - 调用类的方法等 - - 使用Servlet接口的方式: - ① 搭建Web开发环境 - ② 创建动态Web工程 - ③ 创建javax.servlet.Servlet接口的实现类:com.atguigu.servlet.MyFirstServlet - ④ 在service(ServletRequest, ServletResponse)方法中编写如下代码,输出响应信息: @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { //1.编写输出语句,证明当前方法被调用 System.out.println(“Servlet worked…”); //2.通过PrintWriter对象向浏览器端发送响应信息 PrintWriter writer = res.getWriter(); writer.write(“Servlet response”); writer.close(); } ⑤ 在web.xml配置文件中注册MyFirstServlet 说明: - :这个url-pattern可以配置多个,这时表示的就是访问这些url都会触发这个Servlet进行响应,运行浏览器,访问刚才配置的url路径,Servlet的service方法就会被调用。 - 中的文本内容必须以 / 或 . 开始书写路径。相当于将资源映射到项目根目录下形成虚拟的资源文件。 - 中的可以声明多个,可以通过任意一个都可以访问。但是开发中一般只会配置一个。 ⑥ 在WebContent目录下创建index.html ⑦ 在index.html中加入超链接 To Servlet ⑧ 点击超链接测试Servlet ### 3.2 运行分析(执行原理) - index.html - web.xml - 如果配置文件一旦修改,需要重启服务器来重新部署web项目。 ### 3.3 Servlet作用总结 - 接收请求 【解析请求报文中的数据:请求参数】 - 处理请求 【DAO和数据库交互】 - 完成响应 【设置响应报文】 ## 四、 Servlet生命周期(重要) ### 4.1 Servlet生命周期概述 - 应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为——这就是对象的生命周期。 - 简单的叙述生命周期,就是对象在容器中从开始创建到销毁的过程。 ### 4.2 Servlet容器 Servlet对象是Servlet容器创建的,生命周期方法都是由容器调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。 ### 4.3 Servlet生命周期的主要过程 #### ① Servlet对象的创建:构造器 - 默认情况下,Servlet容器第一次收到HTTP请求时创建对应Servlet对象。 - 容器之所以能做到这一点是由于我们在注册Servlet时提供了全类名,容器使用反射技术创建了Servlet的对象。 #### ② Servlet对象初始化:init() - Servlet容器创建Servlet对象之后,会调用init(ServletConfig config)方法。 - 作用:是在Servlet对象创建后,执行一些初始化操作。例如,读取一些资源文件、配置文件,或建立某种连接(比如:数据库连接) - init()方法只在创建对象时执行一次,以后再接到请求时,就不执行了 - 在javax.servlet.Servlet接口中,public void init(ServletConfig config)方法要求容器将ServletConfig的实例对象传入,这也是我们获取ServletConfig的实例对象的根本方法。 #### ③ 处理请求:service() - 在javax.servlet.Servlet接口中,定义了service(ServletRequest req, ServletResponse res)方法处理HTTP请求。 - 在每次接到请求后都会执行。 - 上一节提到的Servlet的作用,主要在此方法中体现。 - 同时要求容器将ServletRequest对象和ServletResponse对象传入。 #### ④ Servlet对象销毁:destroy() - 服务器重启、服务器停止执行或Web应用卸载时会销毁Servlet对象,会调用public void destroy()方法。 - 此方法用于销毁之前执行一些诸如释放缓存、关闭连接、保存内存数据持久化等操作。 ### 4.4 Servlet请求过程 - 第一次请求 - 调用构造器,创建对象 - 执行init()方法 - 执行service()方法 - 后面请求 - 执行service()方法 - 对象销毁前 - 执行destroy()方法 ## 五、 Servlet的两个重要接口 ### 5.1 ServletConfig接口 - ServletConfig接口封装了Servlet配置信息,这一点从接口的名称上就能够看出来。 - 每一个Servlet都有一个唯一对应的ServletConfig对象,代表当前Servlet的配置信息。 - 对象由Servlet容器创建,并传入生命周期方法init(ServletConfig config)中。可以直接获取使用。 - 代表当前Web应用的ServletContext对象也封装到了ServletConfig对象中,使ServletConfig对象成为了获取ServletContext对象的一座桥梁。 - ServletConfig对象的主要功能 - 获取Servlet名称:getServletName() - 获取全局上下文ServletContext对象:getServletContext() - 获取Servlet初始化参数:getInitParameter(String) / getInitParameterNames()。 - 使用如下: - - - 通过String info = config.getInitParameter(“url”);的方式获取value值 - ### 5.2 ServletContext接口 - Web容器在启动时,它会为每个Web应用程序都创建一个唯一对应的ServletContext对象,意思是Servlet上下文,代表当前Web应用。 - 由于一个Web应用程序中的所有Servlet都共享同一个ServletContext对象,所以ServletContext对象也被称为 application 对象(Web应用程序对象)。 - 对象由Servlet容器在项目启动时创建,通过ServletConfig对象的getServletContext()方法获取。在项目卸载时销毁。 - ServletContext对象的主要功能 - ① 获取项目的上下文路径(带/的项目名): getContextPath() - @Override public void init(ServletConfig config) throws ServletException { ServletContext application = config.getServletContext(); System.out.println(“全局上下文对象:”+application); String path = application.getContextPath(); System.out.println(“全局上下文路径:”+path);// /06_Web_Servlet } - ② 获取虚拟路径所映射的本地真实路径:getRealPath(String path) - 虚拟路径:浏览器访问Web应用中资源时所使用的路径。 - 本地路径:资源在文件系统中的实际保存路径。 - 作用:将用户上传的文件通过流写入到服务器硬盘中。 - @Override public void init(ServletConfig config) throws ServletException { //1.获取ServletContext对象 ServletContext context = config.getServletContext(); //2.获取index.html的本地路径 //index.html的虚拟路径是“/index.html”,其中“/”表示当前Web应用的根目录, //即WebContent目录 String realPath = context.getRealPath(“/index.html”); //realPath=D:\DevWorkSpace\MyWorkSpace.metadata.plugins\ //org.eclipse.wst.server.core\tmp0\wtpwebapps\MyServlet\index.html System.out.println(“realPath=”+realPath); } - ③ 获取WEB应用程序的全局初始化参数(基本不用) - 设置Web应用初始化参数的方式是在web.xml的根标签下加入如下代码 - public void init(ServletConfig config) throws ServletException { //1.获取ServletContext对象 ServletContext application = config.getServletContext(); //2.获取Web应用初始化参数 String paramValue = application.getInitParameter(“ParamName”); System.out.println(“全局初始化参数paramValue=”+paramValue); } - ④ 作为域对象共享数据 - 作为最大的域对象在整个项目的不同web资源内共享数据。 - - - 其中, - setAttribute(key,value):以后可以在任意位置取出并使用 - getAttribute(key):取出设置的value值 ## 六、 Servlet技术体系 ### 6.1 Servlet接口 ### 6.2 Servlet接口的常用实现类 - 为什么要扩展Servlet接口? - 封装不常用方法 - 实现类体系 - GenericServlet实现Servlet接口 - HttpServlet继承GenericServlet - 创建Servlet的最终方式 - 继承HttpServlet #### 6.2.1 GenericServlet抽象类 - GenericServlet对Servlet功能进行了封装和完善,重写了init(ServletConfig config)方法,用来获取ServletConfig对象。此时如果GenericServlet的子类(通常是自定义Servlet)又重写了init(ServletConfig config)方法有可能导致ServletConfig对象获取不到,所以子类不应该重写带参数的这个init()方法。 - 如果想要进行初始化操作,可以重写GenericServlet提供的无参的init()方法,这样就不会影响ServletConfig对象的获取。 - 将service(ServletRequest req,ServletResponse res)保留为抽象方法,让使用者仅关心业务实现即可。 #### 6.2.2 HttpServlet抽象类 - 专门用来处理Http请求的Servlet。 - 对GenericServlet进行进一步的封装和扩展,在service(ServletRequest req, ServletResponse res)方法中,将ServletRequest和ServletResponse转换为HttpServletRequest和HttpServletResponse,根据不同HTTP请求类型调用专门的方法进行处理。 - 今后在实际使用中继承HttpServlet抽象类创建自己的Servlet实现类即可。重写doGet(HttpServletRequest req, HttpServletResponse resp)和doPost(HttpServletRequest req, HttpServletResponse resp)方法实现请求处理,不再需要重写service(ServletRequest req, ServletResponse res)方法了。 - 又因为我们业务中get,post的处理方式又都是一样的,所以我们只需要写一种方法即可,使用另外一种方法调用我们写好的doXXX方法。web.xml配置与之前相同。 - //处理浏览器的get请求 doGet(HttpServletRequest request, HttpServletResponse response){ //业务代码 } //处理浏览器的post请求 doPost(HttpServletRequest request, HttpServletResponse response){ doGet(request, response); } ## 七、 其它几个重要的接口 ### 7.1 HttpServletRequest接口 - 该接口是ServletRequest接口的子接口,封装了HTTP请求的相关信息。 - 浏览器请求服务器时会封装请求报文交给服务器,服务器接受到请求会将请求报文解析生成request对象。 - 由Servlet容器创建其实现类对象并传入service(HttpServletRequest req, HttpServletResponse res)方法中。 - 以下我们所说的HttpServletRequest对象指的是容器提供的HttpServletRequest实现类对象。 HttpServletRequest对象的主要功能有: #### 7.1.1 获取请求参数 - 什么是请求参数? - 请求参数就是浏览器向服务器提交的数据。 - 浏览器向服务器如何发送数据? - ① 附在url后面(和get请求一致,拼接的形式就行请求数据的绑定),如: - http://localhost:8080/MyServlet/MyHttpServlet?userId=20 - ② 通过表单提交 - - 使用HttpServletRequest对象获取请求参数 - //一个name对应一个值 String userId = request.getParameter(“userId”); - //一个name对应一组值 String[] soccerTeams = request.getParameterValues(“soccerTeam”); for(int i = 0; i < soccerTeams.length; i++){ System.out.println(“team “+i+”=”+soccerTeams[i]); } #### 7.1.2 获取url地址参数 String path = request.getContextPath();//重要 System.out.println(“上下文路径:”+path); System.out.println(“端口号:”+request.getServerPort()); System.out.println(“主机名:”+request.getServerName()); System.out.println(“协议:”+request.getScheme()); #### 7.1.3 获取请求头信息 String header = request.getHeader(“User-Agent”); System.out.println(“user-agent:”+header); String referer = request.getHeader(“Referer”); System.out.println(“上个页面的地址:”+referer);//登录失败,返回登录页面让用户继续登录 #### 7.1.4 请求的转发 将请求转发给另外一个URL地址,参见第7章-请求的转发与重定向。 //获取请求转发对象 RequestDispatcher dispatcher = request.getRequestDispatcher(“success.html”); dispatcher.forward(request, response);//发起转发 #### 7.1.5 向请求域中保存数据 //将数据保存到request对象的属性域中 request.setAttribute(“attrName”, “attrValueInRequest”); //两个Servlet要想共享request对象中的数据,必须是转发的关系 request.getRequestDispatcher(“/ReceiveServlet”).forward(request, response); //从request属性域中获取数据 Object attribute = request.getAttribute(“attrName”); System.out.println(“attrValue=”+attribute); ### 7.2 HttpServletResponse接口 - 该接口是ServletResponse接口的子接口,封装了服务器针对于HTTP响应的相关信息。(暂时只有服务器的配置信息,没有具体的和响应体相关的内容) - 由Servlet容器创建其实现类对象,并传入service(HttpServletRequest req, HttpServletResponse res)方法中。 - 后面我们所说的HttpServletResponse对象指的是容器提供的HttpServletResponse实现类对象。 HttpServletResponse对象的主要功能有: #### 7.2.1 使用PrintWriter对象向浏览器输出数据 //通过PrintWriter对象向浏览器端发送响应信息 PrintWriter writer = res.getWriter(); writer.write(“Servlet response”); writer.close(); - 写出的数据可以是页面、页面片段、字符串等 - 当写出的数据包含中文时,浏览器接收到的响应数据就可能有乱码。为了避免乱码,可以使用Response对象在向浏览器输出数据前设置响应头。 #### 7.2.2 设置响应头 - 响应头就是浏览器解析页面的配置。比如:告诉浏览器使用哪种编码和文件格式解析响应体内容 response.setHeader(“Content-Type”, “text/html;charset=UTF-8”); - 设置好以后,会在浏览器的响应报文中看到设置的响应头中的信息。 #### 7.2.3 重定向请求 - 实现请求重定向,参见第8章-请求的转发与重定向。 - 举例:用户从login.html页面提交登录请求数据给LoginServlet处理。如果账号密码正确,需要让用户跳转到成功页面,通过servlet向响应体中写入成功页面过于复杂,通过重定向将成功页面的地址交给浏览器并设置响应状态码为302,浏览器会自动进行跳转。 //注意路径问题,加上/会失败,会以主机地址为起始,重定向一般需要加上项目名 response.sendRedirect(“success.html”); ## 八、 请求的转发与重定向 请求的转发与重定向是web应用页面跳转的主要手段,在Web应用中使用非常广泛。所以我们一定要搞清楚他们的区别。 ### 8.1 请求的转发 - 第一个Servlet接收到了浏览器端的请求,进行了一定的处理,然后没有立即对请求进行响应,而是将请求“交给下一个Servlet”继续处理,下一个Servlet处理完成之后对浏览器进行了响应。在服务器内部将请求“交给”其它组件继续处理就是请求的转发。对浏览器来说,一共只发了一次请求,服务器内部进行的“转发”浏览器感觉不到,同时浏览器地址栏中的地址不会变成“下一个Servlet”的虚拟路径。 - HttpServletRequest代表HTTP请求,对象由Servlet容器创建。转发的情况下,两个Servlet可以共享同一个Request对象中保存的数据。 - 当需要将后台获取的数据传送到JSP上显示的时候,就可以先将数据存放到Request对象中,再转发到JSP从属性域中获取。此时由于是“转发”,所以它们二者共享Request对象中的数据。 - 转发的情况下,可以访问WEB-INF下的资源。 - 转发以“/”开始表示项目根路径,重定向以”/”开始表示主机地址。 - 功能: - 获取请求参数 - 获取请求路径即URL地址相关信息 - 在请求域中保存数据 - 转发请求 - 代码举例 protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { //1.使用RequestDispatcher对象封装目标资源的虚拟路径 RequestDispatcher dispatcher = request.getRequestDispatcher(“/index.html”); //2.调用RequestDispatcher对象的forward()方法“前往”目标资源 //[注意:传入的参数必须是传递给当前Servlet的service方法的 //那两个ServletRequest和ServletResponse对象] dispatcher.forward(request, response); } ### 8.2 请求的重定向 - 第一个Servlet接收到了浏览器端的请求,进行了一定的处理,然后给浏览器一个特殊的响应消息,这个特殊的响应消息会通知浏览器去访问另外一个资源,这个动作是服务器和浏览器自动完成的。整个过程中浏览器端会发出两次请求,且在浏览器地址栏里面能够看到地址的改变,改变为下一个资源的地址。 - 重定向的情况下,原Servlet和目标资源之间就不能共享请求域数据了。 - HttpServletResponse代表HTTP响应,对象由Servlet容器创建。 - 功能: - 向浏览器输出数据 - 重定向请求 - 重定向的响应报文的头 - HTTP/1.1 302 Found Location: success.html - 应用: - 用户从login.html页面提交登录请求数据给LoginServlet处理。 - 如果账号密码正确,需要让用户跳转到成功页面,通过servlet向响应体中写入成功页面过于复杂,通过重定向将成功页面的地址交给浏览器并设置响应状态码为302,浏览器会自动进行跳转 - 代码举例: protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { //1.调用HttpServletResponse对象的sendRedirect()方法 //2.传入的参数是目标资源的虚拟路径 response.sendRedirect(“index.html”); } ### 8.3 对比请求的转发与重定向 | | 转发 | 重定向 | | —- | —- | —- | | 浏览器感知 | 在服务器内部完成,浏览器感知不到 | 服务器以302状态码通知浏览器访问新地址,浏览器有感知 | | 浏览器地址栏 | 不改变 | 改变 | | 整个过程发送请求次数 | 一次 | 两次 | | 执行效率 | 效率高 | 效率低 | | API(或发起者) | Request对象 | Response对象 | | 能否共享request对象数据 | 能 | 否 | | WEB-INF下的资源 | 能访问 | 不能访问 | | 目标资源 | 必须是当前web应用中的资源 | 不局限于当前web应用 | 说明1:默认情况下,浏览器是不能访问服务器web-inf下的资源的,而服务器是可以访问的。 说明2:浏览器默认的绝对路径:http://localhost:8080/ 服务器项目的代码中的绝对路径:http://localhost:8080/项目名/ ## 九、 请求与响应中的字符编码设置 ### 9.1 字符编码问题 - 我们web程序在接收请求并处理过程中,如果不注意编码格式及解码格式,很容易导致中文乱码,引起这个问题的原因到底在哪里?如何解决?我们这个小节将会讨论此问题。 - 说到这个问题我们先来说一说字符集。 - 什么是字符集,就是各种字符的集合,包括汉字,英文,标点符号等等。各国都有不同的文字、符号。这些文字符号的集合就叫字符集。 - 现有的字符集ASCII、GB2312、BIG5、GB18030、Unicode、UTF-8、ISO-8859-1等 - 这些字符集,集合了很多的字符,然而,字符要以二进制的形式存储在计算机中,我们就需要对其进行编码,将编码后的二进制存入。取出时我们就要对其解码,将二进制解码成我们之前的字符。这个时候我们就需要制定一套编码解码标准。否则就会导致出现混乱,也就是我们的乱码。 ### 9.2 编码与解码 - 编码:将字符转换为二进制数 | 汉字 | 编码方式 | 编码 | 二进制 | | —- | —- | —- | —- | | ‘中’ | GB2312 | D6D0 | 1101 0110-1101 0000 | | ‘中’ | UTF-16 | 4E2D | 0100 1110-0010 1101 | | ‘中’ | UTF-8 | E4B8AD | 1110 0100- 1011 1000-1010 1101 | - 解码:将二进制数转换为字符 1110 0100-1011 1000-1010 1101 → E4B8AD → ’中’ - 乱码:一段文本,使用A字符集编码,使用B字符集解码,就会产生乱码。所以解决乱码问题的根本方法就是统一编码和解码的字符集。 ### 9.3 解决请求乱码问题 解决乱码的方法:就是统一字符编码。 #### 9.3.1 GET请求 - GET请求参数是在地址后面的。我们需要修改tomcat的配置文件。需要在server.xml文件修改Connector标签,添加URIEncoding=”utf-8”属性。 - 一旦配置好以后,可以解决当前工作空间中所有的GET请求的乱码问题。 #### 9.3.2 POST请求 - post请求提交了中文的请求体,服务器解析出现问题。 - 解决方法:在获取参数值之前,设置请求的解码格式,使其和页面保持一致。 - request.setCharacterEncoding(“utf-8”); - POST请求乱码问题的解决,只适用于当前的操作所在的类中。不能类似于GET请求一样统一解决。因为请求体有可能会上传文件。不一定都是中文字符。 ### 9.4 解决响应乱码问题 - 向浏览器发送响应的时候,要告诉浏览器,我使用的字符集是哪个,浏览器就会按照这种方式来解码。如何告诉浏览器响应内容的字符编码方案。很简单。 - 解决方法一: - response.setHeader(“Content-Type”, “text/html;charset=utf-8”); - 解决方法二 : - response.setContentType(“text/html;charset=utf-8”); - 说明:有的人可能会想到使用response.setCharacterEncoding(“utf-8”),设置reponse对象将UTF-8字符串写入到响应报文的编码为UTF-8。只这样做是不行的,还必须手动在浏览器中设置浏览器的解析用到的字符集。 ## 十、 Web应用路径设置 问题再现: ① 创建Web应用Path,目录结构如图所示 ② 在a.html中有超链接To b.html ③ 如果先直接访问a.html,再通过超链接转到b.html没有问题。 ④ 如果先通过TestServlet转发到a.html,则浏览器地址栏会变成 http://localhost:8989/Path/TestServlet 此时再点击超链接To b.html就会发生问题,找不到b.html。 如何解决? 原因是超链接To b.html使用的是相对路径,浏览器进行解析时,只能以当前浏览器地址栏里的路径为基准。例如,当前浏览器地址栏里的内容是:http://localhost:8989/Path/TestServlet 那么经过浏览器解析后b.html的访问地址就成了:http://localhost:8989/Path/TestServletb.html这显然无法访问到b.html。 完整的url构成如下图: 相对路径和绝对路径 相对路径:虚拟路径如果不以“/”开始,就是相对路径,浏览器会以当前资源所在的虚拟路径为基准对相对路径进行解析,从而生成最终的访问路径。此时如果通过转发进入其他目录,再使用相对路径访问资源就会出错。所以为了防止路径出错,我们经常将相对路径转化为绝对路径的形式进行请求。 绝对路径:虚拟路径以“/”开始,就是绝对路径。 ① 在服务器端:虚拟路径最开始的“/”表示当前Web应用的根目录。只要是服务端解析的绝对路径,都是以web根目录为起始的。由服务器解析的路径包括:<1> web.xml的配置路径、<2>request转发的路径。 ② 在浏览器端:虚拟路径最开始的“/”表示当前主机地址。 例如:链接地址“/Path/dir/b.html”经过浏览器解析后为: 相当于http://localhost:8989/Path/dir/b.html 由浏览器解析的路径包括: <1>重定向操作:response.sendRedirect(“/xxx”) <2>所有HTML标签: 、 |