尚硅谷javaweb笔记
1、基本概念
1.1、前言
web开发:
web,网页的意思,www.baidu.com·
静态web
html,css
提供给所有人看的数据始终不会发生变化!
动态web
淘宝,几乎是所有的网站;
提供给所有人看的数据始终会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同!
技术栈:Servlet/JSP,ASP,PHP
1.2、web应用程序
可以提供浏览器访问的程序;
a.html、b.html.….多个web资源,这些web资源可以被外界访问,对外界提供服务;
你们能访问到的任何一个页面或者资源,都存在于这个世界的某一个角落的计算机上。
URL
这个统一的web资源会被放在同一个文件夹下,web应用程序 > Tomcat:服务器
一个web应用由多部分组成(静态web,动态web)
html,css,js
jsp,servlet
Java程序
jar包
配置文件(Properties)
Web应用程序编写完毕后,若想提供给外界访问;需费一个服务器来统一管理
1.3、静态web
*.htm, *.html这些都是网员的后境、如果服务器上一直存在这些东西,我们就可以直接进行读取,需要网络;
静态web存在的缺点
Web页面无法动态更新,所有用户看到都是同一个页面
轮播图,点击特效:伪动态
JavaScript[实际开发中,它用的最多]
VBScript
它无法和数据库交互(数据无法持久化,用户无法交互)
1.4、动态web
页面会动态展示,“web页面的展示效果因人而异”
缺点:
加入服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布;
停机维护
优点:
Web页面可以动态更新,所有用户看到都不是同一个页面
它可以与数据库交互(数据持久化:注册,商品信息,用户信息………)
HTML
HTML中的基础标签
<html>
<head>
<title>这是我的第一个网页</title>
<meta charset="UTF-8">
</head>
<body>
HELLO WORLD!<br/>你好 HTML!
<p>这是第一个段落</p>
<img src="imgs/junjun.jpg"width="126" height="93" alt="这是美女图片"/>
<h1>标题一</h1>
美女颜值排行榜:
<ol type="A" start="3">
<li>筠筠</li>
<li>曦姐</li>
<li>芋圆</li>
<li>香菇</li>
<li>...</li>
</ol>
511人员名单:
<ul type="circle">
<li>小马</li>
<li>黑子</li>
<li>壮哥</li>
<li>宇</li>
</ul>
<u>你</u>是喜欢<b>芋圆</b>还是<i>珍珠</i>
水分子的化学式: H<sub>2</sub>O<br/>
2<sup>2</sup>
<span>君子报仇</span>十年不晚
<a href="http://www.baidu.com"target="_blank">百度一下</a>
<a href="http://taobao.com"target="_parent">淘宝</a>
<a href="https://www.douyin.com/?ug_source=microsoft_mz03"target="_top">抖音</a>
</body>
</html>
<!--
在HTML中:
head 标签:包含了文档的元数据(metadata),
如文档的标题(title)、字符集(charset)、链接到样式表和脚本等。
这些信息不会直接显示在页面内容中,但对于页面的展示和搜索引擎优化(SEO)非常重要。
body 标签:包含了网页的所有内容,如文本、图片、视频、游戏、可播放音频等。
这是用户在浏览器中看到的部分。
1)
html语言是解释型语言,浏览器是容错的
2)
html页面中由一对标签组成:<html></html>
<html>称之为开始标签
</html>称之为结束标签
3)
title 表示网页的标题
4)
可以在meta标签中设置编码方式
5)
<br/>表示换行.br标签是一个单标签,单标签: 开始标签和结束标签是同一个,斜杠放在单词的前面
p 表示段落标签
7)
img 标签图片标签
src属性表示图片文件的路径
width height表示图片的大小
alt表示图片的提示
8)
路径问题:
相对路径和绝对路径
9)
h1-h6: 标题标签
10)
列表标签:
--ol 有序
start 表示从几开始 type表示要显示的类型:A a i I 1(default默认)
--ul 无序列表
type disc(default),circle,square
11)u下划线 b粗体 i斜体
12)上标sup 下标sub
13)HTML中的实体: 小于号<大于等于≥版权©
14)span不换行的块标记
15)a 表示超链接
href 连接的地址
target:
_self 在本窗口打开
_blank 在一个新的窗口打开
_parent 在父类窗口打开
_top 在顶层窗口打开
-->
HTML中的table标签
<html>
<head>
<title>表格标签的学习</title>
<meta charset="UTF-8">
</head>
<body>
<table border="1" width="600" cellspacing="0" cellpadding="4">
<tr align="center">
<th>姓名</th>
<th>门派</th>
<th>成名绝技</th>
<th>内功值</th>
</tr>
<tr align="center">
<td>乔峰</td>
<td>丐帮</td>
<td>少林长拳</td>
<td>5000</td>
</tr>
<tr align="center">
<td>虚竹</td>
<td>灵鹫宫</td>
<td>北冥神功</td>
<td>15000</td>
</tr>
<tr align="center">
<td>扫地僧</td>
<td>少林寺</td>
<td>七十二绝技</td>
<td>未知</td>
</tr>
</table>
<hr/>
<table border="1" cellspacing="0" cellpadding="4" width="600">
<tr>
<th>名称</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
<tr align="center">
<td>苹果</td>
<td>5</td>
<td>20</td>
<td>100</td>
<td><img src="imgs/th.jpg"width="24" height="24"/></td>
</tr>
<tr align="center">
<td>荔枝</td>
<td>12</td>
<td>88</td>
<td>199</td>
<td><img src="imgs/th.jpg"width="24" height="24"/></td>
</tr>
<tr align="center">
<td>芒果</td>
<td>3.5</td>
<td>4</td>
<td>14</td>
<td><img src="imgs/th.jpg"width="24" height="24"/></td>
</tr>
</table>
</body>
</html>
<!--
16)表格 table
行 tr
列 td
列表头 th
17)table中有如下属性(虽然已经淘汰,理解即可)
-border: 表格边框的粗细
-width: 表格的宽度
-cellspacing :单元格间距
- cellspadding:单元格填充
tr中有一个属性: align->center ,left,right居中,左右
rowspan: 行合并
colspan: 列合并
-->
HTML表单标签
<html>
<head>
<title>登录界面</title>
<meta charset="UTF-8">
</head>
<body>
<form action="demo05.html" method="post">
昵称: <input type="text"name="nickname"value="请输入你的名字"/><br/>
密码: <input type="password"name="pwd"/><br/>
性别: <input type="radio"name="gender"value="male"checked/>男<br/>
<input type="radio"name="gender"value="female"checked/>女<br/>
爱好: <input type="checkbox"name="hobby"value="basketball"/>篮球
<input type="checkbox"name="hobby"value="football"checked/>足球
<input type="checkbox"name="hobby"value="earth"/>地球<br/>
星座: <select name="star">
<option value="1">白羊</option>
<option value="2"selected>巨蟹</option>
<option value="3">金牛</option>
<option value="4">狮子</option>
<option value="5">处女</option>
<option value="6">水瓶</option>
</select><br/>
备注: <textarea name="remark"rows="4"cols="50"></textarea><br/>
<input type="submit" value="注册"/>
<input type="reset" value="重置"/>
<input type="button" value="这是一个普通按钮"/>
</form>
</body>
</html>
<!--
18)
表单 form
19)input type="text"表示文本框 其中name属性一定要指定,否则该文本的数据不会发给服务器
input type="password"表示密码框
input type="radio"表示单选按钮 name属性需要保持一致才有互斥的效果
input type="checkbox"表示复选框 name属性建议保持一致,这样服务器获取值的时候获取的就是一个数组
select 表示下拉列表 每一个选项是option 其中value属性1是发送给服务器的值,selected表示的是默认
textarea 表示多行文本框 他的value值就是开始结束标签之间的内容
input type="submit"表示提交按钮
input type="reset"表示重置按钮
input type="button"表示普通按钮
-->
Node节点
Element元素节点
Text文本节点
CSS
css的语法
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
/*被style标签包围的范围是css环境,可以写css代码*/
/*标签样式表*/
p{
color:red;
}
/*类样式表*/
.f20{
font-size:20px;
}
/*ID样式*/
#p4{
background-color:pink;
font-size:24px;
font-weigth:bolder;
font-style:italic;
font-family:"华文云彩";
}
/*组合样式*/
div p{
color:blue;
}
div.f32{
font-size:32px;
font-family:"黑体";
}
</style>
</head>
<body>
<!--
<p><font color="red">这是段落一</font></p>
<p><font color="red">这是段落二</font></p>
-->
<p>这是段落一</p>
<p>这是段落二</p>
<p class="f20">这是段落3</p>
<p id="p4">这是段落四</p><!-- id属性在整个HTML文档中尽量保持唯一-->
<div>
<p><span>HELLO</span></p>
<span class="f32">World</span>
<p class="f32">!!!</p>
</div>
</body>
</html>
<!--
css基本的分类
标签样式表
类样式表
ID样式表
css从位置上的分类:嵌入式样式表,内部样式表,外部样式表
-->
css盒子模型
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
#div1{
width:400px;
height:400px;
background-color: red;
/*1.border 边框样式*/
border-width:1px;/*边框粗细*/
border-style:solid;/*边框样式:solid实线 dotted点线状*/
border-color:blue;/*边框颜色*/
}
#div2{
width:200px;
height:200px;
background-color: #0a94ff;
margin-top:100px;
margin-left:100px;
/*margin:100px 100px 50px 150px;一个值 四个方向统一:两个值:上下,左右;三个值上,左右,下;四个值上右下左*/
/*padding : 填充*/
padding-top:50px;
padding-left:50px;
}
#div3{
width:100px;
height:100px;
background-color: #0a8e6c;
margin-top:50px;
margin-left:50px;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">
<div id="div3"> </div>
</div>
</div>
</body>
</html>
<!--
CSS盒子模型:
1.border 边框
2.margin 间距
3.padding 填充
CSS布局
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
body{
margin:0;
padding:0;
}
#div1{
width:200px;
height:50px;
background-color: red;
/*绝对定位*/
position:absolute;
left:100px;
}
#div2 {
width: 200px;
height: 50px;
background-color: deeppink;
position:relative;
float:left;
}
#div3{
height: 50px;
background-color: aqua;
}
#div4{
width: 200px;
height: 50px;
background-color: olivedrab;
float:left;
}
#div5{
width: 200px;
height: 50px;
background-color: deeppink;
}
div{
position:relative;
}
</style>
</head>
<body>
<div id="div1"> </div>
<div id="div2"> </div>
<div id="div3">
<div id="div4"> </div>
<div id="div5"> </div>
</div>
</body>
</html>
<!--
position:absolute:--绝对定位 需要配合left top
relative:--相对定位 一般和float margin padding...一起使用
-->
CSS-水果库存界面静态实现
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/fruit.css">
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<table id="tbl_fruit">
<tr>
<th class="w20">名称</th>
<th class="w20">单价</th>
<th class="w20">数量</th>
<th class="w20">小计</th>
<th>操作</th>
</tr>
<tr>
<td>苹果</td>
<td>5</td>
<td>20</td>
<td>100</td>
<td><img src="imgs/th.jpg"class="delImg"></td>
</tr>
<tr>
<td>大香蕉</td>
<td>3</td>
<td>30</td>
<td>90</td>
<td><img src="imgs/th.jpg"class="delImg"></td>
</tr>
<tr>
<td>苹果</td>
<td>5</td>
<td>20</td>
<td>100</td>
<td><img src="imgs/th.jpg"class="delImg"></td>
</tr>
<tr>
<td>总计</td>
<td colspan="4">999</td>
</tr>
</table>
</div>
</div>
</body>
</html>
body{
margin:0;
padding:0;
background-color:#808080;
}
div{
position:relative;
float:left;
}
#div_container{
width:80%;
height:100%;
border:0px solid blue;
margin-left:10%;
float:left;
background-color:azure;
}
#tbl_fruit{
width:60%;
line-height:28px;
margin-top:120px;
margin-left:20%;
}
#div_fruit_list{
width:100%;
border:0px solid red;
}
#tbl_fruit, #tbl_fruit tr, #tbl_fruit td, #tbl_fruit th{
border: 1px solid gray;
border-collapse:collapse;
text-align:center;
font-size:16px;
font-family:"黑体";
font-weight:lighter;
color:ThreeDDarkShadow
}
.w20{
width:20%;
}
.delImg{
width:24px;
height:24px;
}
Javascript
JavaScript和Java在语法上存在多方面的区别,这些区别主要体现在语言类型、变量声明、数据类型、流程控制、面向对象特性以及运行环境等方面。以下是对这些区别的详细分析:
1. 语言类型
- Java:是一种静态类型、强类型语言。在编译时,Java会检查变量的类型,确保类型安全。
- JavaScript:是一种动态类型、弱类型语言。JavaScript在运行时确定变量的类型,允许同一个变量在不同时间持有不同类型的值。
2. 变量声明
- Java:变量声明时必须指定类型,如
int a = 5;
。 - JavaScript:变量声明时不需要指定类型,可以使用
var
、let
或const
关键字,如var a = 5;
。在ES6及以后的版本中,推荐使用let
和const
来声明变量,因为它们提供了块级作用域。
3. 数据类型
- Java:拥有基本数据类型(如int、float、double、char等)和引用数据类型(如类、接口、数组等)。
- JavaScript:数据类型较为简单,包括数字(Number)、字符串(String)、布尔值(Boolean)、空(Null)、未定义(Undefined)以及对象(Object,包括数组和函数等)。
4. 流程控制
- Java和JavaScript在流程控制方面(如if语句、循环语句等)的语法非常相似,都支持条件判断、循环遍历等。但JavaScript由于其动态性,可能在某些情况下表现出更灵活的行为。
5. 面向对象特性
- Java:是一种纯粹的面向对象编程语言,支持类、继承、封装和多态等面向对象特性。
- JavaScript:虽然也支持面向对象编程,但其基于原型的继承机制与Java的类继承机制有所不同。JavaScript中的函数可以作为对象使用,支持闭包等高级特性。
6. 运行环境
- Java:通常运行在Java虚拟机(JVM)上,具有跨平台性。Java程序被编译成字节码,然后由JVM解释执行。
- JavaScript:主要运行在浏览器中,作为网页的脚本语言。随着Node.js等技术的发展,JavaScript也可以在服务器端运行。
7. 其他语法区别
- 注释:Java和JavaScript都支持单行注释(//)和多行注释(/* ... */),但JavaScript还支持HTML注释(<!-- ... -->),尽管这主要用于HTML文档中。
- 字符串:在Java中,字符串是对象,而在JavaScript中,字符串是基本数据类型。但在JavaScript中,字符串也可以像对象一样被操作(如使用
.length
属性获取长度)。 - 数组:Java中的数组是静态的,一旦创建其长度就不可变;而JavaScript中的数组是动态的,可以随时添加或删除元素。
鼠标悬浮和离开
body{
margin:0;
padding:0;
background-color:#808080;
}
div{
position:relative;
float:left;
}
#div_container{
width:80%;
height:100%;
border:0px solid blue;
margin-left:10%;
float:left;
background-color:azure;
}
#tbl_fruit{
width:60%;
line-height:28px;
margin-top:120px;
margin-left:20%;
}
#div_fruit_list{
width:100%;
border:0px solid red;
}
#tbl_fruit, #tbl_fruit tr, #tbl_fruit td, #tbl_fruit th{
border: 1px solid gray;
border-collapse:collapse;
text-align:center;
font-size:16px;
font-family:"黑体";
font-weight:lighter;
color:ThreeDDarkShadow
}
.w20{
width:20%;
}
.delImg{
width:24px;
height:24px;
}
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/fruit.css">
<script type="text/javascript"src="js/demo08.js"></script>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<table id="tbl_fruit">
<tr>
<th class="w20">名称</th>
<th class="w20">单价</th>
<th class="w20">数量</th>
<th class="w20">小计</th>
<th>操作</th>
</tr>
<tr>
<td>苹果</td>
<td>5</td>
<td>20</td>
<td>100</td>
<td><img src="imgs/th.jpg"class="delImg"></td>
</tr>
<tr>
<td>大香蕉</td>
<td>3</td>
<td>30</td>
<td>90</td>
<td><img src="imgs/th.jpg"class="delImg"></td>
</tr>
<tr>
<td>芒果</td>
<td>4</td>
<td>20</td>
<td>80</td>
<td><img src="imgs/th.jpg"class="delImg"></td>
</tr>
<tr>
<td>总计</td>
<td colspan="4">999</td>
</tr>
</table>
</div>
</div>
</body>
</html>
window.onload = function(){
//当页面加载完成,我们需要绑定各种事件
//根据id获取到表格
var fruitTbl = document.getElementById("tbl_fruit");
//获取表格中的所有的行
var rows = fruitTbl.rows;
for (var i = 0; i < rows.length; i++) {
var tr = rows[i];
//1.绑定鼠标悬浮以及离开时设置背景颜色事件
tr.onmouseover = showBGColor;
tr.onmouseout = clearBGColor;
//获取tr这一行的所有单元格
var cells = tr.cells;
var priceTD = cells[1];
//2.绑定鼠标悬浮在单价单元格变手势的事件
priceTD.onmouseover = showhand;
}
}
// 当当鼠标悬浮时,设置背景颜色
function showBGColor() {
//event: 当前发生的事件
//event.srcElement
//alert(event.srcElement);
//alert(event.srcElement.tagName); -->TD
if (event && event.srcElement && event.srcElement.tagName== "TD") {
var td = event.srcElement;
//td.parentElement表示获取td的父元素 ->TR
var tr = td.parentElement;
//如果想要通过js代码设置某节点的样式,则需要加上.style
tr.style.backgroundColor = "navy";
//tr.cells表示获取这个tr中的所有单元格
var tds = tr.cells
for (var i = 0; i < tds.length; i++) {
tds[i].style.color = "white";
}
}
}
//当鼠标离开时,恢复原式样式
function clearBGColor(){
if (event && event.srcElement && event.srcElement.tagName == "TD") {
var td = event.srcElement;
var tr = td.parentElement;
tr.style.backgroundColor = "transparent";
var tds = tr.cells;
for (var i = 0; i < tds.length; i++) {
tds[i].style.color = "threeddarkshadow";
}
}
}
//当鼠标放在单价上时,他就变成手的形状
function showhand() {
if (event && event.srcElement && event.srcElement.tagName == "TD") {
var td = event.srcElement;
//cursor: 光标
td.style.cursor = "hand";
}
}
更新单价-小计-总计
css html不变
window.onload = function(){
//当页面加载完成,我们需要绑定各种事件
//根据id获取到表格
var fruitTbl = document.getElementById("tbl_fruit");
//获取表格中的所有的行
var rows = fruitTbl.rows;
for (var i = 1; i < rows.length-1; i++) {
var tr = rows[i];
//1.绑定鼠标悬浮以及离开时设置背景颜色事件
tr.onmouseover = showBGColor;
tr.onmouseout = clearBGColor;
//获取tr这一行的所有单元格
var cells = tr.cells;
var priceTD = cells[1];
//2.绑定鼠标悬浮在单价单元格变手势的事件
priceTD.onmouseover = showhand;
//3.绑定鼠标单击单元价格表的事件
priceTD.onclick = editprice;
}
}
//当鼠标点击单价单元格时进行价格编辑
function editprice() {
if (event && event.srcElement && event.srcElement.tagName == "TD") {
var priceTD = event.srcElement;
//目的是判断当前priceTD是否有子节点,而且第一个子节点是文本节点,textNode对应的是3,ElementNode对应1
if (priceTD.firstChild && priceTD.firstChild.nodeType == 3) {
//innerText表示设置或者获取当前节点的内部文本
var oldprice = priceTD.innerText;
//innerHTML表示设置当前节点内部的HTML
priceTD.innerHTML = "<input type='text'size='4'/>";
var input = priceTD.firstChild;
if (input.tagName == "INPUT") {
input.value = oldprice;
input.select();
input.onblur = updateprice;
}
}
}
}
function updateprice() {
if (event && event.srcElement && event.srcElement.tagName == "INPUT") {
var input = event.srcElement;
var newprice = input.value;
var priceTD = input.parentElement;
priceTD.innerText = newprice;
updatexj(priceTD.parentElement);
}
}
function updatexj(tr) {
if (tr && tr.tagName == "TR") {
var tds = tr.cells;
var price = tds[1].innerText;
var count = tds[2].innerText;
var xj = parseInt(price) * parseInt(count);
tds[3].innerText = xj;
updatezj();
}
}
function updatezj() {
var fruitTbl = document.getElementById("tbl_fruit"); // 重新获取表格
var rows = fruitTbl.rows;
var sum = 0;
for (var i = 1; i < rows.length - 1; i++) {
var tr = rows[i];
var xj = parseInt(tr.cells[3].innerText) || 0; // 添加默认值以防转换失败
sum += xj;
}
rows[rows.length - 1].cells[1].innerText = sum;
}
// 当当鼠标悬浮时,设置背景颜色
function showBGColor() {
//event: 当前发生的事件
//event.srcElement
//alert(event.srcElement);
//alert(event.srcElement.tagName); -->TD
if (event && event.srcElement && event.srcElement.tagName== "TD") {
var td = event.srcElement;
//td.parentElement表示获取td的父元素 ->TR
var tr = td.parentElement;
//如果想要通过js代码设置某节点的样式,则需要加上.style
tr.style.backgroundColor = "navy";
//tr.cells表示获取这个tr中的所有单元格
var tds = tr.cells
for (var i = 0; i < tds.length; i++) {
tds[i].style.color = "white";
}
}
}
//当鼠标离开时,恢复原式样式
function clearBGColor(){
if (event && event.srcElement && event.srcElement.tagName == "TD") {
var td = event.srcElement;
var tr = td.parentElement;
tr.style.backgroundColor = "transparent";
var tds = tr.cells;
for (var i = 0; i < tds.length; i++) {
tds[i].style.color = "threeddarkshadow";
}
}
}
//当鼠标放在单价上时,他就变成手的形状
function showhand() {
if (event && event.srcElement && event.srcElement.tagName == "TD") {
var td = event.srcElement;
//cursor: 光标
td.style.cursor = "hand";
}
}
建项目时的常见问题
Servlet
定义
Servlet,全称“Java Servlet”,中文意思为小服务程序或服务连接器,
Servlet是Java Servlet API的一个组成部分,其最初是由Sun公司在1990年研发出来的。Servlet是一个Java语言的组件,只需要一些基本的Java API即可编写。它是一个用Java编写的服务器端程序,遵循Servlet规范开发的Java类,由服务器调用并运行在服务器端。狭义的Servlet是指Java语言实现的一个接口,而广义的Servlet则是指任何实现了这个Servlet接口的类。
Servlet的功能
Servlet的功能非常强大,主要包括以下几个方面:
- 处理HTTP请求与响应:Servlet主要用于处理客户端(如Web浏览器)发送的HTTP请求,并根据请求生成相应的HTTP响应返回给客户端。
- 生成动态Web内容:Servlet能够生成动态的Web页面内容,这些内容可以根据客户端的请求和服务器端的数据动态生成。
- 与服务器资源通信:Servlet可以与数据库、其他Java应用程序等服务器资源进行通信,以获取或处理数据。
- 会话管理:Servlet可以管理客户端与服务器之间的会话,支持多个客户端同时与服务器进行交互。
- 安全性:Servlet可以用于实现Web应用程序的安全性,如用户认证、授权等。
Servlet的特点
Servlet具有以下几个显著的特点:
- 平台独立性:由于Servlet是用Java编写的,因此它具有Java语言的平台独立性,可以在任何支持Java的平台上运行。
- 可扩展性:Servlet可以根据业务需求进行灵活调整,甚至进行自定义开发,以满足不同的Web应用需求。
- 可重用性:Servlet可以在多个Web应用程序中重复使用,提高了代码的重用性和开发效率。
- 简易性:Java语言的基本语法对于开发Servlet程序非常简单,学习成本相对较低。
- Servlet定义:
xml
<servlet>
<servlet-name>Servlet01</servlet-name>
<servlet-class>com.ly.servlets.Servlet01</servlet-class>
</servlet>
这部分代码定义了一个Servlet,名为Servlet01
。servlet-class
标签指定了这个Servlet类的全限定名(即包含包名的类名),这里是com.ly.servlets.Servlet01
。这意味着在Web应用程序的WEB-INF/classes
目录或其JAR包中,应该存在一个名为Servlet01
的类,并且这个类位于com.ly.servlets
包中。
- Servlet映射:
xml
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
这部分代码将Servlet01
Servlet映射到特定的URL模式上,这里是/demo01
。这意味着,当Web服务器接收到以/demo01
开头的请求时,它将这个请求转发给Servlet01
处理。URL模式可以是具体的路径(如/demo01
),也可以是带有通配符的模式(如*.do
),用于匹配一类URL。
可通过映射名来访问
servlet原理
servlet设置编码
servlet继承关系已经service方法
1.继承关系:HttpServlet -> GenericServlet -> Servlet
2.Servlet中的核心方法: init(),service(),destory()
3.服务方法: 当有请求过来时,service方法会自动响应(其实是tomcat容器调用的)
在HttpServlet中我们回去分析请求的方式:到底是get,post,head还是delete等等,然后再决定调用的是哪个do开头的方法
4.因此我们在新建Servlet时,我们才会去考虑请求方法,从而决定重写哪个do方法
Servlet的生命周期
1).生命周期:从出生到死亡的过程,对应Servlet的三个方法init(),service(),destory()
2).默认情况下:
第一次接受请求时,这个Servlet会进行实例化(调用构造方法),初始化(调用init()),然后服务(调用service())
从第二次请求开始,每一次都是服务
当容器关闭时,其中所有的Servlet实例会销毁,调用销毁方法
3).通过案列我们发现
-Servlet实例tomcat只会创建一个,所有请求都是这个实例去响应
-默认情况下,第一次请求时,tomcat才会去实例化,初始化,再去服务.
-优点:提高系统的启动速度. 缺点:第一次请求时耗时较长
4).Servlet的初始化时机:
-默认是第一次接收请求进行实例化初始化
-可以通过<load-on-startup>来设置Servlet启动的先后顺序,数字越小,启动越靠前,最小值0
5).Servlet在容器中是单例的,线程不安全的
-单例:所有的请求都是同一个实例去响应
-线程不安全:一个线程需要根据这个实例的某个成员的变量值进行逻辑判断.但在中间的某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程的执行路径发送了变化.启发:尽量不要在Servlet中定义成员成员变量,如果不得不定义成员变量,那么不要:1.不要修改某个成员变量的值 2.不要根据成员变量的值进行逻辑判断
6)服务端内部转发以及客户端重定向
-服务器内部转发:requset.getRequestDispatcher("...").forward(request,response)
-一次请求响应的过程,对于客户端而言,内部经过了多少次转发,客户端是不知道的
-地址栏没变化
-客户重定向
response.sendRedirect("...")
-两次请求响应的过程,客户端肯定知道请求URL有变化
-地址栏有变化
Thymeleaf-视图模板技术
Thymeleaf一篇就够了_thymeleaf sa-CSDN
servlet保存作用域
原始情况下,保存作用域我们可以认为有四个: page(页面级别,现在几乎不用),request(一次请求响应范围),session(一次会话范围有效),application(一次应用程序内有效)
Servlet保存作用域在Java Web开发中扮演着重要角色,它允许在不同组件或请求之间共享数据。Servlet主要提供了四种保存作用域,但通常提到的三大作用域是Request、Session和Application。以下是这三种作用域的简要介绍:
1. Request作用域
定义:Request作用域是指数据在一次HTTP请求和响应期间有效,即从客户端发送请求到服务器响应请求的整个过程。它仅限于当前请求中有效,且请求之间互不干扰。
生命周期:数据存储在HttpServletRequest
对象中,当请求处理完成后,请求作用域中的数据将被销毁。
适用场景:适用于在同一次请求中传递数据,比如在重定向、请求转发、表单提交等情况下。它特别适用于Web组件之间需要共享同一个请求中的数据时。
常用方法:
request.setAttribute(String name, Object o)
:向请求中添加属性。request.getAttribute(String name)
:根据属性名获取属性值。request.removeAttribute(String name)
:从请求中移除属性。
2. Session作用域
定义:Session作用域是指数据在用户会话开始时创建,在用户关闭浏览器或会话过期后销毁,即跨越多个HTTP请求的时间段。
生命周期:数据存储在HttpSession
对象中,在用户会话期间,多个请求可以共享会话作用域中的数据。
适用场景:适用于在用户会话期间保持用户的状态信息,比如用户登录状态、购物车信息等。它允许在一个会话中的多个请求之间共享数据。
常用方法:
HttpSession session = request.getSession()
:获取当前会话的Session对象(如果当前请求没有对应的Session,则创建一个新的Session)。session.setAttribute(String name, Object value)
:向Session中添加属性。session.getAttribute(String name)
:根据属性名获取Session中的属性值。session.removeAttribute(String name)
:从Session中移除属性。
3. Application作用域
定义:Application作用域是指数据在整个Web应用程序中有效,是全局共享的。它不受限于用户会话或单个请求。
生命周期:数据存储在ServletContext
对象中,在Web应用程序启动时创建,在应用程序关闭时销毁。
适用场景:适用于在整个Web应用程序中共享全局数据,比如配置信息、数据库连接等。它允许多个用户、多个会话之间的数据共享。
常用方法:
ServletContext application = request.getServletContext()
:获取当前Web应用的ServletContext对象。application.setAttribute(String name, Object obj)
:向ServletContext中添加属性。application.getAttribute(String name)
:根据属性名获取ServletContext中的属性值。application.removeAttribute(String name)
:从ServletContext中移除属性。
综上所述,Servlet的保存作用域为Java Web开发提供了灵活的数据管理方式,根据数据的需求和生命周期,开发者可以选择合适的作用域来存储和共享数据。
Servlet路径问题
相对路径和绝对路径
Http协议
1).介绍
超文本传输协议.最大的作用是确定了请求和响应数据的格式.浏览器发送给服务器的数据:请求报文;服务器返回给浏览器的数据:响应报文
2).Http是无状态的
3).Http请求响应包含两个部分:请求和响应
-请求:
请求包含三个部分: 1.请求行; 2.请求消息头; 3.请求主体
1)请求行包含三个信息: 1.请求的方式; 2.请求的URL 3.请求的协议(一般是 HTTP1.1)
2)请求消息头中包含了很多客户端需要告诉服务器的信息,比如: 我的浏览器型号,版本,我能接收的类型,我给你发的内容
3)请求体,三种情况
get方式,没有请求体,但有一个Query String
post方式,没有请求体,formdata
json格式,有请求体,request payload
-响应
响应也包含三个部分: 1,响应行; 2,响应头 3.响应体
1)响应行包含三个信息: 1.协议 2.响应状态码 3.响应状态
2)响应头:包含了服务器的信息;服务器发送给浏览器的信息(内容的媒体类型,编码,内容长度等)
3)响应体:相应的实际内容
//200:正常响应
//404:找不到资源
//405:请求方式不支持
//500:服务器内部错误
会话
会话(Session)是指从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了。如果浏览器或服务端都没有被关闭,则会话就会持续建立着,浏览器和服务器就可以继续使用该会话进行请求发送和响应。
Http是无状态的
-Http无状态:服务器无法判断这两次请求时同一个客户端发过来的还是不同客户发过来的.
-无状态带来的问题:第一次添加进购物车后结账,如果这两次请求服务器无法区分是同一个用户的,就会导致混乱
-通过会话跟踪技术来解决无状态的问题.
会话跟踪技术
-客户端第一次发请求给服务器,服务器获取session,获取不到则创建新的,然后响应给客户端
-下次客户端给服务器发请求时,会把sessionID带给服务器,那么服务器就能获取到了,那么服务器就判断这一次请求和上一次请求是同一个客户端,从而能区分开客户端
-常用的API:
request.getSession()->获取当前会话,没有则创建一个
request.getSession(true)->效果和没有参数相同
request.getSession(false) ->获取当前会话,没有则返回null,不会创建新的
session.getId()->获取当前sessionID
session.isNew()->判断当前sessionID是否是新的
session.getMaxInactiveInterval()->session的非激活时长,默认1800秒
session.setMaxInactiveInterval()设置非激活时长
session.incalidate()->强制让会话立即失效
...
Session保存作用域
-session保存作用域是和某一个具体的Session对应的唯一的Session ID
-常用的API:
void session.setAttribute(k,v)
Object session.getAttribute(k)
void removeAttribute(k)
MVC
基本介绍
MVC,全称Model-View-Controller,是一种广泛使用的软件设计典范,尤其在Web开发领域有着重要的应用。它通过将应用程序划分为三个核心部分——模型(Model)、视图(View)和控制器(Controller),来实现业务逻辑、数据、界面显示的分离,从而提高了代码的可维护性、可复用性和可扩展性。
MVC的组成部分
业务层(service):
- 模型(Model):
-
- 模型是应用程序中用于处理业务逻辑和数据逻辑的部分。
- 它负责在数据库中存取数据,以及执行相关的数据验证和业务规则。
- 模型是应用程序的核心,它封装了数据和对数据的处理方法,使得数据访问和业务逻辑处理与用户界面展示分离。
- 视图(View):
-
- 视图是应用程序中处理数据显示的部分。
- 它根据模型提供的数据来创建用户界面,向用户展示信息。
- 视图不直接处理业务逻辑,而是依赖于模型提供的数据来渲染界面。
- 控制器(Controller):
-
- 控制器是应用程序中处理用户输入和响应的部分。
- 它负责接收用户的请求,根据请求调用相应的模型来处理业务逻辑,然后将处理结果传递给视图进行展示。
- 控制器充当了模型和视图之间的桥梁,协调两者之间的交互。
视图层:用于做数据展示以及和用户交互的一个界面
控制层:能够介绍客户端的请求,具体的业务功能还是需要借助于模型组件来完成
模型层:模型分为很多种:有比较简单的pojo(Plain Old Java Object)/vo(value object),有业务模型组件,有数据访问组件
1)pojo/vo:值对象
2)DAO:数据访问对象
3)BO:业务对象
区分业务对象和数据访问对象:
1)DAO中的方法都是单精度方法.一个方法只考虑一个操作.
2)BO中的方法属于业务方法,也实际的业务是比较复杂的,因此业务方法的粒度是比较粗的
注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。
那么这个业务方法中包含了多个DAo方法。也就是说注册这个业务功能需要通过多个DAo方法的组合调用,从而完成注册功能的;注册:
1. 检查用户名是否已经被注册 - DAO中的select操作
2. 向用户表新增一条新用户记录- DAO中的insert操作
3.向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作
4.向系统消息表新增一条记录(某某某新用户注册了,需要根据通讯录信息向他的联系人推送消息) - DAO中的inser
5.向系统日志表新增一条记录(某用户在某Ip在某年某月某日某时某分某秒某毫秒注册)- DAO中的insert操作
IOC
IoC(控制反转)
IoC,即Inversion of Control,意为控制反转,也称为依赖注入(Dependency Injection,DI)。它是设计模式的一种,其核心是将对象间的依赖关系的关注点从程序内部转移到程序外部,通过容器来管理对象的创建、销毁及依赖关系,从而实现松耦合、可维护和可测试。
主要特点和作用:
- 降低耦合度:通过容器管理对象及其依赖关系,减少对象间的直接依赖。
- 提高可维护性和可扩展性:当依赖对象发生变化时,只需修改容器配置,无需修改代码。
- 便于测试:可以使用Mock对象来模拟依赖对象,简化测试过程。
实现方式:
- 依赖注入:将依赖的对象通过构造函数、Setter方法或接口注入到被依赖的对象中。
- IoC容器:负责实例化、配置和组装Bean,管理Bean的生命周期和依赖关系。Spring提供了两种IoC容器:BeanFactory和ApplicationContext。
1.耦合/依赖
依赖:即某某某离不开某某某
在软件系统中,层与层之间是存在依赖的,也称之为耦合.
我们系统架构或者是设计的一个原则是:高内聚低耦合
层内部的组成应该是高度耦合的.而层与层之间的关系应该是低耦合的,最理想的情况是0耦合.
Filter过滤器
- 定义:Filter是Java Servlet API中的组件,用于在HTTP请求和响应处理过程中进行数据过滤和干预。它是JAVAEE技术规范之一,定义了一套对目标资源的请求进行过滤的技术规范。
- 作用:Filter可以在请求到达目标资源之前或响应发送给客户端之后,对请求和响应进行预处理或后处理。这包括修改请求头、请求参数、响应体等,或者根据一定条件决定是否放行请求。
1)Filter也属于Servlet规范
2)Filter开发步骤:新建类实现Filter接口,然后实现其中的三个方法:init,doFilter,destroy
配置Filter,可以用注解@WebFilter,也可以使用xml文件<filter><filter-mapping>
3)Filter在配置时,和Servlet一样,也可以配置通配符,例如@WebFilter("*.do")表示拦截所有以.do结尾的请求
4)过滤器链
1)如果采取的是注解的方式进行配置,那么过滤器拦截的顺序就是按照全类名的先后顺序排列
2)如果采取的是xml文件的方式进行配置,那么按照配置的先后顺序进行排序.
事务管理需要了解的前置知识
QQzone
1.熟悉QQzone业务需求
1) 用户登录
2) 登录成功,显示主界面,左侧是好友列表:上端显示欢迎词.如果不是自己的空间,则显示超链接:返回自己的空间
3) 查看日志详细:
- 日志本身的信息(作者头像,昵称,日志标题,日志内容,日志的日期)
- 回复列表(回复者的头像,昵称,回复内容,回复日期)
- 主人回复信息
4) 删除日志
5) 删除特定回复
6) 删除主人回复
7) 添加日志,添加回复,添加主人回复
8) 点击左侧好友链接,进入好友空间
2.数据库设计
1) 抽取实体 : 用户登录信息,用户详细信息,日志,回帖,主任回复
2) 分析其中的属性:
- 用户登录信息: 账号,密码,头像.昵称
- 用户详细信息: 真实姓名,星座,血型,邮箱,手机号...
- 日志: 标题,内容,日期,作者
- 回复: 内容,日期,作者,日志
- 主任回复: 内容,日期,作者,回复
3) 分析实体之前的关系
- 用户登录信息 : 用户详细信息 1:1 PK(主键)
- 用户 : 日志 1:N
- 日志 : 回复 1:N
- 回复 : 主人回复 1:1 UK
- 用户 : 好友 M:N
3.数据库的范式:
1) 第一个范式: 列不可再分
2) 第二个范式: 一张表只表达一层含义(只描述一件事)
3) 第三个范式: 表中的每一列和主键都是直接依赖关系,而不是间接依赖关系
4.数据库设计的范式和数据库的查询性能很多时候是相悖的,我们需要根据实际的业务情况做一个选择:
- 查询频次不高的情况下,我们更倾向于提高数据库的设计范式,从而提高存储效率
- 查询频次较高的情况下,我们更倾向于牺牲数据库的规范度,从而降低数据库设计的范式,允许特定特定的冗余,从而提高查询效率