day7 - javascript(三)
内置对象(续)
Date
在JavaScript中,Date
对象用来表示日期和时间。
要获取系统当前时间,用:
var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳
注意,当前时间是浏览器从本机操作系统获取的时间,所以不一定准确,因为用户可以把当前时间设定为任何值。
如果要创建一个指定日期和时间的Date
对象,可以用:
var d = new Date(2015, 5, 19, 20, 15, 30, 123);
d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)
JavaScript的Date对象月份值从0开始,牢记0=1月,1=2月,2=3月,……,11=12月。
第二种创建一个指定日期和时间的方法是解析一个符合ISO 8601格式的字符串:
var d = Date.parse('2015-06-24T19:49:22.875+08:00');
d; // 1435146562875
但它返回的不是Date
对象,而是一个时间戳。不过有时间戳就可以很容易地把它转换为一个Date
:
var d = new Date(1435146562875);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
d.getMonth(); // 5
使用Date.parse()时传入的字符串使用实际月份0112,转换为Date对象后getMonth()获取的月份值为011。
RegExp
<input type="text" name="" id="phone" placeholder="请输入手机号">
<button onclick="check()">验证</button>
<script>
function check(){
var input = document.getElementById('phone');
//获取输入框值
var phone = input.value;
//正则表达式
var regex = /^1[345789]\d{9}$/;
if(regex.test(phone)){
alert('手机号格式正确')
}else{
alert('格式不正确')
}
}
</script>
JSON对象
//json对象
var user = {
id:101,
name:'softeem',
age:18,
langs:['java','c++','python','javascript']
}
//json字符串
var user2 = "{\"id\":101,\"name\":\"softeem\",\"age\":18,\"langs\":[\"java\",\"javascript\"]}";
console.log(user);
console.log(user2);
//json字符串(来自后台)转换为json对象(javascript)
user2 = JSON.parse(user2);
console.log(user2);
//json对象序列化为json字符串
user = JSON.stringify(user);
console.log(user);
DOM
DOM(Document Object Model),文档对象模型;在javascript中将html中的所有元素看作为一颗倒置文档树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cnihThLr-1598188797304)(D:\带班资料\2020\j2003\线下\part4-web前端\20200817\笔记\assets\1597633651121.png)]
DOM对象
//document表示整个html文档
// document.head 获取html文档的头部
// document.body 获取html中body部分
//获取文档中的所有元素
var alls = document.all;
//获取文档中所有img节点
var imgs = document.images;
//获取文档中所有的a元素(超链接)
var links = document.links;
//获取文档中所有的表单对象
var forms = document.forms;
常见DOM操作
//根据元素的id获取元素(返回唯一结果)
var img = document.getElementById('img1');
//根据css选择器获取单个元素
var box = document.querySelector('.box>div>p');
//根据css选择器获取所有符合条件的元素
var inputs = document.querySelectorAll('.txt');
//根据class名称获取所有元素
var txt = document.getElementsByClassName('txt');
//根据标签名获取所有的元素
var div = document.getElementsByTagName('div');
//根据元素的name属性获取所有元素
var favs = document.getElementsByName('fav');
表单操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="checkbox" name="fav" value="java">学java
<input type="checkbox" name="fav" value="js">学javascript
<input type="checkbox" name="fav" value="mysql">学数据库
<input type="checkbox" name="fav" value="jdbc">学jdbc <br>
<input type="checkbox"
name=""
id="selectAll"
onclick="selectAll(this.checked)">全选1
<input type="checkbox" name="" id="selectAll2">全选2
<script>
//全选实现1
function selectAll(isSelected){
var cks = document.getElementsByName('fav');
for(var i = 0;i<cks.length;i++){
cks[i].checked = isSelected;
}
}
//全选实现2 document.getElementById('selectAll2').addEventListener('click',function(){
var cks = document.getElementsByName('fav');
for(var i = 0;i<cks.length;i++){
cks[i].checked = this.checked;
}
})
</script>
</body>
</html>
Audio
//创建音频元素
var player = document.createElement('audio');
//设置属性
player.src = 'music/taotai.mp3';
document.getElementById('btnPlay').onclick=function(){
//播放
player.play();
}
document.getElementById('btnPause').onclick=function(){
//暂停播放
player.pause();
}
//为播放器绑定当前播放时间改变事件,一旦currentTime值产生变化就执行以下函数
player.addEventListener('timeupdate',function(){
//获取当前播放进度(秒)
var now = player.currentTime;
//获取歌曲的总播放时长(秒)
var total = player.duration;
var w = now / total * 100 + '%';
//调用dom元素的css属性
document.querySelector('.progress').style.width = w;
})
//当歌曲播放完成之后执行
player.addEventListener('ended',function(){
})
练习
实现数据绑定功能
var musics = [ {
ablum: "xxx",
artist: "sdefsdf",
id: 11,
name: "不爱我就别伤害我",
path: "musics/1592384107425.mp3",
size: 3607533,
style: "流行",
uptime: 1592384107000
},
{
ablum: "xxx",
artist: "sdefsdf",
id: 12,
name: "大田后生仔",
path: "musics/1592384126362.mp3",
size: 7281893,
style: "流行",
uptime: 1592384126000
}]
day8 - javascript-BOM
BOM对象
BOM(Browser Object Model),javascript内置一些能够跟本机浏览器交互的对象,这些对象都隶属于顶层对象window
- 获取浏览器的版本相关信息使用navigator
- 获取浏览器窗口信息使用window
- 获取本机屏幕相关信息适应screen
- 获取导航信息,链接跳转使用location
- 需要获取历史记录以及跳转使用history
window
window对象是js中的全局作用域,也表示浏览器窗口信息
window对象中包含的常见属性:
-
innerHeight 获取浏览器内部高度
-
innnerWidth 获取浏览器内部宽度
-
outerHeight 获取浏览器外部高度
-
outerWidth 获取浏览器外部宽度
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KLI1QMAY-1598188848805)(\assets\1597712513131.png)]
window对象常见方法:
- alert:警告框
- confirm:确认框
- prompt:输入提示框
- open:打开新的窗口
- setInterval
- setTimeout
navigator
navigator
对象表示浏览器的信息,最常用的属性包括:
- navigator.appName:浏览器名称;
- navigator.appVersion:浏览器版本;
- navigator.language:浏览器设置的语言;
- navigator.platform:操作系统类型;
- navigator.userAgent:浏览器设定的
User-Agent
字符串。
console.log('appName = ' + navigator.appName);
console.log('appVersion = ' + navigator.appVersion);
console.log('language = ' + navigator.language);
console.log('platform = ' + navigator.platform);
console.log('userAgent = ' + navigator.userAgent);
请注意,navigator
的信息可以很容易地被用户修改,所以JavaScript读取的值不一定是正确的。很多初学者为了针对不同浏览器编写不同的代码,喜欢用if
判断浏览器版本,例如:
var width;
if (getIEVersion(navigator.userAgent) < 9) {
width = document.body.clientWidth;
} else {
width = window.innerWidth;
}
但这样既可能判断不准确,也很难维护代码。正确的方法是充分利用JavaScript对不存在属性返回undefined
的特性,直接用短路运算符||
计算:
var width = window.innerWidth || document.body.clientWidth;
screen
screen
对象表示屏幕的信息,常用的属性有:
- screen.width:屏幕宽度,以像素为单位;
- screen.height:屏幕高度,以像素为单位;
- screen.colorDepth:返回颜色位数,如8、16、24。
console.log('Screen size = ' + screen.width + ' x ' + screen.height);
location
location
对象表示当前页面的URL信息。例如,一个完整的URL:
http://www.example.com:8080/path/index.html?a=1&b=2#TOP
可以用location.href
获取。要获得URL各个部分的值,可以这么写:
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'
要加载一个新页面,可以调用location.assign()
。如果要重新加载当前页面,调用location.reload()
方法非常方便。
if (confirm('重新加载当前页' + location.href + '?')) {
location.reload();
} else {
location.assign('/'); // 设置一个新的URL地址
}
history
history
对象保存了浏览器的历史记录,JavaScript可以调用history
对象的back()
或forward ()
,相当于用户点击了浏览器的“后退”或“前进”按钮。
这个对象属于历史遗留对象,对于现代Web页面来说,由于大量使用AJAX和页面交互,简单粗暴地调用history.back()
可能会让用户感到非常愤怒。
新手开始设计Web页面时喜欢在登录页登录成功时调用history.back()
,试图回到登录前的页面。这是一种错误的方法。
localStorage
// cookie :存在安全风险
// 在html5中新增了浏览器本地存储的api,主要包含两个对象:
// + localStorage 本地存储
// + sessionStorage 基于一次会话存储
// 以上两个对象存储数据的方式类似java中的Map:以键值对的形式存储数据
console.log(localStorage)
//向本地存储中存储数据
localStorage.setItem('name','softeem');
localStorage.setItem('sex','男');
//获取存储的元素个数
console.log(localStorage.length);
//获取本地存储的数据
console.log(localStorage.getItem('name'));
document.getElementById('del').addEventListener('click',function(){
//移除某一个元素
localStorage.removeItem('sex');
})
document.getElementById('clearAll').addEventListener('click',function(){
//清除本地存储
localStorage.clear();
})
//获取指定索引对应的键名
console.log(localStorage.key(1))
综合案例开发:音乐播放器客户端实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zNfTae40-1598188848812)(D:\带班资料\2020\j2003\线下\part4-web前端\20200818\笔记\assets\1597832594588.png)]
核心js代码
数据(data.js)
var musics = [
{
ablum: "海阔天空",
artist: "Beyond",
id: 1,
name: "大地",
path: "musics/1592373302464.mp3",
size: 4147913,
style: "摇滚",
uptime: 1592373302000
},
{
ablum: "xxx",
artist: "GALA ",
id: 2,
name: "追梦赤子心",
path: "musics/1592373330188.mp3",
size: 8357216,
style: "摇滚",
uptime: 1592373330000
},
{
ablum: "123",
artist: "筷子兄弟",
id: 3,
name: "父亲",
path: "musics/1592373363687.mp3",
size: 12050851,
style: "怀旧",
uptime: 1592373363000
}
]
功能实现
//创建音频播放器对象
var player = document.createElement('audio');
//记录当前正在播放的歌曲的索引
var currentIndex = 0;
//声明一个标记,记录歌曲的播放状态(是否播放)
var isplay = false;
//绑定数据到页面中
(function() {
var html = '';
//循环遍历歌曲列表,根据歌曲数目在页面中生成对应的html代码
for (var i = 0; i < musics.length; i++) {
var m = musics[i];
//根据循环的次数创建对应的歌曲项
html += `<tr class="music-item" data-index="${i}">
<td class="tb-space" style="text-align: center"></td>
<td><a href="javascript:;">${m.name}</a></td>
<td><a href="javascript:;">${m.artist}</a></td>
<td><a href="javascript:;">${m.ablum}</a></td>
<td>${fmtSize(m.size)}</td>
<td class="tb-space"></td>
</tr>`;
}
//将生成html插入到指定的dom节点中
document.getElementById('tbody').innerHTML = html;
//初始化播放源
player.src=musics[currentIndex].path;
})();
//为列表项触发点击事件
var trs = document.querySelectorAll('.music-item');
for(var i = 0 ;i < trs.length;i++){
trs[i].addEventListener('click',function(){
//清除播放状态
clearStatus();
//获取元素上data-index属性的属性值(获取需要播放的歌曲列表项)
var index = this.dataset.index;
//记录当前需要播放的歌曲索引
currentIndex = index;
//获取需要播放的歌曲对象
var m = musics[index];
//为播放器设置播放源
player.src = m.path;
//开始播放
startPlay();
})
}
//开始播放
function startPlay(){
//将状态标记为正在播放
isplay = true;
//播放
player.play();
//修改当前行的背景色
trs[currentIndex].style.backgroundColor='#f0f0f0';
trs[currentIndex].getElementsByTagName('td')[0].innerHTML = '<img src="imgs/playing.gif">';
//将播放按钮的背景图片设置为暂停图标
document.getElementById('btnPlay').className='btn-pause';
//将正在播放的歌曲歌曲名显示到底部控制区域
document.getElementById('playingName').innerText = musics[currentIndex].name;
}
//清除上一首正在播放的歌曲状态
function clearStatus(){
//还原上一首正在播放的歌曲列表项背景色
trs[currentIndex].style.backgroundColor='';
//清除当前行下的第一个单元格的内容(清除图标)
trs[currentIndex].getElementsByTagName('td')[0].innerHTML='';
}
//暂停播放
function pausePlay(){
//将播放状态标记为false
isplay = false;
//暂停播放
player.pause();
//将当前播放按钮的类名称修改
document.getElementById('btnPlay').className='btn-play';
}
//播放控制
document.getElementById('btnPlay').addEventListener('click',function(){
if(isplay){
pausePlay();
}else{
startPlay();
}
})
//记录歌曲的当前播放时间
var now = 0;
//记录歌曲的总播放时长
var total = 0;
//当播放器数据被加载时触发
player.addEventListener('loadeddata',function(){
//获取当前播放器的播放位置以及总播放时长(单位:秒)
now = player.currentTime;
total = player.duration;
//将歌曲的播放时间显示到控制区域
document.querySelector('.play-current').innerText = fmtTime(now);
document.querySelector('.play-duration').innerText = fmtTime(total);
})
//为播放器绑定播放进度改版实践
player.addEventListener('timeupdate',function(){
//获取最新的播放进度
now = player.currentTime;
//计算进度的百分比
var p = now / total * 100 + '%';
//为进度条元素设置宽度
document.querySelector('.progress-control').style.width=p;
//更新最新播放时间
document.querySelector('.play-current').innerText = fmtTime(now);
})
//为播放器绑定播放完成事件
player.addEventListener('ended',function(){
//清除上一首播放状态
clearStatus();
currentIndex++;
if(currentIndex >= musics.length){
currentIndex = 0;
}
//重新为播放器设置播放源
player.src = musics[currentIndex].path;
//继续播放
startPlay();
})
//工具函数,格式化歌曲的播放时间为 mm:ss
function fmtTime(time){
//将秒为单位时间转换为毫秒单位
time *= 1000;
//使用毫秒数构建一个日期对象
time = new Date(time);
var m = time.getMinutes();
var s = time.getSeconds();
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
return m + ':' + s;
}
//工具函数,格式化歌曲大小
function fmtSize(size){
size = size / (1024*1024);
size = size.toFixed(1);
return size + 'MB';
}
day1 - JavaWeb入门
Web请求结构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DM34n7zW-1598188874319)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597885098877.png)]
JavaWeb体系介绍
- web服务器
- Servlet
- JSP(轻量级Servlet)
- JDBC
Tomcat服务器(软件)
什么是Web服务器
web服务器通常也称之为web容器,提供了对javaweb项目的运行环境,内部可以实现对客户端的请求接收,通过web应用中对应的java程序进行处理(访问数据库,进行业务逻辑操作等)之后,向客户端响应运行结果。
目前javaweb开发中常见的服务器包含以下几种:
- tomcat(开源免费的web服务器)
- jetty(开源免费的web服务器,常见于一些web聊天应用)
- weblogic(Oracle开发收费的web服务器)
- jboss(开源免费的web服务器,与EJB结合良好)
服务器和服务器软件
**服务器(硬件):**实际上就是一台主机(一台电脑),一般情况下服务器配置要求要高于普通的个人电脑(PC机);在服务器中通常运行的是一些服务软件(web服务器软件,mysql数据库服务,http服务器软件等)
**服务器软件:**是运行在服务器主机上的一些应用程序,比如tomcat服务器,mysql服务器等。
Tomcat
tomcat有apache(阿帕奇)开源组织对外开源免费的一个web容器,提供了对javaweb应用中jsp和servlet等web技术的运行环境,通过http协议接收以及响应客户端请求。
tomcat下载与安装
-
访问tomcat官网:http://tomcat.apache.org/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YfN9r75J-1598188874320)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597886547214.png)]
-
下载tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jeBEJs5k-1598188874322)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597886591850.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PzpufChf-1598188874326)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597886836787.png)]
启动与访问
-
由于tomcat是由java技术编写而成,因此需要在主机中具备java的运行环境,即配置JAVA_HOME(具体参考java环境变量配置)
-
打开tomcat解压缩之后的目录,找到bin目录:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wc3NEglS-1598188874328)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597887005250.png)]
-
找到bin目录中,名字叫
startup.bat
文件(linux下使用startup.sh
)双击启动;[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egA4YuWB-1598188874329)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597887135362.png)]
-
启动正常时,命令行没有任何错误信息,并显示如下信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bRJy0Rwh-1598188874332)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597891204184.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COMvMeZb-1598188874333)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597891381717.png)]
bat:windows中的批处理文件
目录结构
tomcat的目录结构如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0op6z89-1598188874334)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597891645338.png)]
以上目录中,经常操作的主要包含以下:
conf:配置目录
webapps:web项目的发布目录
注意事项:
在tomcat访问应用程序时,如果不指定具体的资源,tomcat会默认请求名为
index.html
、index.htm
、index.jsp
等相关的资源,因为在conf/web.xml配置中默认有指定,并且该配置也允许程序员修改;[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZcZmP3j-1598188874335)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597895218636.png)]
常用配置
tomcat管理账号密码设置
当需要涉及到对tomcat中应用程序管理时,通常需要提供访问的账号密码,此时可以通过在conf/tomcat-user.xml
进行用户信息配置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W8VG4rbc-1598188874336)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597894846652.png)]
以上配置中:
第一行:配置角色
第二行:配置用户并指定角色
端口号配置
由于计算机中不同的网络应用需要对外通信就必须指定各自的访问端口,但是有可能端口会出现冲突;tomcat服务器默认占据的8080端口,即需要访问指定主机的服务器只需要通过主机名+端口即可;http协议默认端口是80,如果将tomcat服务器的端口配置为80,则访问时就无需手动指定端口号。
修改端口号
使用文本编辑器(推荐vscode)打开apache-tomcat-9.0.37>conf>server.xml
,第69~71行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-93Q1Ab92-1598188874337)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597891053160.png)]
将以上port值修改为指定数值即可
虚拟访问路径配置
所谓虚拟访问路径配置,即将主机中指定的一些资源通过tomcat服务器配置虚拟访问路径之后对外提供可访问的能力
-
准备本地的文件夹(存储的需要对外公开的资源)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qsulbShQ-1598188874337)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597893946434.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eqyFzFF0-1598188874338)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597893964395.png)]
-
打开tomcat服务器所在目录的conf目录,打开server.xml文件,配置以下标签:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JHmgHUUH-1598188874339)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597894029537.png)]
docBase:表示对外提供的资源所在的本机绝对路径
path:设置虚拟的访问地址
-
打开浏览器,访问指定资源,浏览器地址栏中输入:http://192.168.7.2/mp3/2.mp3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iF0fdSt3-1598188874340)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597894116747.png)]
地址栏中的资源路径:/mp3/2.mp3通过tomcat服务器解析之后找到服务器所在主机中虚拟路径映射的绝对路劲地址:
D:\bak\2.mp3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCioYjSA-1598188874341)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597894251521.png)]
配置Tomcat到系统服务
]
安装完成后,可在系统服务中看到该服务(需刷新)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SxF5plFr-1598188874342)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200820\笔记\assets\1597896426666.png)]
Idea中集成Tomcat
Eclipse中集成Tomcat
- 确保Eclipse是JEE版(JavaSE无法集成,需要安装web插件才可以)
Javaweb项目创建
Idea中创建Web项目
部署web项目到服务器
Eclipse中创建web项目
运行javaweb应用的前提:
- 在开发工具中有集成Tomcat服务器(如果已经集成过了可以跳过)
- 创建javaweb项目
- idea中创建: web Application
- eclipse中创建:Dynamic Web Project
- 将web程序部署到服务器中
- 启动服务器
Servlet入门
Servlet 概述
Servlet(Server+Applet),服务端小程序;是一项运行在服务器端的java程序,可以接受来自客户端的http请求,并且对请求的信息作出相应。Servlet是一项接口技术,任何时候创建一个Servlet应用都必须从Servlet接口实现,实际上就是一个java类
Hello Servlet
创建一个Servlet包含三个基本步骤:
-
创建一个类从Servlet实现(继承HttpServlet)
public class HelloServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException {} @Override public ServletConfig getServletConfig() {return null;} @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("HelloServlet...."); } @Override public String getServletInfo() {return null;} @Override public void destroy() {} }
-
实现service的方法
@Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { //实现具体的操作 }
-
配置Servlet(基于xml/基于注解)
<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.softeem.servlets.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
serlvet:
配置servlet名称以及类路径
servlet-mapping:
servlet映射配置,配置servlet名称以及虚拟的访问路径
Servlet创建方式对比
- 实现javax.servlet.Servlet接口
- 继承javax.servlet.GenericServlet类
- 继承javax.servlet.HttpServlet类(推荐)
关于405错误状态码:
客户端请求服务端的method与服务端servlet接收处理的方法不一致,比如:
客户端发送的get请求,服务端使用doPost处理
Servlet执行原理
- 当web容器启动时,首先对web.xml初始化检查配置是否正确,比如url-pattern
- 客户端浏览器发起对servlet请求,通过请求的资源路径寻找对应的url-pattern
- 通过url-pattern对应的servlet-name寻找到servlet标签中的servlet-name
- 根据servlet-name所在标签找到servlet-class并且执行对应类中的service方法
day2 - Servlet技术(二)
Servlet生命周期
任何一个Servlet类从初始化到使用完毕销毁都有一套完整的执行流程,这一套执行流程我们称之为servlet的生命周期.
生命周期
- 当请求第一次到达时,容器会对被请求的servlet初始化,并调用init方法,完成初始操作,而且只会初始化一次(单例)
- 紧接着执行service方法,service默认会根据客户端的请求方法选择调用对应的doXXX方法
- 一旦web容器停止服务,此时所有的servlet都会被销毁,同时执行destroy完成收尾工作(先执行destroy再销毁)
load-on-startup
通过对servlet设置load-on-startup配置(默认值-1),可以控制servlet的初始化顺序,一旦为servlet指定了load-on-startup配置后,则即便,客户端不请求该servlet,web容器也会默认根据设置的数值大小对指定的servlet进行初始化,并调用init方法,关于配置方式分为两种:
- 基于注解的配置
- 基于xml文件配置(web.xml)
Servlet配置详解
基于注解的servlet配置
servlet3.0之后允许使用注解的方式配置servlet,相比在web.xml配置来说,代码得到了极大的简化,具体使用方式如下:
客户端访问方式与之前保持一致:
http://localhost/javaweb02/msg
即可
url-pattern配置
//配置访问映射地址(虚拟访问路径)
//@WebServlet("/hello")
//@WebServlet({"/hello","/helloServlet","/HelloServlet"})
//@WebServlet("/user/hello")
//@WebServlet("/user/*")
//@WebServlet("/hello.do")
@WebServlet("*.do")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Hello....get");
}
}
对于以上配置方式,对应的访问地址如下:
@WebServlet("/hello")
http://localhost/javaweb02/hello
@WebServlet({"/hello","/helloServlet","/HelloServlet"})
http://localhost/javaweb02/hello
http://localhost/javaweb02/helloServlet
http://localhost/javaweb02/HelloServlet
@WebServlet("/user/hello")
http://localhost/javaweb02/user/hello
@WebServlet("/user/*")
http://localhost/javaweb02/user/XXX
@WebServlet("/hello.do")
http://localhost/javaweb02/hello.do
注意事项:
在一个web应用中不能出现重复的url-pattern,否则服务器启动时会抛出异常
ServletConfig与初始化参数
Idea配置Tomcat热部署
- 配置tomcat服务器使用热部署模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ucyzuNva-1598188962378)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200821\笔记\assets\1597979864095.png)]
-
使用debug启动web应用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5EIjS8pG-1598188962380)(D:\带班资料\2020\j2003\线下\part5-javaweb\20200821\笔记\assets\1597980105654.png)]
获取客户端提交数据
HttpServletRequest
HttpServletRequest对象表示客户端请求,当客户端通过Http协议请求到Servlet时,所有的请求数据都会封装到HttpServletRequest对象中,通过该对象提供的相关方法可以获取客户端提交过来的数据信息。
获得客户机信息:
方法 | 解释 |
---|---|
getRequestURL() | 返回客户端发出请求时的完整URL。 |
getRequestURI() | 返回请求行中的参数部分。 |
getQueryString () | 方法返回请求行中的参数部分(参数名+值) |
getRemoteHost() | 返回发出请求的客户机的完整主机名。 |
getRemoteAddr() | 返回发出请求的客户机的IP地址。 |
getPathInfo() | 返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以"/"开头。 |
getRemotePort() | 返回客户机所使用的网络端口号。 |
getLocalAddr() | 返回WEB服务器的IP地址。 |
getLocalName() | 返回WEB服务器的主机名。 |
获得客户机请求头
方法 | 解释 |
---|---|
getHeader(string name) | 以 String 的形式返回指定请求头的值。如果该请求不包含指定名称的头,则此方法返回 null。如果有多个具有相同名称的头,则此方法返回请求中的第一个头。头名称是不区分大小写的。可以将此方法与任何请求头一起使用 |
getHeaders(String name) | 以 String 对象的 Enumeration 的形式返回指定请求头的所有值 |
getHeaderNames() | 返回此请求包含的所有头名称的枚举。如果该请求没有头,则此方法返回一个空枚举 |
获得客户机请求参数
方法 | 解释 |
---|---|
getParameter(String name) | 根据name获取请求参数(常用) |
getParameterValues(String name) | 根据name获取请求参数列表(常用) |
getParameterMap() | 返回的是一个Map类型的值,该返回值记录着前端(如jsp页面)所提交请求中的请求参数和请求参数值的映射关系。(编写框架时常用) |
getParameterNames() | 获取所有请求参数的name名称 |
案例
-
表单结构
<form action="msg"> 用户名: <input type="text" name="name"><br> 密码:<input type="password" name="pwd"><br> 年龄:<input type="number" name="age"><br> <!--对于单选按钮,如果未指定value时,后台获取到的是on;如果未进行选择则获取null--> 性别:<input type="radio" name="sex" id="sex_male" checked value="男"><label for="sex_male">男</label> <input type="radio" name="sex" id="sex_famale" value="女"> <label for="sex_famale">女</label> <br> 兴趣爱好: <input type="checkbox" name="hobby" value="java">java <input type="checkbox" name="hobby" value="game">打游戏 <input type="checkbox" name="hobby" value="doudou">打豆豆 <input type="checkbox" name="hobby" value="sleep">睡觉 <br> 所在城市:<select name="city"> <option value="武汉">武汉</option> <option value="北京">北京</option> <option value="上海">上海</option> <option value="广州">广州</option> <option value="深圳">深圳</option> </select><br> 个性签名: <textarea name="mark" cols="50" rows="5"></textarea><br> 出生日期: <input type="date" name="birth"><br> <button type="submit">注册</button> </form>
-
servlet中doGet方法实现
//设置请求编码(解决提交数据时的乱码问题) request.setCharacterEncoding("utf-8"); //获取请求参数中指定参数名的参数值(参数即为表单控件的name属性) String name = request.getParameter("name"); String pwd = request.getParameter("pwd"); String age = request.getParameter("age"); String sex = request.getParameter("sex"); // String hobby = request.getParameter("hobby"); //获取多个参数名一致的参数值,并以数组的形式返回(复选框) String[] hobbies = request.getParameterValues("hobby"); String city = request.getParameter("city"); String mark = request.getParameter("mark"); String birth = request.getParameter("birth"); System.out.println(name); System.out.println(pwd); System.out.println(age); System.out.println(sex); for(String h:hobbies){ System.out.println(h); } System.out.println(city); System.out.println(mark); System.out.println(birth); System.out.println("===================================="); //获取请求中所有提交数据 Map<String, String[]> parameterMap = request.getParameterMap(); parameterMap.forEach((k,v)->{ for(String s:v){ System.out.println(k+"---->"+s); } });