javaWeb
HTML
HTML入门
概述
HTML(超文本标记语言—HyperText Markup Language)是构成 Web 世界的基础,是一种用来告知浏览器如何组织页面的标记语言
超文本 Hypertext,是指连接单个或者多个网站间的网页的链接。通过链接,就能访问互联网中的内容
标记 Markup ,是用来注明文本,图片等内容,以便于在浏览器中显示,例如
<head>
,<body>
等
网页的构成
- HTML:通常用来定义网页内容的含义和基本结构
- CSS:通常用来描述网页的表现与展示效果
- JavaScript:通常用来执行网页的功能与行为
参考视频:https://www.bilibili.com/video/BV1Qf4y1T7Hx
组成
标签
HTML 页面由一系列的元素(elements) 组成,而元素是使用标签创建的
一对标签(tags)可以设置一段文字样式,添加一张图片或者添加超链接等等
在 HTML 中,<h1>
标签表示标题,我们可以使用开始标签和结束标签包围文本内容,这样其中的内容就以标题的形式显示
1 |
|
属性
HTML 标签可以拥有属性
- 属性是属于标签的,修饰标签,让标签有更多的效果
- 属性一般定义在起始标签里面
- 属性一般以属性=属性值的形式出现
- 属性值一般用
''
或者""
括起来。 不加引号也是可以的(不建议使用)。比如:name=’value’
1 |
|
在 HTML 标签中,align
属性表示水平对齐方式,我们可以赋值为 center
表示 居中 。
结构
文档结构介绍:
- 文档声明:用于声明当前 HTML 的版本,这里的
<!DOCTYPE html>
是 HTML5 的声明 - html 根标签:除文档声明以外,其它内容全部要放在根标签 html 内部
- 文档头部配置:head 标签,是当前页面的配置信息,外部引入文件, 例如网页标签、字符集等
<meta charset="utf-8">
:这个标签是页面的元数据信息,设置文档使用 utf-8 字符集编码<title>
:这个标签定义文档标题,位置出现在浏览器标签。在收藏页面时,它可用来描述页面
- 文档显示内容:body 标签,里边的内容会显示到浏览器页面上
HTML语法
注释方式
将一段 HTML 中的内容置为注释,你需要将其用特殊的记号 包括起来
1 |
|
基本元素
空元素
一些元素只有一个标签,叫做空元素。它是在开始标签中进行关闭的。
1 |
|
嵌套元素
把元素放到其它元素之中——这被称作嵌套。
1 |
|
块元素
在HTML中有两种重要元素类别,块级元素和内联元素
块级元素:
独占一行。块级元素(block)在页面中以块的形式展现。相对于其前面的内容它会出现在新的一行,其后的内容也会被挤到下一行展现。比如
<p>
,<hr>
,<li>
,<div>
等。行内元素
行内显示。行内元素不会导致换行。通常出现在块级元素中并环绕文档内容的一小部分,而不是一整个段落或者一组内容。比如
<b>
,<a>
,<i>
,<span>
等。
注意:一个块级元素不会被嵌套进行内元素中,但可以嵌套在其它块级元素中。
常用的两个标签:(重要)
<div>
是一个通用的内容容器,并没有任何特殊语义。它可以被用来对其它元素进行分组,一般用于样式化相关的需求。它是一个块级元素。- 属性:id、style、class
<span>
是短语内容的通用行内容器,并没有任何特殊语义。它可以被用来编组元素以达到某种样式。它是一个行内元素
基本属性
标签属性,主要用于拓展标签。属性包含元素的额外信息,这些信息不会出现在实际的内容中。但是可以改变标签的一些行为或者提供数据,属性总是以name = value"
的格式展现。
属性名:同一个标签中,属性名不得重复。
大小写:属性和属性值对大小写不敏感。不过W3C标准中,推荐使用小写的属性/属性值。
引号:双引号是最常用的,不过使用单引号也没有问题。
常用属性:
属性名 作用 class 定义元素类名,用来选择和访问特定的元素 id 定义元素唯一标识符,在整个文档中必须是唯一的 name 定义元素名称,可以用于提交服务器的表单字段 value 定义在元素内显示的默认值 style 定义CSS样式,这些样式会覆盖之前设置的样式
特殊字符
在HTML中,字符 <
, >
,"
,'
和 &
是特殊字符
原义字符 | 等价字符引用 |
---|---|
< | < |
> | > |
“ | " |
‘ | ' |
& | & |
空格 | |
文本标签
使用文本内容标签设置文字基本样式
标签名 | 作用 |
---|---|
p | 表示文本的一个段落 |
h | 表示文档标题,<h1>–<h6> ,呈现了六个不同的级别的标题,<h1> 级别最高,而 <h6> 级别最低 |
hr | 表示段落级元素之间的主题转换,一般显示为水平线 |
li | 表示列表里的条目。(常用在ul ol 中) |
ul | 表示一个无序列表,可含多个元素,无编号显示。 |
ol | 表示一个有序列表,通常渲染为有带编号的列表 |
em | 表示文本着重,一般用斜体显示 |
strong | 表示文本重要,一般用粗体显示 |
font | 表示字体,可以设置样式(已过时) |
i | 表示斜体 |
b | 表示加粗文本 |
1 |
|
效果如下:
图片标签
img标签中的img其实是英文image的缩写, img标签的作用, 就是告诉浏览器我们需要显示一张图片
1 |
|
属性名 | 作用 |
---|---|
src | 图片路径 |
title | 鼠标悬停(hover)时显示文本。 |
alt | 图片描述,图形不显示时的替换文本。 |
height | 图像的高度。 |
width | 图像的宽度。 |
超链接
超链接标签的作用: 就是用于控制页面与页面(服务器资源)之间跳转的
1 |
|
1 |
|
效果图:
表单标签
基本介绍
form 表示表单,是用来收集用户输入信息并向 Web 服务器提交的一个容器
1 |
|
属性名 | 作用 |
---|---|
action | 处理此表单信息的Web服务器的URL地址 |
method | 提交此表单信息到Web服务器的方式,可能的值有get和post,默认为get |
autocomplete | 自动补全,指示表单元素是否能够拥有一个默认值,配合input标签使用 |
get与post区别:
post:指的是 HTTP POST 方法;表单数据会包含在表单体内然后发送给服务器。
get:指的是 HTTP GET 方法;表单数据会附加在
action
属性的URI中,并以 ‘?’ 作为分隔符,然后这样得到的 URI 再发送给服务器。
地址栏可见 | 数据安全 | 数据大小 | |
---|---|---|---|
GET | 可见 | 不安全 | 有限制(取决于浏览器) |
POST | 不可见 | 相对安全 | 无限制 |
表单元素
标签名 | 作用 | 备注 |
---|---|---|
label | 表单元素的说明,配合表单元素使用 | for属性值为相关表单元素id属性值 |
input | 表单中输入控件,多种输入类型,用于接受来自用户数据 | type属性值决定输入类型 |
button | 页面中可点击的按钮,可以配合表单进行提交 | type属性值决定按钮类型 |
select | 表单的控件,下拉选项菜单 | 与option配合实用 |
optgroup | option的分组标签 | 与option配合实用 |
option | select的子标签,表示一个选项 | |
textarea | 表示多行纯文本编辑控件 | |
fieldset | 用来对表单中的控制元素进行分组(也包括 label 元素) | |
legend | 用于表示它的fieldset内容的标题。 | fieldset 的子元素 |
按键控件
button标签:表示按钮
- type属性:表示按钮类型,submit值为提交按钮。
属性值 | 作用 | 备注 |
---|---|---|
button | 无行为按钮,用于结合JavaScript实现自定义动态效果 | 同 <input type="submit"/> |
submit | 提交按钮,用于提交表单数据到服务器。 | 同 <input type="submit"/> |
reset | 重置按钮,用于将表单中内容恢复为默认值。 | 同<input type="reset" /> |
输入控件
基本介绍
label标签:表单的说明。
- for属性值:匹配input标签的id属性值
input标签:输入控件。
属性:
- type:表示输入类型,text值为普通文本框
- id:表示标签唯一标识
- name:表示标签名称,提交服务器的标识
- value:表示标签的默认数据值
- placeholder:默认的提示信息,仅适用于当type 属性为text, search, tel, url or email时;
- required:是否必须为该元素填充值,当type属性是hidden,image或者button类型时不可使用
- readonly:是否只读,可以让用户不修改这个输入框的值,就使用value属性设置默认值
- disabled:是否可用,如果某个输入框有disabled那么它的数据不能提交到服务器通常是使用在有的页面中,让一些按钮不能点击
- autocomplete:自动补全,规定表单或输入字段是否应该自动完成。当自动完成开启,浏览器会基于用户之前的输入值自动填写值。可以设置指定的字段为off,关闭自动补全
1 |
|
效果图:
n-v属性
属性名 | 作用 |
---|---|
name | <input> 的名字,在提交整个表单数据时,可以用于区分属于不同<input> 的值 |
value | 这个<input> 元素当前的值,允许用户通过页面输入 |
使用方式:以name属性值作为键,value属性值作为值,构成键值对提交到服务器,多个键值对浏览器使用&
进行分隔。
type属性
属性值 | 作用 | 备注 |
---|---|---|
text | 单行文本字段 | |
password | 单行文本字段,值被遮盖 | |
用于编辑 e-mail 的字段,可以对e-mail地址进行简单校验 | ||
radio | 单选按钮。 1. 在同一个”单选按钮组“中,所有单选按钮的 name 属性使用同一个值;一个单选按钮组中是,同一时间只有一个单选按钮可以被选择。 2. 必须使用 value 属性定义此控件被提交时的值。 3. 使用checked 必须指示控件是否缺省被选择。 | |
checkbox | 复选框。 1. 必须使用 value 属性定义此控件被提交时的值。 2. 使用 checked 属性指示控件是否被选择。 3. 选中多个值时,所有的值会构成一个数组而提交到Web服务器 | |
date | HTML5 用于输入日期的控件 | 年,月,日,不包括时间 |
time | HTML5 用于输入时间的控件 | 不含时区 |
datetime-local | HTML5 用于输入日期时间的控件 | 不包含时区 |
number | HTML5 用于输入浮点数的控件 | |
range | HTML5 用于输入不精确值控件 | max-规定最大值min-规定最小值 step-规定步进值 value-规定默认值 |
search | HTML5 用于输入搜索字符串的单行文本字段 | 可以点击x 清除内容 |
tel | HTML5 用于输入电话号码的控件 | |
url | HTML5 用于编辑URL的字段 | 可以校验URL地址格式 |
file | 此控件可以让用户选择文件,用于文件上传。 | 使用 accept 属性可以定义控件可以选择的文件类型。 |
hidden | 此控件用户在页面上不可见,但它的值会被提交到服务器,用于传递隐藏值 |
1 |
|
选择控件
下拉列表标签
1 |
|
option:选择菜单的选项
optgroup:列表项分组标签
属性:label设置分组名称
文本域控件
1 |
|
属性:
name-标签名称
rows-行数
cols-列数
1 |
|
分组控件
1 |
|
表格标签
基本属性
<table>
, 表示表格标签,表格是数据单元的行和列的两维表
- tr:table row,表示表中单元的行
- td:table data,表示表中一个单元格
- th:table header,表格单元格的表头,通常字体样式加粗居中
代码展示:
1 |
|
效果图:
First name | Last name |
---|---|
John | Doe |
Jane | Doe |
跨行跨列
1 |
|
效果图:
表格结构
标签名 | 作用 | 备注 |
---|---|---|
thead | 定义表格的列头的行 | 一个表格中仅有一个 |
tbody | 定义表格的主体 | 用来封装一组表行(tr元素) |
tfoot | 定义表格的各列汇总行 | 一个表格中仅有一个 |
样式布局
基本格式
在head标签中,通过style标签加入样式。
基本格式:可以含有多个属性,一个属性名也可以含有多个值,同时设置多样式。
1 |
|
背景格式
background属性用来设置背景相关的样式。
背景色
[background-color
]属性定义任何元素的背景色1
2
3body {
background-color: #567895;
}背景图
该[background-image
]属性允许在元素的背景中显示图像。使用url函数指定图片路径1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>背景图片</title>
<style>
body{
/*添加背景图片*/
background: url("../img/bg.png");
}
</style>
</head>
<body>
</body>
</html>背景重复
[
background-repeat
]属性用于控制图像的平铺行为。可用值:no-repeat
-停止完全重复背景repeat-x
—水平重复repeat-y
—竖直重复repeat
—默认值;双向重复
1
2
3
4body {
background-image: url(star.png);
background-repeat: repeat-x;/*水平重复*/
}
div布局
div简单布局:
- broader:边界
- solid:实线
- blue:颜色
1
2
3
4
5
6
7<style>
div{ border: 1px solid blue;}
</style>
<div >left</div>
<div >center</div>
<div>right</div>class值
可以设置宽度,浮动,背景1
2
3
4
5
6.class值{
属性名:属性值;
}
<标签名 class="class值">
提示: class是自定义的值属性
background:背景颜色
width:宽度 (npx 或者 n%)
height:长度
text-align:文本对齐方式
background-image: url(“../img/bg.png”):背景图
float:浮动
指定一个元素应沿其容器的左侧或右侧放置,允许文本或者内联元素环绕它,该元素从网页的正常流动中移除,其他部分保持正常文档流顺序。
1
2
3
4
5
6
7<!-- 加入浮动 -->
float:none;不浮动
float:left;左浮动
float:right;右浮动
<!-- 清除浮动 -->
clear:both;清除两侧浮动,此元素不再收浮动元素布局影响。
div基本布局
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">
<title>样式演示</title>
<style>
/*给div标签添加边框*/
div{
border: 1px solid red;
}
/*左侧图片的div样式*/
.left{
width: 20%;
float: left;
height: 500px;
}
/*中间正文的div样式*/
.center{
width: 59%;
float: left;
height: 500px;
}
/*右侧广告图片的div样式*/
.right{
width: 20%;
float: left;
height: 500px;
}
/*底部超链接的div样式*/
.footer{
/*清除浮动效果*/
clear: both;
/*文本对齐方式*/
text-align: center;
/*背景颜色*/
background: blue;
}
</style>
</head>
<body>
<!--顶部登陆注册-->
<div>top</div>
<!--导航条-->
<div>navibar</div>
<!--左侧图片-->
<div class="left">left</div>
<!--中间正文-->
<div class="center">center</div>
<!--右侧广告图片-->
<div class="right">right</div>
<!--底部页脚超链接-->
<div class="footer">footer</div>
</body>
</html>
语义化标签
为了更好的组织文档,HTML5规范中设计了几个语义元素,可以将特殊含义传达给浏览器。
标签 | 名称 | 作用 | 备注 |
---|---|---|---|
header | 标头元素 | 表示内容的介绍 | 块元素,文档中可以定义多个 |
nav | 导航元素 | 表示导航链接 | 常见于网站的菜单,目录和索引等,可以嵌套在header中 |
article | 文章元素 | 表示独立内容区域 | 标签定义的内容本身必须是有意义且必须独立于文档的其他部分 |
footer | 页脚元素 | 表示页面的底部 | 块元素,文档中可以定义多个 |
HTML拓展
音频标签
<audio>
:用于播放声音,比如音乐或其他音频流,是 HTML 5 的新标签。
常用属性:
属性名 | 取值 | 描述 |
---|---|---|
src | URL | 音频资源的路径 |
autoplay | autoplay | 音频准备就绪后自动播放 |
controls | controls | 显示控件,比如播放按钮。 |
loop | loop | 表示循环播放 |
preload | preload | 音频在页面加载时进行预加载。 如果使用 “autoplay”,则忽略该属性。 |
视频标签
<video>
标签用于播放视频,比如电影片段或其他视频流,是 HTML 5 的新标签。
常用属性:
属性名 | 取值 | 描述 |
---|---|---|
src | URL | 要播放的视频的 URL。 |
width | 设置视频播放器的宽度。 | |
height | 设置视频播放器的高度。 | |
autoplay | autoplay | 视频在就绪后自动播放。 |
control | controls | 显示控件,比如播放按钮。 |
loop | loop | 如果出现该属性,则当媒介文件完成播放后再次开始播放。 |
preload | preload | 视频在页面加载时进行加载。 如果使用 “autoplay”,则忽略该属性。 |
mute | muted | 规定视频的音频输出应该被静音。 |
poste | URL | 视频下载时显示的图像,或者视频播放前显示的图像。 |
1 |
|
回到顶部
在html里面锚点的作用: 通过a标签跳转到指定的位置.
1 |
|
详情概要
summary标签来描述概要信息, 利用details标签来描述详情信息. 默认情况下是折叠展示, 想看见详情必须点击
1 |
|
概要信息
详情信息CSS
CSS入门
概述
CSS (层叠样式表——Cascading Style Sheets,缩写为 CSS),简单的说,它是用于设置和布局网页的计算机语言。会告知浏览器如何渲染页面元素。例如,调整内容的字体,颜色,大小等样式,设置边框的样式,调整模块的间距等。
层叠:是指样式表允许以多种方式规定样式信息。可以规定在单个元素中,可以在页面头元素中,也可以在另一个CSS文件中,规定的方式会有次序的差别。
样式:是指丰富的样式外观。拿边框距离来说,允许任何设置边框,允许设置边框与框内元素的距离,允许设置边框与边框的距离等等。
组成
CSS是一门基于规则的语言—你能定义用于你的网页中特定元素的一组样式规则。这里面提到了两个概念,一是特定元素,二是样式规则。对应CSS的语法,也就是选择器(selects)和声明(eclarations)。
- 选择器:指定要添加样式的 HTML元素的方式。可以使用标签名,class值,id值等多种方式。
- 声明:形式为**属性(property):值(value)**,用于设置特定元素的属性信息。
- 属性:指示文体特征,例如
font-size
,width
,background-color
。 - 值:每个指定的属性都有一个值,该值指示您如何更改这些样式。
- 属性:指示文体特征,例如
格式:
1 |
|
实现
今天开始学CSS
CSS语法
注释方式
CSS中的注释以/*
和开头*/
。
1 |
|
引入方式
内联样式
内联样式是CSS声明在元素的style
属性中,仅影响一个元素:
格式:
1
<标签 style="属性名:属性值; 属性名:属性值;">内容</标签>
例如:
1
2
3<h1 style="color: blue;background-color: yellow;border: 1px solid black;">
Hello World!
</h1>效果:
Hello World!
特点:格式简单,但是样式作用无法复用到多个元素上,不利于维护
内部样式表
内部样式表是将CSS样式放在style标签中,通常style标签编写在HTML 的head标签内部。
格式:
1
2
3
4
5
6
7
8<head>
<style>
选择器 {
属性名: 属性值;
属性名: 属性值;
}
</style>
</head>例如:
1
2
3
4
5
6
7
8
9<head>
<style>
h1 {
color: blue;
background-color: yellow;
border: 1px solid black;
}
</style>
</head>特点:内部样式只能作用在当前页面上,如果是多个页面,就无法复用了
外部样式表
外部样式表是CSS附加到文档中的最常见和最有用的方法,因为您可以将CSS文件链接到多个页面,从而允许您使用相同的样式表设置所有页面的样式。
外部样式表是指将CSS编写在扩展名为.css
的单独文件中,并从HTML<link>
元素引用它,通常link标签`编写在HTML 的[head]标签内部。
格式
1
<link rel="stylesheet" href="css文件">
- rel:表示“关系 (relationship) ”,属性值指链接方式与包含它的文档之间的关系,引入css文件固定值为stylesheet。
- href:属性需要引用某文件系统中的一个文件。
举例
创建styles.css文件
1
2
3
4
5h1 {
color: blue;
background-color: yellow;
border: 1px solid black;
}link标签引入文件
1
2
3
4
5
6
7
8
9
10<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>效果同上
为了CSS文件的管理,在项目中创建一个
css文件夹
,专门保存样式文件,并调整指定的路径以匹配1
2<link rel="stylesheet" href="../css/styles.css">
<!--..代表上一级 相对路径-->
优先级
规则层叠于一个样式表中,其中数字 4 拥有最高的优先权:
- 浏览器缺省设置
- 外部样式表
- 内部样式表(位于 标签内部)
- 内联样式(在 HTML 元素内部)
选择器
介绍选择器
为了样式化某些元素,我们会通过选择器来选中HTML文档中的这些元素,每个CSS规则都以一个选择器或一组选择器为开始,去告诉浏览器这些规则应该应用到哪些元素上。
选择器的分类:
分类 | 名称 | 符号 | 作用 | 示例 |
---|---|---|---|---|
基本选择器 | 元素选择器 | 标签名 | 基于标签名匹配元素 | div{ } |
类选择器 | . |
基于class属性值匹配元素 | .center{ } | |
ID选择器 | # |
基于id属性值匹配元素 | #username{ } | |
通用选择器 | * |
匹配文档中的所有内容 | *{ } | |
属性选择器 | 属性选择器 | [] |
基于某属性匹配元素 | [type]{ } |
伪类选择器 | 伪类选择器 | : |
用于向某些选择器添加特殊的效果 | a:hover{ } |
组合选择器 | 分组选择器 | , | 使用 , 号结合两个选择器,匹配两个选择器的元素 | span,p{} |
后代选择器 | 空格 | 使用空格符号结合两个选择器,基于 第一个选择器,匹配第二个选择器的所有后代元素 |
.top li{ } |
基本选择器
页面元素:
1
2
3
4
5
6
7
8
9<body>
<div>div1</div>
<div class="cls">div2</div>
<div class="cls">div3</div>
<div id="d1">div4</div>
<div id="d2">div5</div>
</body>元素选择器
1
2
3
4/*选择所有div标签,字体为蓝色*/
div{
color: red;
}类选择器
1
2
3
4/*选择class为cls的,字体为蓝色*/
.cls{
color: blue;
}ID选择器
1
2
3
4
5
6
7
8/*id选择器*/
#d1{
color: green;/*id为d1的字体变成绿色*/
}
#d2{
color: pink;/*id为d2的字体变成粉色*/
}/通用选择器
1
2
3
4/*所有标签 */
*{
background-color: aqua;
}
属性选择器
页面:
1
2
3
4
5<body>
用户名:<input type="text"/> <br/>
密码:<input type="password"/> <br>
邮箱:<input type="email"/> <br>
</body>选择器:
1
2
3
4
5
6
7
8/*输入框中输入的字符是红色*/
[type] {
color: red;
}
/*输入框中输入的字符是蓝色*/
[type=password] {
color: blue;
}
伪类选择器
页面元素
1
2
3<body>
<a href="https://www.baidu.com" target="_blank">百度一下</a>
</body>伪类选择器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/*未访问的状态*/
a:link{
color: black;
}
/*已访问的状态*/
a:visited{
color: blue;
}
/*鼠标悬浮的状态*/
a:hover{
color: red;
}
/*已选中的状态*/
a:active{
color: yellow;
}注意:伪类顺序 link ,visited,hover,active,否则有可能失效。
组合选择器
页面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<body>
<span>span</span> <br/>
<p>段落</p>
<div class="top">
<ol>
<li>aa</li>
<li>bb</li>
</ol>
</div>
<div class="center">
<ol>
<li>cc</li>
<li>dd</li>
</ol>
</div>
</body>分组选择器
1
2
3
4/*span p两个标签下的字体为蓝色*/
span,p{
color: blue;
}后代选择器
1
2
3
4/*class为top下的所有li标签字体颜色为红色*/
.top li{
color: red;
}
优先级
选择器优先级
- ID选择器 > 类选择器 > 标签选择器 > 通用选择器
- 如果优先级相同,那么就满足就近原则
边框样式
单个边框
单个边框
border:边框
border-top: 上边框
border-left: 左边框
border-bottom: 底边框
border-right: 右边框无边框,当border值为none时,可以让边框不显示
1
2
3
4
5div {
width: 200px;
height: 200px;
border: none;
}圆角
通过使用[
border-radius
]属性设置盒子的圆角,虽然能分别设置四个角,但是通常我们使用一个值,来设置整体效果
1 |
|
1 |
|
边框轮廓
轮廓outline:是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用
- 属性值:double:双实线 dotted:圆点 dashed:虚线 none:无
1 |
|
盒子模型
模型介绍
盒子模型是通过设置元素框与元素内容和外部元素的边距,而进行布局的方式。
- element : 元素。
- padding : 内边距,也有资料将其翻译为填充。
- border : 边框。
- margin : 外边距,也有资料将其翻译为空白或空白边。
边距
内边距、边框和外边距都是可选的,默认值是零。在 CSS 中,width 和 height 指的是内容区域的宽度和高度。
外边距
单独设置边框的外边距,设置上、右、下、左方向:1
2
3
4margin-top
margin-right
margin-bottom
margin-leftmargin: auto /*浏览器自动计算外边距,具有居中效果。*/
1
2
3
4
5
6
* 一个值
```css
/* 所有 4 个外边距都是 10px */
margin:10px;两个值
1
2margin:10px 5px;/* 上外边距和下外边距是 10px*/
margin:10px auto;/*右外边距和左外边距是 5px */三个值
1
2/* 上外边距是 10px,右外边距和左外边距是 5px,下外边距是 15px*/
margin:10px 5px 15px;四个值
1
2
3/*上外边距是 10px,右外边距是 5px,下外边距是 15px,左外边距是 20px*/
/*上右下外*/
margin:10px 5px 15px 20px;
内边距
与外边距类似,单独设置边框的内边距,设置上、右、下、左方向:1
2
3
4padding-top
padding-right
padding-bottom
padding-left
布局
基本布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<style>
div{
border: 2px solid blue;
}
.big{
width: 200px;
height: 200px;
}
.small{
width: 100px;
height: 100px;
margin: 30px;/* 外边距 */
}
</style>
<div class="big">
<div class="small">
</div>
</div增加内边距会增加元素框的总尺寸
1
2
3
4
5
6
7
8
9
10
11
12
13
14<style>
div{
border: 2px solid blue;
}
.big{
width: 200px;
height: 200px;
padding: 30px;/*内边距 */
}
.small{
width: 100px;
height: 100px;
}
</style>
文本样式
基本属性
属性名 | 作用 | 属性取值 |
---|---|---|
width | 宽度 | |
height | 高度 | |
color | 颜色 | |
font-family | 字体样式 | 宋体、楷体 |
font-size | 字体大小 | px : 像素,文本高度像素绝对数值。 em : 1em等于当前元素的父元素设置的字体大小,是相对数值 |
text-decoration | 下划线 | underline : 下划线 overline : 上划线 line-through : 删除线 none : 不要线条 |
text-align | 文本水平对齐 | lef : 左对齐文本 right : 右对齐文本 center : 使文本居中 justify : 使文本散布,改变单词间的间距,使文本所有行具有相同宽度。 |
line-height | 行高,行间距 | |
vertical-align | 文本垂直对齐 | top:居上 bottom:居下 middle:居中 或者百分比 |
display | 元素如何显示 | 可以设置块级和行内元素的切换,也可以设置元素隐藏 inline:内联元素(无换行、无长宽) block:块级元素(有换行) inline-block:内联元素(有长宽) none:隐藏元素 |
1 |
|
1 |
|
文本显示
元素显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/* 把列表项显示为内联元素,无长宽*/
li {
display:inline;
}
/* 把span元素作为块元素,有换行*/
span {
display:block;
}
/* 行内块元素,结合的行内和块级的优点,既可以行内显示,又可以设置长宽,*/
li {
display:inline-block;
}
/*所有div在一行显示*/
div{
display: inline-block;
width: 100px;
}元素隐藏
当设置为none时,可以隐藏元素。
CSS案例
1 |
|
1 |
|
HTTP
相关概念
HTTP:Hyper Text Transfer Protocol,意为超文本传输协议,是建立在 TCP/IP 协议基础上,指的是服务器和客户端之间交互必须遵循的一问一答的规则,形容这个规则:问答机制、握手机制
HTTP 协议是一个无状态的面向连接的协议,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。所以打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系
注意:无状态并不是代表 HTTP 就是 UDP,面向连接也不是代表 HTTP 就是TCP
HTTP 作用:用于定义 WEB 浏览器与 WEB 服务器之间交换数据的过程和数据本身的内容
浏览器和服务器交互过程:浏览器请求,服务请求响应
- 请求(请求行、请求头、请求体)
- 响应(响应行、响应头、响应体)
URL 和 URI
URL:统一资源定位符
- 格式:http://127.0.0.1:8080/request/servletDemo01
- 详解:http:协议;127.0.0.1:域名;8080:端口;request/servletDemo01:请求资源路径
URI:统一资源标志符
- 格式:/request/servletDemo01
区别:
URL - HOST = URI
,URI 是抽象的定义,URL 用地址定位,URI 用名称定位。只要能唯一标识资源的是 URI,在 URI 的基础上给出其资源的访问方式的是 URL
从浏览器地址栏输入 URL 到请求返回发生了什么?
进行 URL 解析,进行编码
DNS 解析,顺序是先查 hosts 文件是否有记录,有的话就会把相对应映射的 IP 返回,然后去本地 DNS 缓存中寻找,然后依次向本地域名服务器、根域名服务器、顶级域名服务器、权限域名服务器发起查询请求,最终返回 IP 地址给本地域名服务器
本地域名服务器将得到的 IP 地址返回给操作系统,同时将 IP 地址缓存起来;操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来
查找到 IP 之后,进行 TCP 协议的三次握手建立连接
发出 HTTP 请求,取文件指令
服务器处理请求,返回响应
释放 TCP 连接
浏览器解析渲染页面
推荐阅读:https://xiaolincoding.com/network/
版本区别
版本介绍:
- HTTP/0.9 仅支持 GET 请求,不支持请求头
- HTTP/1.0 默认短连接(一次请求建议一次 TCP 连接,请求完就断开),支持 GET、POST、 HEAD 请求
- HTTP/1.1 默认长连接(一次 TCP 连接可以多次请求);支持 PUT、DELETE、PATCH 等六种请求;增加 HOST 头,支持虚拟主机;支持断点续传功能
- HTTP/2.0 多路复用,降低开销(一次 TCP 连接可以处理多个请求);服务器主动推送(相关资源一个请求全部推送);解析基于二进制,解析错误少,更高效(HTTP/1.X 解析基于文本);报头压缩,降低开销
- HTTP/3.0 QUIC (Quick UDP Internet Connections),快速 UDP 互联网连接,基于 UDP 协议
HTTP 1.0 和 HTTP 1.1 的主要区别:
长短连接:
在HTTP/1.0中,默认使用的是短连接,每次请求都要重新建立一次连接,比如获取 HTML 和 CSS 文件,需要两次请求。HTTP 基于 TCP/IP 协议的,每一次建立或者断开连接都需要三次握手四次挥手,开销会比较大
HTTP 1.1起,默认使用长连接 ,默认开启
Connection: keep-alive
,Keep-Alive 有一个保持时间,不会永久保持连接。持续连接有非流水线方式和流水线方式 ,流水线方式是客户端在收到 HTTP 的响应报文之前就能接着发送新的请求报文,非流水线方式是客户端在收到前一个响应后才能发送下一个请求HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接
错误状态响应码:在 HTTP1.1 中新增了 24 个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突,410(Gone)表示服务器上的某个资源被永久性的删除
缓存处理:在 HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略,例如 Entity tag,If-Unmodified-Since,If-Match,If-None-Match等
带宽优化及网络连接的使用:HTTP1.0 存在一些浪费带宽的现象,例如客户端只需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1 则在请求头引入了 range 头域,允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接
HOST 头处理:在 HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此请求消息中的 URL 并没有传递主机名。HTTP1.1 时代虚拟主机技术发展迅速,在一台物理服务器上可以存在多个虚拟主机,并且共享一个 IP 地址,故 HTTP1.1 增加了 HOST 信息
HTTP 1.1 和 HTTP 2.0 的主要区别:
- 新的二进制格式:HTTP1.1 基于文本格式传输数据,HTTP2.0 采用二进制格式传输数据,解析更高效
- 多路复用:在一个连接里,允许同时发送多个请求或响应,并且这些请求或响应能够并行的传输而不被阻塞,避免 HTTP1.1 出现的队头堵塞问题
- 头部压缩,HTTP1.1 的 header 带有大量信息,而且每次都要重复发送;HTTP2.0 把 header 从数据中分离,并封装成头帧和数据帧,使用特定算法压缩头帧。并且 HTTP2.0 在客户端和服务器端记录了之前发送的键值对,对于相同的数据不会重复发送。比如请求 A 发送了所有的头信息字段,请求 B 则只需要发送差异数据,这样可以减少冗余数据,降低开销
- 服务端推送:HTTP2.0 允许服务器向客户端推送资源,无需客户端发送请求到服务器获取
安全请求
HTTP 和 HTTPS 的区别:
- 端口 :HTTP 默认使用端口 80,HTTPS 默认使用端口 443
- 安全性:HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份;HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上,所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密
- 资源消耗:HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源
对称加密和非对称加密
对称加密:加密和解密使用同一个秘钥,把密钥转发给需要发送数据的客户机,中途会被拦截(类似于把带锁的箱子和钥匙给别人,对方打开箱子放入数据,上锁后发送),私钥用来解密数据,典型的对称加密算法有 DES、AES 等
- 优点:运算速度快
- 缺点:无法安全的将密钥传输给通信方
非对称加密:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥,公钥公开给任何人(类似于把锁和箱子给别人,对方打开箱子放入数据,上锁后发送),典型的非对称加密算法有 RSA、DSA 等
- 公钥加密,私钥解密:为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容
- 私钥加密,公钥解密:为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的
- 可以更安全地将公开密钥传输给通信发送方,但是运算速度慢
使用对称加密和非对称加密的方式传送数据
- 使用非对称密钥加密方式,传输对称密钥加密方式所需要的 Secret Key,从而保证安全性
- 获取到 Secret Key 后,再使用对称密钥加密方式进行通信,从而保证效率
思想:锁上加锁
名词解释:
哈希算法:通过哈希函数计算出内容的哈希值,传输到对端后会重新计算内容的哈希,进行哈希比对来校验内容的完整性
数字签名:附加在报文上的特殊加密校验码,可以防止报文被篡改。一般是通过私钥对内容的哈希值进行加密,公钥正常解密并对比哈希值后,可以确保该内容就是对端发出的,防止出现中间人替换的问题
数字证书:由权威机构给某网站颁发的一种认可凭证
HTTPS 工作流程:服务器端的公钥和私钥,用来进行非对称加密,客户端生成的随机密钥,用来进行对称加密
- 客户端向服务器发起 HTTPS 请求,连接到服务器的 443 端口,请求携带了浏览器支持的加密算法和哈希算法,协商加密算法
- 服务器端会向数字证书认证机构注册公开密钥,认证机构用 CA 私钥对公开密钥做数字签名后绑定在数字证书(又叫公钥证书,内容有公钥,网站地址,证书颁发机构,失效日期等)
- 服务器将数字证书发送给客户端,私钥由服务器持有
- 客户端收到服务器端的数字证书后通过 CA 公钥(事先置入浏览器或操作系统)对证书进行检查,验证其合法性。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,将该密钥称之为 client key(客户端密钥、会话密钥)。用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文,HTTPS 中的第一次 HTTP 请求结束
- 客户端会发起 HTTPS 中的第二个 HTTP 请求,将加密之后的客户端密钥发送给服务器
- 服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文
- 服务器将加密后的密文发送给客户端
- 客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据,这样 HTTPS 中的第二个 HTTP 请求结束,整个 HTTPS 传输完成
参考文章:https://www.cnblogs.com/linianhui/p/security-https-workflow.html
参考文章:https://www.jianshu.com/p/14cd2c9d2cd2
请求部分
请求行: 永远位于请求的第一行
请求头: 从第二行开始,到第一个空行结束
请求体: 从第一个空行后开始,到正文的结束(GET 没有)
请求方式
- POST
GET
1
2
3
4
5
6
7
8
9
10
11
12【请求行】
GET /myApp/success.html?username=zs&password=123456 HTTP/1.1
【请求头】
Accept: text/html, application/xhtml+xml, */*; X-HttpWatch-RID: 41723-10011
Referer: http://localhost:8080/myApp/login.html
Accept-Language: zh-Hans-CN,zh-Hans;q=0.5
User-Agent: Mozilla/5.0 (MSIE 9.0; qdesk 2.4.1266.203; Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive
Cookie: Idea-b77ddca6=4bc282fe-febf-4fd1-b6c9-72e9e0f381e8GET 和 POST 比较
作用:GET 用于获取资源,而 POST 用于传输实体主体
参数:GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中(GET 也有请求体,POST 也可以通过 URL 传输参数)。不能因为 POST 参数存储在实体主体中就认为它的安全性更高,因为照样可以通过一些抓包工具(Fiddler)查看
安全:安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。GET 方法是安全的,而 POST 不是,因为 POST 的目的是传送实体主体内容
- 安全的方法除了 GET 之外还有:HEAD、OPTIONS
- 不安全的方法除了 POST 之外还有 PUT、DELETE
幂等性:同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的,所有的安全方法也都是幂等的。在正确实现条件下,GET,HEAD,PUT 和 DELETE 等方法都是幂等的,POST 方法不是
可缓存:如果要对响应进行缓存,需要满足以下条件
- 请求报文的 HTTP 方法本身是可缓存的,包括 GET 和 HEAD,但是 PUT 和 DELETE 不可缓存,POST 在多数情况下不可缓存
- 响应报文的状态码是可缓存的,包括:200、203、204、206、300、301、404、405、410、414 and 501
- 响应报文的 Cache-Control 首部字段没有指定不进行缓存
PUT 和 POST 的区别
PUT 请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉(幂等),所以 PUT 用来修改资源
POST 请求:后一个请求不会把第一个请求覆盖掉(非幂等),所以 POST 用来创建资源
PATCH 方法 是新引入的,是对 PUT 方法的补充,用来对已知资源进行局部更新
请求行详解
1
2GET /myApp/success.html?username=zs&password=123456 HTTP/1.1
POST /myApp/success.html HTTP/1.1内容 说明 GET/POST 请求的方式。 /myApp/success.html 请求的资源。 HTTP/1.1 使用的协议,及协议的版本。 请求头详解
从第 2 行到空行处,都叫请求头,以键值对的形式存在,但存在一个 key 对应多个值的请求头
内容 说明 Accept 告知服务器,客户浏览器支持的 MIME 类型 User-Agent 浏览器相关信息 Accept-Charset 告诉服务器,客户浏览器支持哪种字符集 Accept-Encoding 告知服务器,客户浏览器支持的压缩编码格式,常用 gzip 压缩 Accept-Language 告知服务器,客户浏览器支持的语言,zh_CN 或 en_US 等 Host 初始 URL 中的主机和端口 Referer 告知服务器,当前请求的来源。只有当前请求有来源,才有这个消息头。
作用:1 投放广告 2 防盗链Content-Type 告知服务器,请求正文的 MIME 类型,文件传输的类型,
application/x-www-form-urlencodedContent-Length 告知服务器,请求正文的长度。 Connection 表示是否需要持久连接,一般是 Keep -Alive
(HTTP 1.1 默认进行持久连接 )If-Modified-Since 告知服务器,客户浏览器缓存文件的最后修改时间 Cookie 会话管理相关(非常的重要) 请求体详解
只有 POST 请求方式,才有请求的正文,GET 方式的正文是在地址栏中的
表单的输入域有 name 属性的才会被提交,不分 GET 和 POST 的请求方式
表单的 enctype 属性取值决定了请求正文的体现形式
enctype取值 请求正文体现形式 示例 application/x-www-form-urlencoded key=value&key=value username=test&password=1234 multipart/form-data 此时变成了多部分表单数据。多部分是靠分隔符分隔的。 —————————–7df23a16c0210
Content-Disposition: form-data; name=”username”
test
—————————–7df23a16c0210
Content-Disposition: form-data; name=”password”
1234
——————————-7df23a16c0210
响应部分
响应部分图:
响应行
HTTP/1.1:使用协议的版本
200:响应状态码
OK:状态码描述
响应状态码:
状态码 说明 200 一切都 OK,与服务器连接成功,发送请求成功 302/307 请求重定向(客户端行为,两次请求,地址栏发生改变) 304 请求资源未改变,使用缓存 400 客户端错误,请求错误,最常见的就是请求参数有问题 403 客户端错误,但 forbidden 权限不够,拒绝处理 404 客户端错误,请求资源未找到 500 服务器错误,服务器运行内部错误
转移:
- 301 redirect:301 代表永久性转移 (Permanently Moved)
- 302 redirect:302 代表暂时性转移 (Temporarily Moved )
响应头:以 key:vaue 存在,可能多个 value 情况
消息头 说明 Location 请求重定向的地址,常与 302,307 配合使用。 Server 服务器相关信息 Content-Type 告知客户浏览器,响应正文的MIME类型 Content-Length 告知客户浏览器,响应正文的长度 Content-Encoding 告知客户浏览器,响应正文使用的压缩编码格式,常用的 gzip 压缩 Content-Language 告知客户浏览器,响应正文的语言,zh_CN 或 en_US 等 Content-Disposition 告知客户浏览器,以下载的方式打开响应正文 Refresh 客户端的刷新频率,单位是秒 Last-Modified 服务器资源的最后修改时间 Set-Cookie 服务器端发送的 Cookie,会话管理相关 Expires:-1 服务器资源到客户浏览器后的缓存时间 Catch-Control: no-catch 不要缓存,//针对http协议1.1版本 Pragma:no-catch 不要缓存,//针对http协议1.0版本 响应体:页面展示内容, 类似网页的源码
1
2
3
4
5
6
7
8
9<html>
<head>
<link rel="stylesheet" href="css.css" type="text/css">
<script type="text/javascript" src="demo.js"></script>
</head>
<body>
<img src="1.jpg" />
</body>
</html>
Servlet
JavaEE
JavaEE规范
JavaEE
规范是 J2EE
规范的新名称,早期被称为 J2EE
规范,其全称是 Java 2 Platform Enterprise Edition
,它是由 SUN 公司领导、各厂家共同制定并得到广泛认可的工业标准(JCP
组织成员)。之所以改名为JavaEE
,目的还是让大家清楚 J2EE
只是 Java
企业应用。在 2004 年底中国软件技术大会 Ioc
微容器(也就是 Jdon
框架的实现原理)演讲中指出:我们需要一个跨 J2SE/WEB/EJB
的微容器,保护我们的业务核心组件,以延续它的生命力,而不是依赖 J2SE/J2EE
版本。此次 J2EE
改名为 Java EE
,实际也反映出业界这种共同心声
JavaEE
规范是很多 Java 开发技术的总称。这些技术规范都是沿用自 J2EE
的。一共包括了 13 个技术规范,例如:jsp/servlet
,jndi
,jaxp
,jdbc
,jni
,jaxb
,jmf
,jta
,jpa
,EJB
等。
其中,JCP
组织的全称是 Java Community Process,是一个开放的国际组织,主要由 Java 开发者以及被授权者组成,职能是发展和更新。成立于 1998 年。官网是:JCP
JavaEE
的版本是延续了 J2EE
的版本,但是没有继续采用其命名规则。J2EE
的版本从 1.0 开始到 1.4 结束,而 JavaEE
版本是从 JavaEE 5
版本开始,目前最新的的版本是 JavaEE 8
详情请参考:JavaEE8 规范概览
Web 概述
Web,在计算机领域指网络。像我们接触的 WWW
,它是由 3 个单词组成的,即:World Wide Web
,中文含义是万维网。而我们前面学的 HTML 的参考文档《W3School 全套教程》中的 W3C
就是万维网联盟,他们的出现都是为了让我们在网络的世界中获取资源,这些资源的存放之处,我们称之为网站。我们通过输入网站的地址(网址),就可以访问网站中提供的资源。在网上我们能访问到的内容全是资源(不区分局域网还是广域网),只不过不同类型的资源展示的效果不一样
资源分为静态资源和动态资源
静态资源指的是,网站中提供给人们展示的资源是一成不变的,也就是说不同人或者在不同时间,看到的内容都是一样的。例如:我们看到的新闻,网站的使用手册,网站功能说明文档等等。而作为开发者,我们编写的
html
、css
、js
图片,多媒体等等都可以称为静态资源动态资源它指的是,网站中提供给人们展示的资源是由程序产生的,在不同的时间或者用不同的人员由于身份的不同,所看到的内容是不一样的。例如:我们在CSDN上下载资料,只有登录成功后,且积分足够时才能下载。否则就不能下载,这就是访客身份和会员身份的区别。作为开发人员,我们编写的
JSP
,servlet
,php
,ASP
等都是动态资源。
关于广域网和局域网的划分
- 广域网指的就是万维网,也就是我们说的互联网。
- 局域网是指的是在一定范围之内可以访问的网络,出了这个范围,就不能再使用的网络。
系统结构
基础结构划分:C/S结构,B/S结构两类。
技术选型划分:Model1模型,Model2模型,MVC模型和三层架构+MVC模型。
部署方式划分:一体化架构,垂直拆分架构,分布式架构,流动计算架构,微服务架构。
C/S结构:客户端—服务器的方式。其中C代表Client,S代表服务器。C/S结构的系统设计图如下:
B/S结构是浏览器—服务器的方式。B代表Browser,S代表服务器。B/S结构的系统设计图如下:
两种结构的区别及优劣
区别:
- 第一:硬件环境不同,C/S通常是建立在专用的网络或小范围的网络环境上(即局域网),且必须要安装客户端。而B/S是建立在广域网上的,适应范围强,通常有操作系统和浏览器就行。
- 第二:C/S结构比B/S结构更安全,因为用户群相对固定,对信息的保护更强。
- 第三:B/S结构维护升级比较简单,而C/S结构维护升级相对困难。
优劣
- C/S:能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后再提交给服务器。对应的优点就是客户端响应速度快。
- B/S:总体拥有成本低、维护方便、 分布性强、开发简单,可以不用安装任何专门的软件就能实现在任何地方进行操作,客户端零维护,系统的扩展非常容易,只要有一台能上网的电脑就能使用。
我们的课程中涉及的系统结构都是是基于B/S结构
Tomcat
服务器
服务器的概念非常的广泛,它可以指代一台特殊的计算机(相比普通计算机运行更快、负载更高、价格更贵),也可以指代用于部署网站的应用。我们这里说的服务器,其实是web服务器,或者应用服务器。它本质就是一个软件,一个应用。作用就是发布我们的应用(工程),让用户可以通过浏览器访问我们的应用。
常见的应用服务器,请看下表:
服务器名称 | 说明 |
---|---|
weblogic | 实现了 JavaEE 规范,重量级服务器,又称为 JavaEE 容器 |
websphereAS | 实现了 JavaEE 规范,重量级服务器。 |
JBOSSAS | 实现了 JavaEE 规范,重量级服务器,免费 |
Tomcat | 实现了 jsp/servlet 规范,是一个轻量级服务器,开源免费 |
基本介绍
Windows安装
下载地址:http://tomcat.apache.org/
目录结构详解:
Linux安装
解压apache-tomcat-8.5.32.tar.gz。
防火墙设置
方式1:service iptables stop 关闭防火墙(不建议); 用到哪一个端口号就放行哪一个(80,8080,3306…)
方式2:放行8080 端口
- 修改配置文件
cd /etc/sysconfig
–>vi iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
- 重启加载防火墙或者重启防火墙
service iptables reload
或者service iptables restart
- 修改配置文件
启动停止
Tomcat服务器的启动文件在二进制文件目录bin中:startup.bat,startup.sh
Tomcat服务器的停止文件也在二进制文件目录bin中:shutdown.bat,shutdown.sh (推荐直接关闭控制台)
其中.bat
文件是针对windows系统的运行程序,.sh
文件是针对linux系统的运行程序。
常见问题
启动一闪而过
没有配置环境变量,配置上 JAVA_HOME 环境变量。
Tomcat 启动后控制台输出乱码
打开
/conf/logging.properties
,设置 gbkjava.util.logging.ConsoleHandler.encoding = gbk
Address already in use : JVM_Bind:端口被占用,找到占用该端口的应用
进程不重要:使用cmd命令:netstat -a -o 查看 pid 在任务管理器中结束占用端口的进程
进程很重要:修改自己的端口号。修改的是 Tomcat 目录下
\conf\server.xml
中的配置。
IDEA集成
Run -> Edit Configurations -> Templates -> Tomcat Server -> Local
发布应用
虚拟目录
在 server.xml
的 <Host>
元素中加一个 <Context path="" docBase=""/>
元素
path
:访问资源URI,URI名称可以随便起,但是必须在前面加上一个/docBase
:资源所在的磁盘物理地址
虚拟主机
在<Engine>
元素中添加一个<Host name="" appBase="" unparkWARs="" autoDeploy="" />
,其中:
name
:指定主机的名称appBase
:当前主机的应用发布目录unparkWARs
:启动时是否自动解压war包autoDeploy
:是否自动发布
1 |
|
IDEA部署
新建工程
发布工程
Run
IDEA发布
把资源移动到 Tomcat 工程下 web 目录中,两种访问方式
在 web.xml 中配置默认主页
1
2
3<welcome-file-list>
<welcome-file>/默认主页</welcome-file>
</welcome-file-list>
执行原理
整体架构
Tomcat 核心组件架构图如下所示:
组件介绍:
- GlobalNamingResources:实现 JNDI,指定一些资源的配置信息
- Server:Tomcat 是一个 Servlet 容器,一个 Tomcat 对应一个 Server,一个 Server 可以包含多个 Service
- Service:核心服务是 Catalina,用来对请求进行处理,一个 Service 包含多个 Connector 和一个 Container
- Connector:连接器,负责处理客户端请求,解析不同协议及 I/O 方式
- Executor:线程池
- Container:容易包含 Engine,Host,Context,Wrapper 等组件
- Engine:服务交给引擎处理请求,Container 容器中顶层的容器对象,一个 Engine 可以包含多个 Host 主机
- Host:Engine 容器的子容器,一个 Host 对应一个网络域名,一个 Host 包含多个 Context
- Context:Host 容器的子容器,表示一个 Web 应用
- Wrapper:Tomcat 中的最小容器单元,表示 Web 应用中的 Servlet
核心类库:
- Coyote:Tomcat 连接器的名称,封装了底层的网络通信,为 Catalina 容器提供了统一的接口,使容器与具体的协议以及 I/O 解耦
- EndPoint:Coyote 通信端点,即通信监听的接口,是 Socket 接收和发送处理器,是对传输层的抽象,用来实现 TCP/IP 协议
- Processor : Coyote 协议处理接口,用来实现 HTTP 协议,Processor 接收来自 EndPoint 的 Socket,读取字节流解析成 Tomcat 的 Request 和 Response 对象,并通过 Adapter 将其提交到容器处理,Processor 是对应用层协议的抽象
- CoyoteAdapter:适配器,连接器调用 CoyoteAdapter 的 sevice 方法,传入的是 TomcatRequest 对象,CoyoteAdapter 负责将TomcatRequest 转成 ServletRequest,再调用容器的 service 方法
参考文章:https://www.jianshu.com/p/7c9401b85704
参考文章:https://www.yuque.com/yinhuidong/yu877c/ktq82e
启动过程
Tomcat 的启动入口是 Bootstrap#main 函数,首先通过调用 bootstrap.init()
初始化相关组件:
initClassLoaders()
:初始化三个类加载器,commonLoader 的父类加载器是启动类加载器Thread.currentThread().setContextClassLoader(catalinaLoader)
:自定义类加载器加载 Catalina 类,打破双亲委派Object startupInstance = startupClass.getConstructor().newInstance()
:反射创建 Catalina 对象method.invoke(startupInstance, paramValues)
:反射调用方法,设置父类加载器是 sharedLoadercatalinaDaemon = startupInstance
:引用 Catalina 对象
daemon.load(args)
方法反射调用 Catalina 对象的 load 方法,对服务器的组件进行初始化,并绑定了 ServerSocket 的端口:
parseServerXml(true)
:解析 XML 配置文件getServer().init()
:服务器执行初始化,采用责任链的执行方式LifecycleBase.init()
:生命周期接口的初始化方法,开始链式调用StandardServer.initInternal()
:Server 的初始化,遍历所有的 Service 进行初始化StandardService.initInternal()
:Service 的初始化,对 Engine、Executor、listener、Connector 进行初始化StandardEngine.initInternal()
:Engine 的初始化getRealm()
:创建一个 Realm 对象ContainerBase.initInternal()
:容器的初始化,设置处理容器内组件的启动和停止事件的线程池
Connector.initInternal()
:Connector 的初始化1
2
3public Connector() {
this("HTTP/1.1"); //默认无参构造方法,会创建出 Http11NioProtocol 的协议处理器
}adapter = new CoyoteAdapter(this)
:实例化 CoyoteAdapter 对象protocolHandler.setAdapter(adapter)
:设置到 ProtocolHandler 协议处理器中ProtocolHandler.init()
:协议处理器的初始化,底层调用AbstractProtocol#init
方法endpoint.init()
:端口的初始化,底层调用AbstractEndpoint#init
方法NioEndpoint.bind()
:绑定方法initServerSocket()
:初始化 ServerSocket,以 NIO 的方式监听端口serverSock = ServerSocketChannel.open()
:NIO 的方式打开通道serverSock.bind(addr, getAcceptCount())
:通道绑定连接端口serverSock.configureBlocking(true)
:切换为阻塞模式(没懂,为什么阻塞)
initialiseSsl()
:初始化 SSL 连接selectorPool.open(getName())
:打开选择器,类似 NIO 的多路复用器
初始化完所有的组件,调用 daemon.start()
进行组件的启动,底层反射调用 Catalina 对象的 start 方法:
getServer().start()
:启动组件,也是责任链的模式LifecycleBase.start()
:生命周期接口的初始化方法,开始链式调用StandardServer.startInternal()
:Server 服务的启动globalNamingResources.start()
:启动 JNDI 服务for (Service service : services)
:遍历所有的 Service 进行启动
StandardService.startInternal()
:Service 的启动,对所有 Executor、listener、Connector 进行启StandardEngine.startInternal()
:启动引擎,部署项目ContainerBase.startInternal()
:容器的启动- 启动集群、Realm 组件,并且创建子容器,提交给线程池
((Lifecycle) pipeline).start()
:遍历所有的管道进行启动Valve current = first
:获取第一个阀门((Lifecycle) current).start()
:启动阀门,底层ValveBase#startInternal
中设置启动的状态current = current.getNext()
:获取下一个阀门
Connector.startInternal()
:Connector 的初始化protocolHandler.start()
:协议处理器的启动endpoint.start()
:端点启动NioEndpoint.startInternal()
:启动 NIO 的端点createExecutor()
:创建 Worker 线程组,10 个线程,用来进行任务处理initializeConnectionLatch()
:用来进行连接限流,最大 8*1024 条连接poller = new Poller()
:创建 Poller 对象,开启了一个多路复用器 SelectorThread pollerThread = new Thread(poller, getName() + "-ClientPoller")
:创建并启动 Poller 线程,Poller 实现了 Runnable 接口,是一个任务对象,线程 start 后进入 Poller#run 方法pollerThread.setDaemon(true)
:设置为守护线程startAcceptorThread()
:启动接收者线程acceptor = new Acceptor<>(this)
:创建 Acceptor 对象Thread t = new Thread(acceptor, threadName)
:创建并启动 Acceptor 接受者线程
处理过程
- Acceptor 监听客户端套接字,每 50ms 调用一次 **
serverSocket.accept
**,获取 Socket 后把封装成 NioSocketWrapper(是 SocketWrapperBase 的子类),并设置为非阻塞模式,把 NioSocketWrapper 封装成 PollerEvent 放入同步队列中 - Poller 循环判断同步队列中是否有就绪的事件,如果有则通过
selector.selectedKeys()
获取就绪事件,获取 SocketChannel 中携带的 attachment(NioSocketWrapper),在 processKey 方法中根据事件类型进行 processSocket,将 Wrapper 对象封装成 SocketProcessor 对象,该对象是一个任务对象,提交到 Worker 线程池进行执行 SocketProcessorBase.run()
加锁调用SocketProcessor#doRun
,保证线程安全,从协议处理器 ProtocolHandler 中获取 AbstractProtocol,然后创建 Http11Processor 对象处理请求Http11Processor#service
中调用CoyoteAdapter#service
,把生成的 Tomcat 下的 Request 和 Response 对象通过方法 postParseRequest 匹配到对应的 Servlet 的请求响应,将请求传递到对应的 Engine 容器中调用 Pipeline,管道中包含若干个 Valve,执行完所有的 Valve 最后执行 StandardEngineValve,继续调用 Host 容器的 Pipeline,执行 Host 的 Valve,再传递给 Context 的 Pipeline,最后传递到 Wrapper 容器StandardWrapperValve#invoke
中创建了 Servlet 对象并执行初始化,并为当前请求准备一个 FilterChain 过滤器链执行 doFilter 方法,ApplicationFilterChain#doFilter
是一个责任链的驱动方法,通过调用 internalDoFilter 来获取过滤器链的下一个过滤器执行 doFilter,执行完所有的过滤器后执行servlet.service
的方法- 最后调用 HttpServlet#service(),根据请求的方法来调用 doGet、doPost 等,执行到自定义的业务方法
Servlet
Socket
Socket 是使用 TCP/IP 或者 UDP 协议在服务器与客户端之间进行传输的技术,是网络编程的基础
- Servlet 是使用 HTTP 协议在服务器与客户端之间通信的技术,是 Socket 的一种应用
- HTTP 协议:是在 TCP/IP 协议之上进一步封装的一层协议,关注数据传输的格式是否规范,底层的数据传输还是运用了 Socket 和 TCP/IP
Tomcat 和 Servlet 的关系:Servlet 的运行环境叫做 Web 容器或 Servlet 服务器,Tomcat 是 Web 应用服务器,是一个 Servlet/JSP 容器。Tomcat 作为 Servlet 容器,负责处理客户请求,把请求传送给 Servlet,并将 Servlet 的响应传送回给客户。而 Servlet 是一种运行在支持 Java 语言的服务器上的组件,Servlet 用来扩展 Java Web 服务器功能,提供非常安全的、可移植的、易于使用的 CGI 替代品
基本介绍
Servlet类
Servlet是SUN公司提供的一套规范,名称就叫Servlet规范,它也是JavaEE规范之一。通过API来使用Servlet。
Servlet是一个运行在web服务端的java小程序,用于接收和响应客户端的请求。一个服务器包含多个Servlet
通过实现Servlet接口,继承GenericServlet或者HttpServlet,实现Servlet功能
每次请求都会执行service方法,在service方法中还有参数ServletRequest和ServletResponse
支持配置相关功能
执行流程
创建 Web 工程 → 编写普通类继承 Servlet 相关类 → 重写方法
Servlet执行过程分析:
通过浏览器发送请求,请求首先到达Tomcat服务器,由服务器解析请求URL,然后在部署的应用列表中找到应用。然后找到web.xml配置文件,在web.xml中找到FirstServlet的配置(
实现方式
实现 Servlet 功能时,可以选择以下三种方式:
第一种:实现 Servlet 接口,接口中的方法必须全部实现。
使用此种方式,表示接口中的所有方法在需求方面都有重写的必要。此种方式支持最大程度的自定义。第二种:继承 GenericServlet,service 方法必须重写,其他方可根据需求,选择性重写。
使用此种方式,表示只在接收和响应客户端请求这方面有重写的需求,而其他方法可根据实际需求选择性重写,使我们的开发Servlet变得简单。但是,此种方式是和 HTTP 协议无关的。第三种:继承 HttpServlet,它是 javax.servlet.http 包下的一个抽象类,是 GenericServlet 的子类。选择继承 HttpServlet 时,需要重写 doGet 和 doPost 方法,来接收 get 方式和 post 方式的请求,不要覆盖 service 方法。使用此种方式,表示我们的请求和响应需要和 HTTP 协议相关,我们是通过 HTTP 协议来访问。每次请求和响应都符合 HTTP 协议的规范。请求的方式就是 HTTP 协议所支持的方式(GET POST PUT DELETE TRACE OPTIONS HEAD )。
相关问题
异步处理
Servlet 3.0 中的异步处理指的是允许Servlet重新发起一条新线程去调用 耗时业务方法,这样就可以避免等待
生命周期
servlet从创建到销毁的过程:
出生:(初始化)请求第一次到达 Servlet 时,创建对象,并且初始化成功。Only one time
活着:(服务)服务器提供服务的整个过程中,该对象一直存在,每次只是执行 service 方法
死亡:(销毁)当服务停止时,或者服务器宕机时,对象删除,
serrvlet生命周期方法:init(ServletConfig config)
→ service(ServletRequest req, ServletResponse res)
→ destroy()
默认情况下, 有了第一次请求, 会调用 init() 方法进行初始化【调用一次】,任何一次请求,都会调用 service() 方法处理这个请求,服务器正常关闭或者项目从服务器移除, 调用 destory() 方法进行销毁【调用一次】
扩展:servlet 是单例多线程的,尽量不要在 servlet 里面使用全局(成员)变量,可能会导致线程不安全
- 单例:Servlet 对象只会创建一次,销毁一次,Servlet 对象只有一个实例。
- 多线程:服务器会针对每次请求, 开启一个线程调用 service() 方法处理这个请求
线程安全
Servlet运用了单例模式,整个应用中只有一个实例对象,所以需要分析这个唯一的实例中的类成员是否线程安全
1 |
|
启动两个浏览器,输入不同的参数(http://localhost:8080/ServletDemo/username=aaa 或者bbb),访问之后发现输出的结果都是一样,所以出现线程安全问题。
在Servlet中定义了类成员之后,多个浏览器都会共享类成员的数据,其中任何一个线程修改了数据,都会影响其他线程。因此,我们可以认为Servlet它不是线程安全的。因为Servlet是单例,单例对象的类成员只会随类实例化时初始化一次,之后的操作都是改变,而不会重新初始化。
解决办法:如果类成员是共用的,只在初始化时赋值,其余时间都是获取。或者加锁synchronized
映射方式
Servlet支持三种映射方式,三种映射方式的优先级为:第一种>第二种>第三种。
具体名称方式
这种方式,只有和映射配置一模一样时,Servlet才会接收和响应来自客户端的请求。
访问URL:http://localhost:8080/servlet/servletDemo1
2
3
4
5
6
7
8<servlet>
<servlet-name>servletDemo</servlet-name>
<servlet-class>com.itheima.servlet.ServletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo</servlet-name>
<url-pattern>/servletDemo</url-pattern>
</servlet-mapping>/开头+通配符的方式
这种方式,只要符合目录结构即可,不用考虑结尾是什么
访问URL:http://localhost:8080/servlet/ + 任何字符1
2
3
4
5
6
7
8<servlet>
<servlet-name>servletDemo</servlet-name>
<servlet-class>com.itheima.servlet.ServletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>通配符+固定格式结尾
这种方式,只要符合固定结尾格式即可,其前面的访问URI无须关心(注意协议,主机和端口必须正确)
访问URL:http://localhost:8080/任何字符任何目录 + .do (http://localhost:8080/seazean/i.do)1
2
3
4
5
6
7
8<servlet>
<servlet-name>servletDemo05</servlet-name>
<servlet-class>com.itheima.servlet.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo05</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
多路径映射
一个Servlet的多种路径配置的支持。给一个Servlet配置多个访问映射,从而根据不同请求的URL实现不同的功能
1 |
|
1 |
|
这样就可以根据不同的网页显示不同的数据。
启动时创建
- 第一种:应用加载时创建Servlet,它的优势是在服务器启动时,就把需要的对象都创建完成了,从而在使用的时候减少了创建对象的时间,提高了首次执行的效率。它的弊端是在应用加载时就创建了Servlet对象,因此,导致内存中充斥着大量用不上的Servlet对象,造成了内存的浪费。
- 第二种:请求第一次访问是创建Servlet,它的优势就是减少了对服务器内存的浪费,因为一直没有被访问过的Servlet对象都没有创建,因此也提高了服务器的启动时间。而它的弊端就是要在应用加载时就做的初始化操作,它都没法完成,从而要考虑其他技术实现。
在web.xml中是支持对Servlet的创建时机进行配置的,配置的方式如下:
1 |
|
默认Servlet
默认 Servlet 是由服务器提供的一个 Servlet,它配置在 Tomcat 的 conf 目录下的 web.xml 中。
它的映射路径是<url-pattern>/<url-pattern>
,我们在发送请求时,首先会在我们应用中的 web.xml 中查找映射配置。但是当找不到对应的 Servlet 路径时,就去找默认的 Servlet,由默认 Servlet 处理。
ServletConfig
ServletConfig 是 Servlet 的配置参数对象。在 Servlet 规范中,允许为每个 Servlet 都提供一些初始化配置,每个 Servlet 都有自己的ServletConfig,作用是在 Servlet 初始化期间,把一些配置信息传递给 Servlet
生命周期:在初始化阶段读取了 web.xml 中为 Servlet 准备的初始化配置,并把配置信息传递给 Servlet,所以生命周期与 Servlet 相同。如果 Servlet 配置了 <load-on-startup>1</load-on-startup>
,ServletConfig 也会在应用加载时创建。
获取 ServletConfig:在 init 方法中为 ServletConfig 赋值
常用API:
String getInitParameter(String name)
:根据初始化参数的名称获取参数的值,根据,获取 Enumeration<String> getInitParameterNames()
: 获取所有初始化参数名称的枚举(遍历方式看例子)ServletContext getServletContext()
: 获取ServletContext对象String getServletName()
: 获取Servlet名称
代码实现:
web.xml 配置:
初始化参数使用<servlet>
标签中的<init-param>
标签来配置,并且每个 Servlet 都支持有多个初始化参数,并且初始化参数都是以键值对的形式存在的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<!--配置ServletDemo8-->
<servlet>
<servlet-name>servletDemo8</servlet-name>
<servlet-class>com.itheima.web.servlet.ServletDemo8</servlet-class>
<!--配置初始化参数-->
<init-param>
<!--用于获取初始化参数的key-->
<param-name>encoding</param-name>
<!--初始化参数的值-->
<param-value>UTF-8</param-value>
</init-param>
<!--每个初始化参数都需要用到init-param标签-->
<init-param>
<param-name>servletInfo</param-name>
<param-value>This is Demo8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo8</servlet-name>
<url-pattern>/servletDemo8</url-pattern>
</servlet-mapping>代码:
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//演示Servlet的初始化参数对象
public class ServletDemo8 extends HttpServlet {
//定义Servlet配置对象ServletConfig
private ServletConfig servletConfig;
//在初始化时为ServletConfig赋值
@Override
public void init(ServletConfig config) throws ServletException {
this.servletConfig = config;
}
/**
* doGet方法输出一句话
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.输出ServletConfig
System.out.println(servletConfig);
//2.获取Servlet的名称
String servletName= servletConfig.getServletName();
System.out.println(servletName);
//3.获取字符集编码
String encoding = servletConfig.getInitParameter("encoding");
System.out.println(encoding);
//4.获取所有初始化参数名称的枚举
Enumeration<String> names = servletConfig.getInitParameterNames();
//遍历names
while(names.hasMoreElements()){
//取出每个name
String name = names.nextElement();
//根据key获取value
String value = servletConfig.getInitParameter(name);
System.out.println("name:"+name+",value:"+value);
}
//5.获取ServletContext对象
ServletContext servletContext = servletConfig.getServletContext();
System.out.println(servletContext);
}
//调用doGet方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}效果:
ServletContext
ServletContext 对象是应用上下文对象。服务器为每一个应用都创建了一个 ServletContext 对象,ServletContext 属于整个应用,不局限于某个 Servlet,可以实现让应用中所有 Servlet 间的数据共享。
上下文代表了程序当下所运行的环境,联系整个应用的生命周期与资源调用,是程序可以访问到的所有资源的总和,资源可以是一个变量,也可以是一个对象的引用
生命周期:
- 出生:应用一加载,该对象就被创建出来。一个应用只有一个实例对象(Servlet 和 ServletContext 都是单例的)
- 活着:只要应用一直提供服务,该对象就一直存在。
- 死亡:应用被卸载(或者服务器停止),该对象消亡。
域对象:指的是对象有作用域,即有作用范围,可以实现数据共享,不同作用范围的域对象,共享数据的能力不一样。
Servlet 规范中,共有4个域对象,ServletContext 是其中一个,web 应用中最大的作用域,叫 application 域,可以实现整个应用间的数据共享功能。
数据共享:
获取ServletContext:
Java 项目继承 HttpServlet,HttpServlet 继承 GenericServlet,GenericServlet 中有一个方法可以直接使用
1
2
3public ServletContext getServletContext() {
return this.getServletConfig().getServletContext();
}ServletRequest 类方法:
1
ServletContext getServletContext()//获取ServletContext对象
常用API:
String getInitParameter(String name)
: 根据名称获取全局配置的参数String getContextPath
: 获取当前应用访问的虚拟目录String getRealPath(String path)
: 根据虚拟目录获取应用部署的磁盘绝对路径void setAttribute(String name, Object object)
: 向应用域对象中存储数据Object getAttribute(String name)
: 根据名称获取域对象中的数据,没有则返回nullvoid removeAttribute(String name)
: 根据名称移除应用域对象中的数据
代码实现:
web.xml配置:
配置的方式,需要在<web-app>
标签中使用<context-param>
来配置初始化参数,它的配置是针对整个应用的配置,被称为应用的初始化参数配置。1
2
3
4
5
6
7
8
9
10
11
12<!--配置应用初始化参数-->
<context-param>
<!--用于获取初始化参数的key-->
<param-name>servletContextInfo</param-name>
<!--初始化参数的值-->
<param-value>This is application scope</param-value>
</context-param>
<!--每个应用初始化参数都需要用到context-param标签-->
<context-param>
<param-name>globalEncoding</param-name>
<param-value>UTF-8</param-value>
</context-param>代码:
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
43public class ServletContextDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = getServletContext();
//获取全局配置的globalEncoding
String value = context.getInitParameter("globalEncoding");
System.out.println(value);//UTF-8
//获取应用的访问虚拟目录
String contextPath = context.getContextPath();
System.out.println(contextPath);//servlet
//根据虚拟目录获取应用部署的磁盘绝对路径
//获取b.txt文件的绝对路径 web目录下
String b = context.getRealPath("/b.txt");
System.out.println(b);
//获取c.txt文件的绝对路径 /WEB-INF目录下
String c = context.getRealPath("/WEB-INF/c.txt");
System.out.println(c);
//获取a.txt文件的绝对路径 //src目录下
String a = context.getRealPath("/WEB-INF/classes/a.txt");
System.out.println(a);
//向域对象中存储数据
context.setAttribute("username","zhangsan");
//移除域对象中username的数据
//context.removeAttribute("username");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
//E:\Database\Java\Project\JavaEE\out\artifacts\Servlet_war_exploded\b.txt
//E:\Database\Java\Project\JavaEE\out\artifacts\Servlet_war_exploded\WEB-INF\c.txt
//E:\Database\Java\Project\JavaEE\out\artifacts\Servlet_war_exploded\WEB-INF\classes\a.txt
注解开发
Servlet3.0 版本!不需要配置 web.xml
注解案例
1
2
3
4
5
6
7
8
9
10
11
12@WebServlet("/servletDemo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet Demo1 Annotation");
}
}WebServlet注解(@since Servlet 3.0 (Section 8.1.1))
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@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
//指定Servlet的名称。相当于xml配置中<servlet>标签下的<servlet-name>
String name() default "";
//用于映射Servlet访问的url映射,相当于xml配置时的<url-pattern>
String[] value() default {};
//相当于xml配置时的<url-pattern>
String[] urlPatterns() default {};
//用于配置Servlet的启动时机,相当于xml配置的<load-on-startup>
int loadOnStartup() default -1;
//用于配置Servlet的初始化参数,相当于xml配置的<init-param>
WebInitParam[] initParams() default {};
//用于配置Servlet是否支持异步,相当于xml配置的<async-supported>
boolean asyncSupported() default false;
//用于指定Servlet的小图标
String smallIcon() default "";
//用于指定Servlet的大图标
String largeIcon() default "";
//用于指定Servlet的描述信息
String description() default "";
//用于指定Servlet的显示名称
String displayName() default "";
}手动创建容器:(了解)
Request
请求响应
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
请求对象
请求:客户机希望从服务器端索取一些资源,向服务器发出询问
请求对象:在 JavaEE 工程中,用于发送请求的对象,常用的对象是 ServletRequest 和 HttpServletRequest ,它们的区是是否与 HTTP 协议有关
Request 作用:
- 操作请求三部分(行,头,体)
- 请求转发
- 作为域对象存数据
请求路径
方法 | 作用 |
---|---|
String getLocalAddr() | 获取本机(服务器)地址 |
String getLocalName() | 获取本机(服务器)名称 |
int getLocalPort() | 获取本机(服务器)端口 |
String getRemoteAddr() | 获取访问者IP |
String getRemoteHost | 获取访问者主机 |
int getRemotePort() | 获取访问者端口 |
String getMethod(); | 获得请求方式 |
String getRequestURI() | 获取统一资源标识符(/request/servletDemo01) |
String getRequestURL() | 获取统一资源定位符(http://localhost:8080/request/servletDemo01) |
String getQueryString() | 获取请求消息的数据 (GET方式 URL中带参字符串:username=aaa&password=123) |
String getContextPath() | 获取虚拟目录名称(/request) |
String getServletPath | 获取Servlet映射路径 ( |
String getRealPath(String path) | 根据虚拟目录获取应用部署的磁盘绝对路径 |
URL = URI + HOST
URL = HOST + ContextPath + ServletPath
获取请求头
方法 | 作用 |
---|---|
String getHeader(String name) | 获得指定请求头的值。 如果没有该请求头返回null,有多个值返回第一个 |
Enumeration |
获取指定请求头的多个值 |
Enumeration |
获取所有请求头名称的枚举 |
1 |
|
请求参数
请求参数
请求参数是正文部分标签内容,