.jpeg.-jpg
jQuery,顾名思义,也就是JavaScript和查询(query),他就是辅助JavaScript开发的JS类库。
免费、开源、语法设计可以使开发更便捷,例如操作文档对象(DOM)、选择DOM元素、制作动画效果、事件处理、使用Ajax以及其他功能
选择器 | 描述 |
---|---|
#ID | 选择器:根据 id 查找标签对象 |
.class | 选择器:根据 class 查找标签对象 |
element | 选择器:根据标签名查找标签对象 |
* | 选择器:表示任意的,所有的元素 |
selector1,selector2 | 组合选择器:合并选择器 1,选择器 2 的结果并返回 |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
div, span, p {
width: 140px;
height: 140px;
margin: 5px;
background: #aaa;
border: #000 1px solid;
float: left;
font-size: 17px;
font-family: Verdana;
}
div.mini {
width: 55px;
height: 55px;
background-color: #aaa;
font-size: 12px;
}
div.hide {
display: none;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script>
$(function (){
//1.选择 body 内的所有 div 元素
$("#btn1").click(function () {
$("body div").css("background-color","#bbffaa");
})
//2.在 body 内, 选择div子元素
$("#btn2").click(function () {
$("body > div").css("background-color","#bbffaa");
})
//3.选择 id 为 one 的下一个 div 元素
$("#btn3").click(function (){
$("#one + div").css("background-color","#bbffaa");
})
//4.选择 id 为 two 的元素后面的所有 div 兄弟元素
$("#btn4").click(function () {
$("#two ~ div").css("background-color","#bbffaa");
})
})
script>
head>
<body>
<input type="button" value="选择 body 内的所有 div 元素" id="btn1" />
<input type="button" value="在 body 内, 选择div子元素" id="btn2" />
<input type="button" value="选择 id 为 one 的下一个 div 元素" id="btn3" />
<input type="button" value="选择 id 为 two 的元素后面的所有 div 兄弟元素" id="btn4" />
<br><br>
<div class="one" id="one">
id 为 one,class 为 one 的div
<div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
id为two,class为one,title为test的div
<div class="mini" title="other">class为mini,title为otherdiv>
<div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">div>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<span id="span">^^span元素^^span>
body>
html>
选择器 | 描述 |
---|---|
ancestor descendant | 后代选择器 :在给定的祖先元素下匹配所有的后代元素 |
parent > child | 子元素选择器:在给定的父元素下匹配所有的子元素 |
prev + next | 相邻元素选择器:匹配所有紧接在 prev 元素后的 next 元 |
prev ~ sibings | 之后的兄弟元素选择器:匹配 prev 元素之后的所有 siblings 元素 |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
div, span, p {
width: 140px;
height: 140px;
margin: 5px;
background: #aaa;
border: #000 1px solid;
float: left;
font-size: 17px;
font-family: Verdana;
}
div.mini {
width: 55px;
height: 55px;
background-color: #aaa;
font-size: 12px;
}
div.hide {
display: none;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script>
$(function (){
//1.选择 body 内的所有 div 元素
$("#btn1").click(function () {
$("body div").css("background-color","#bbffaa");
})
//2.在 body 内, 选择div子元素
$("#btn2").click(function () {
$("body > div").css("background-color","#bbffaa");
})
//3.选择 id 为 one 的下一个 div 元素
$("#btn3").click(function (){
$("#one + div").css("background-color","#bbffaa");
})
//4.选择 id 为 two 的元素后面的所有 div 兄弟元素
$("#btn4").click(function () {
$("#two ~ div").css("background-color","#bbffaa");
})
})
script>
head>
<body>
<input type="button" value="选择 body 内的所有 div 元素" id="btn1" />
<input type="button" value="在 body 内, 选择div子元素" id="btn2" />
<input type="button" value="选择 id 为 one 的下一个 div 元素" id="btn3" />
<input type="button" value="选择 id 为 two 的元素后面的所有 div 兄弟元素" id="btn4" />
<br><br>
<div class="one" id="one">
id 为 one,class 为 one 的div
<div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
id为two,class为one,title为test的div
<div class="mini" title="other">class为mini,title为otherdiv>
<div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">div>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<span id="span">^^span元素^^span>
body>
html>
选择器 | 描述 |
---|---|
:first | 获取第一个元素 |
:last | 获取最后个元素 |
:not(selector) | 去除所有与给定选择器匹配的元素 |
:even | 匹配所有索引值为偶数的元素,从 0 开始计 |
:odd | 匹配所有索引值为奇数的元素,从 0 |
:eq(index) | 匹配一个给定索引值的元素 |
:gt(index) | 匹配所有大于给定索引值的元素 |
:lt(index) | 匹配所有小于给定索引值的元素 |
:header | 匹配如 h1, h2, h3 |
:animated | 匹配所有正在执行动画效果的元素 |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
div, span, p {
width: 140px;
height: 140px;
margin: 5px;
background: #aaa;
border: #000 1px solid;
float: left;
font-size: 17px;
font-family: Verdana;
}
div.mini {
width: 55px;
height: 55px;
background-color: #aaa;
font-size: 12px;
}
div.hide {
display: none;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script>
$(document).ready(function(){
function anmateIt(){
$("#mover").slideToggle("slow", anmateIt);
}
anmateIt();
});
$(function () {
//1.选择第一个 div 元素
$("#btn1").click(function () {
$("div:first").css("background-color","#bbffaa");
})
//2.选择最后一个 div 元素
$("#btn2").click(function () {
$("div:last").css("background-color","red");
})
//3.选择class不为 one 的所有 div 元素
$("#btn3").click(function () {
$("div:not(.one)").css("background-color","#bbffaa");
})
//4.选择索引值为偶数的 div 元素
$("#btn4").click(function () {
$("div:even").css("background-color","#bbffaa")
})
//5.选择索引值为奇数的 div 元素
$("#btn5").click(function () {
$("div:odd").css("background-color","#bbffaa")
})
//6.选择索引值为大于 3 的 div 元素
$("#btn6").click(function () {
$("div:gt(3)").css("background-color","#bbffaa")
})
//7.选择索引值为等于 3 的 div 元素
$("#btn7").click(function () {
$("div:eq(3)").css("background-color","#bbffaa")
})
//8.选择索引值为小于 3 的 div 元素
$("#btn8").click(function () {
$("div:lt(3)").css("background-color","#bbffaa")
})
//9.选择所有的标题元素
$("#btn9").click(function () {
$(":header").css("background-color","#bbffaa")
})
//10.选择当前正在执行动画的所有元素
$("#btn10").click(function () {
$("div:animated").css("background-color","#bbffaa")
})
//选择没有执行动画的最后一个div
$("#btn11").click(function () {
$("div:not(:animated):last").css("background-color","#bbffaa")
})
})
script>
head>
<body>
<input type="button" value="选择第一个div元素" id="btn1">
<input type="button" value="选择最后一个div元素" id="btn2">
<input type="button" value="选择class不为one的所有div元素" id="btn3">
<input type="button" value="选择索引值为偶数的div元素" id="btn4">
<input type="button" value="选择索引值为奇数的div元素" id="btn5">
<input type="button" value="选择索引值大于3的div元素" id="btn6">
<input type="button" value="选择索引值等于3的div元素" id="btn7">
<input type="button" value="选择索引值小于3的div元素" id="btn8">
<input type="button" value="选择所有的标题元素" id="btn9">
<input type="button" value="选择当前正在执行动画的所有元素" id="btn10" />
<input type="button" value="选择没有执行动画的最后一个div" id="btn11" />
<h3>基本选择器h3>
<br><br>
<div class="one" id="one">
id为one,class为one的div
<div class="mini">class为mini的ivdiv>
div>
<div class="one" id="two" title="test">
id为two,class为one,title为test的div
<div class="mini" title="other">class为mini,title为otherdiv>
<div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">div>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<div id="mover">正在执行动画的div元素.div>
body>
html>
选择器 | 描述 |
---|---|
:contains(text) | 匹配包含给定文本的元素 |
:empty | 匹配所有不包含子元素或者文本的空元素 |
:parent | 匹配含有子元素或者文本的元素 |
:has(selector) | 匹配含有选择器所匹配的元素的元素 |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
div, span, p {
width: 140px;
height: 140px;
margin: 5px;
background: #aaa;
border: #000 1px solid;
float: left;
font-size: 17px;
font-family: Verdana;
}
div.mini {
width: 55px;
height: 55px;
background-color: #aaa;
font-size: 12px;
}
div.hide {
display: none;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script>
/**
:contains(text)
:empty
:has(selector)
:parent
*/
$(document).ready(function(){
function anmateIt(){
$("#mover").slideToggle("slow", anmateIt);
}
anmateIt();
});
$(function () {
//1.选择 含有文本 'di' 的 div 元素
$("#btn1").click(function () {
$("div:contains('di')").css("background-color","#bbffaa")
})
//2.选择不包含子元素(或者文本元素) 的 div 空元素
$("#btn2").click(function () {
$("div:empty").css("background-color","#bbffaa");
})
//3.选择含有 class 为 mini 元素的 div 元素
$("#btn3").click(function () {
$("div:has(.mini)").css("background-color","#bbffaa")
})
//4.选择含有子元素(或者文本元素)的div元素
$("#btn4").click(function () {
$("div:parent").css("background-color","#bbffaa")
})
})
script>
head>
<body>
<input type="button" value="选择 含有文本 'di' 的 div 元素" id="btn1" />
<input type="button" value="选择不包含子元素(或者文本元素) 的 div 空元素" id="btn2" />
<input type="button" value="选择含有 class 为 mini 元素的 div 元素" id="btn3" />
<input type="button" value="选择含有子元素(或者文本元素)的div元素" id="btn4" />
<br><br>
<div class="one" id="one">
id 为 one,class 为 one 的div
<div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
id为two,class为one,title为test的div
<div class="mini" title="other">class为mini,title为otherdiv>
<div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">div>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<div id="mover">正在执行动画的div元素.div>
body>
html>
选择器 | 描述 |
---|---|
[attribute] | 匹配包含给定属性的元素 |
[attribute=value] | 匹配给定的属性是某个特定值的元素 |
[attribute!=value] | 匹配所有不含有指定的属性,或者属性不等于特定值的元素。 |
[attribute^=value] | 匹配给定的属性是以某些值开始的元素 |
[attribute$=value] | 匹配给定的属性是以某些值结尾的元素 |
[attribute*=value] | 匹配给定的属性是以包含某些值的元素 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BpBZmO6Z-1647142934498)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211218211913710.png)] | 复合属性选择器,需要同时满足多个条件时使用。 |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style type="text/css">
div,span,p {
width: 140px;
height: 140px;
margin: 5px;
background: #aaa;
border: #000 1px solid;
float: left;
font-size: 17px;
font-family: Verdana;
}
div.mini {
width: 55px;
height: 55px;
background-color: #aaa;
font-size: 12px;
}
div.hide {
display: none;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script>
/**
[attribute]
[attribute=value]
[attribute!=value]
[attribute^=value]
[attribute$=value]
[attribute*=value]
[attrSel1][attrSel2][attrSelN]
*/
$(function () {
//1.选取含有 属性title 的div元素
$("#btn1").click(function() {
$("div[title]").css("background", "#bbffaa");
});
//2.选取 属性title值等于'test'的div元素
$("#btn2").click(function() {
$("div[title = 'test']").css("background", "#bbffaa");
});
//3.选取 属性title值不等于'test'的div元素(*没有属性title的也将被选中)
$("#btn8").click(function() {
$("div[title != 'test']").css("background", "#bbffaa");
});
//4.选取 属性title值 以'te'开始 的div元素
$("#btn4").click(function() {
$("div[title ^= 'te']").css("background", "#bbffaa");
});
//5.选取 属性title值 以'est'结束 的div元素
$("#btn5").click(function() {
$("div[title $= 'est' ]").css("background", "#bbffaa");
});
//6.选取 属性title值 含有'es'的div元素
$("#btn6").click(function() {
$("div[title *= 'es']").css("background", "#bbffaa");
});
//7.首先选取有属性id的div元素,然后在结果中 选取属性title值 含有'es'的 div 元素
$("#btn7").click(function() {
$("div[id][title *= 'es']").css("background", "#bbffaa");
});
//8.选取 含有 title 属性值, 且title 属性值不等于 test 的 div 元素
$("#btn8").click(function() {
$("div[title][title != 'test']").css("background", "#bbffaa");
});
})
script>
head>
<body>
<input type="button" value="选取含有 属性title 的div元素." id="btn1" style="display: none;"/>
<input type="button" value="选取 属性title值等于'test'的div元素." id="btn2" />
<input type="button"
value="选取 属性title值不等于'test'的div元素(没有属性title的也将被选中)." id="btn3" />
<input type="button" value="选取 属性title值 以'te'开始 的div元素." id="btn4" />
<input type="button" value="选取 属性title值 以'est'结束 的div元素." id="btn5" />
<input type="button" value="选取 属性title值 含有'es'的div元素." id="btn6" />
<input type="button"
value="组合属性选择器,首先选取有属性id的div元素,然后在结果中 选取属性title值 含有'es'的 div 元素."
id="btn7" />
<input type="button"
value="选取 含有 title 属性值, 且title 属性值不等于 test 的 div 元素." id="btn8" />
<br>
<br>
<div class="one" id="one">
id 为 one,class 为 one 的div
<div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
id为two,class为one,title为test的div
<div class="mini" title="other">class为mini,title为otherdiv>
<div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">div>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display: none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<div>
包含input的type为"hidden"的div<input type="hidden" value="123456789"
size="8">
div>
<div id="mover">正在执行动画的div元素.div>
body>
html>
选择器 | 描述 |
---|---|
:input | 匹配所有 input, textarea, select 和 button 元素 |
:text | 匹配所有 文本输入框 |
:password | 匹配所有的密码输入框 |
:radio | 匹配所有的单选框 |
:checkbox | 匹配所有的复选框 |
:submit | 匹配所有提交按钮 |
:image | 匹配所有 img 标 |
:reset | 匹配所有重置按钮 |
:button | 匹配所有 input type=button 按 |
:file | 匹配所有 input type=file 文件上传 |
:hidden | 匹配所有不可见元素 display:none 或 input |
选择器 | 描述 |
---|---|
:enabled | 匹配所有可用元素 |
:disabled | 匹配所有不可用元素 |
:checked | 匹配所有选中的单选,复选,和下拉列表中选中的 option 标签对 |
:selected | 匹配所有选中的 option |
综合表单和属性过滤器示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script>
$(function () {
/**
:input
:text
:password
:radio
:checkbox
:submit
:image
:reset
:button
:file
:hidden
表单对象的属性
:enabled
:disabled
:checked
:selected
*/
//1.对表单内 可用input 赋值操作
//val()可以操作表单选项的value属性值
//可以设置和获取
$("#btn1").click(function () {
$(":text:enabled").val("我叫张二狗")
})
//2.对表单内 不可用input 赋值操作
$("#btn2").click(function (){
$(":text:disabled").val("我叫狗蛋")
})
//3.获取多选框选中的个数 使用size()方法获取选取到的元素集合的元素个数
$("#btn3").click(function () {
alert($(":checkbox:checked").length)
})
//4.获取多选框,每个选中的value值
$("#btn4").click(function () {
//获取所有选中的复选框
let $cehe = $(":checkbox:checked");
//each方法是jQuery对象提供用来遍历元素的方法
//在遍历的function函数中,有一个this对象,这个this对象,就是当前遍历到的dom对象
$cehe.each(function () {
alert(this.value)
});
})
//5.获取下拉框选中的内容
$("#btn5").click(function () {
//获取选中的option标签对象
let opt = $("select option:selected");
//遍历,获取option标签内容
opt.each(function () {
alert(this.value);
});
})
})
script>
head>
<body>
<h3>表单对象属性过滤选择器h3>
<button id="btn1">对表单内 可用input 赋值操作.button>
<button id="btn2">对表单内 不可用input 赋值操作.button>
<br/><br/>
<button id="btn3">获取多选框选中的个数.button>
<button id="btn4">获取多选框选中的内容.button>
<br/><br/>
<button id="btn5">获取下拉框选中的内容.button>
<br/><br/>
<form id="form1" action="#">
可用元素: <input name="add" value="可用文本框1"/><br>
不可用元素: <input name="email" disabled="disabled" value="不可用文本框"/><br>
可用元素: <input name="che" value="可用文本框2"/><br>
不可用元素: <input name="name" disabled="disabled" value="不可用文本框"/><br>
<br>
多选框: <br>
<input type="checkbox" name="newsletter" checked="checked" value="test1"/>test1
<input type="checkbox" name="newsletter" value="test2"/>test2
<input type="checkbox" name="newsletter" value="test3"/>test3
<input type="checkbox" name="newsletter" checked="checked" value="test4"/>test4
<input type="checkbox" name="newsletter" value="test5"/>test5
<br><br>
下拉列表1: <br>
<select name="test" multiple="multiple" style="height: 100px" id="sele1">
<option>浙江option>
<option selected="selected">辽宁option>
<option>北京option>
<option selected="selected">天津option>
<option>广州option>
<option>湖北option>
select>
<br><br>
下拉列表2: <br>
<select name="test2">
<option>浙江option>
<option>辽宁option>
<option selected="selected">北京option>
<option>天津option>
<option>广州option>
<option>湖北option>
select>
form>
body>
html>
选择器 | 描述 |
---|---|
eq() | 获取给定索引的元素 |
first() | 获取第一个元素 |
last() | 获取最后一个元素 |
filter(exp) | 留下匹配的元素 |
is(exp) | 判断是否匹配给定的选择器,只要有一个匹配就返回,true |
has(exp) | 返回包含有匹配选择器的元素的元素 |
not(exp) | 删除匹配选择器的元素 |
children(exp) | 返回匹配给定选择器的子元素 |
find(exp) | 返回匹配给定选择器的后代元素 |
next() | 返回当前元素的下一个兄弟元素 |
nextAll() | 返回当前元素后面所有的兄弟元素 |
nextUntil() | 返回当前元素到指定匹配的元素为止的后面元素 |
parent() | 返回父元素 |
prev(exp) | 返回当前元素的上一个兄弟元素 |
prevAll() | 返回当前元素前面所有的兄弟元素 |
prevUnit(exp) | 返回当前元素到指定匹配的元素为止的前面元素 |
siblings(exp) | 返回所有兄弟元素 |
add() | 把 add 匹配的选择器的元素添加到当前 jquery 对象 |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
div, span, p {
width: 140px;
height: 140px;
margin: 5px;
background: #aaa;
border: #000 1px solid;
float: left;
font-size: 17px;
font-family: Verdana;
}
div.mini {
width: 55px;
height: 55px;
background-color: #aaa;
font-size: 12px;
}
div.hide {
display: none;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script !src="">
$(function () {
$(document).ready(function() {
function animateIt() {
$("#mover").slideToggle("slow", animateIt);
}
animateIt();
})
//(1)eq() 选择索引值为等于 3 的 div 元素
$("#btn1").click(function(){
$("div").eq(3).css("background-color","#bfa");
});
//(2)first()选择第一个 div 元素
$("#btn2").click(function(){
//first() 选取第一个元素
$("div").first().css("background-color","#bfa");
});
//(3)last()选择最后一个 div 元素
$("#btn3").click(function(){
//last() 选取最后一个元素
$("div").last().css("background-color","#bfa");
});
//(4)filter()在div中选择索引为偶数的
$("#btn4").click(function(){
//filter() 过滤 传入的是选择器字符串
$("div").filter(":even").css("background-color","#bfa");
});
//(5)is()判断#one是否为:empty或:parent
//is用来检测jq对象是否符合指定的选择器
$("#btn5").click(function(){
alert($("#one").is("empty"));
});
//(6)has()选择div中包含.mini的
$("#btn6").click(function(){
//has(selector) 选择器字符串 是否包含selector
$("div").has('.mini').css("background-color","#bfa");
});
//(7)not()选择div中class不为one的
$("#btn7").click(function(){
//not(selector) 选择不是selector的元素
$("div").not(".one").css("background-color","#bfa");
});
//(8)children()在body中选择所有class为one的div子元素
$("#btn8").click(function(){
//children() 选出所有的子元素
$("div").children().css("background-color","#bfa");
});
//(9)find()在body中选择所有class为mini的div元素
$("#btn9").click(function(){
//find() 选出所有的后代元素
$("body").find(".mini").css("background-color","#bfa");
});
//(10)next() #one的下一个div
$("#btn10").click(function(){
//next() 选择下一个兄弟元素
$("#one").next("div").css("background-color","#bfa");
});
//(11)nextAll() #one后面所有的span元素
$("#btn11").click(function(){
//nextAll() 选出后面所有的元素
$("#one").nextAll("span").css("background-color","#bfa");
});
//(12)nextUntil() #one和span之间的元素
$("#btn12").click(function(){
//
$("#one").nextUntil("span").css("background-color","#bfa")
});
//(13)parent() .mini的父元素
$("#btn13").click(function(){
$(".mini").parent().css("background-color","#bfa");
});
//(14)prev() #two的上一个div
$("#btn14").click(function(){
//prev()
$("#two").prev().css("background-color","#bfa")
});
//(15)prevAll() span前面所有的div
$("#btn15").click(function(){
//prevAll() 选出前面所有的元素
$("span").prevAll().css("background-color","#bfa")
});
//(16)prevUntil() span向前直到#one的元素
$("#btn16").click(function(){
//prevUntil(exp) 找到之前所有的兄弟元素直到找到exp停止
$("span").prevUntil("#one").css("background-color","#bfa")
});
//(17)siblings() #two的所有兄弟元素
$("#btn17").click(function(){
//siblings() 找到所有的兄弟元素,包括前面的和后面的
$("#two").siblings().css("background-color","#bfa")
});
//(18)add()选择所有的 span 元素和id为two的元素
$("#btn18").click(function(){
// $("span,#two,.mini,#one")
$("span").add("#two")
.add(".mini").add("#one").css("background-color","#bfa");
});
})
script>
head>
<body>
<input type="button" value="eq()选择索引值为等于 3 的 div 元素" id="btn1" />
<input type="button" value="first()选择第一个 div 元素" id="btn2" />
<input type="button" value="last()选择最后一个 div 元素" id="btn3" />
<input type="button" value="filter()在div中选择索引为偶数的" id="btn4" />
<input type="button" value="is()判断#one是否为:empty或:parent" id="btn5" />
<input type="button" value="has()选择div中包含.mini的" id="btn6" />
<input type="button" value="not()选择div中class不为one的" id="btn7" />
<input type="button" value="children()在body中选择所有class为one的div子元素" id="btn8" />
<input type="button" value="find()在body中选择所有class为mini的div后代元素" id="btn9" />
<input type="button" value="next()#one的下一个div" id="btn10" />
<input type="button" value="nextAll()#one后面所有的span元素" id="btn11" />
<input type="button" value="nextUntil()#one和span之间的元素" id="btn12" />
<input type="button" value="parent().mini的父元素" id="btn13" />
<input type="button" value="prev()#two的上一个div" id="btn14" />
<input type="button" value="prevAll()span前面所有的div" id="btn15" />
<input type="button" value="prevUntil()span向前直到#one的元素" id="btn16" />
<input type="button" value="siblings()#two的所有兄弟元素" id="btn17" />
<input type="button" value="add()选择所有的 span 元素和id为two的元素" id="btn18" />
<h3>基本选择器.h3>
<br /><br />
文本框<input type="text" name="account" disabled="disabled" />
<br><br>
<div class="one" id="one">
id 为 one,class 为 one 的div
<div class="mini">class为minidiv>
div>
<div class="one" id="two" title="test">
id为two,class为one,title为test的div
<div class="mini" title="other"><b>class为mini,title为otherb>div>
<div class="mini" title="test">class为mini,title为testdiv>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">div>
div>
<div class="one">
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini">class为minidiv>
<div class="mini" title="tesst">class为mini,title为tesstdiv>
div>
<div style="display:none;" class="none">style的display为"none"的divdiv>
<div class="hide">class为"hide"的divdiv>
<span id="span1">^^span元素 111^^span>
<div>
包含input的type为"hidden"的div<input type="hidden" size="8">
div>
<span id="span2">^^span元素 222^^span>
<div id="mover">正在执行动画的div元素.div>
body>
html>
方法 | 描述 |
---|---|
html() | 它可以设置和获取起始标签到结束标签中的内容(和DOM innerHtml方法一样) |
text() | 它可以设置和获取起始标签到结束标签中的文本(和DOM innerText方法一样) |
val() | 它可以设置和获取获取表单项的value属性值(和DOM value一样) |
attr() | 可以设置和获取属性的值,不推荐操作checked、readOnly、selected、disabled等等 |
prop() | 可以设置和获取属性的值,只推荐操作checked、readOnly、selected、disabled等等 |
appendTo() | 在被选元素的结尾(仍然在内部)插入指定内容 |
prependTo() | 在被选元素的开头(仍然在内部)插入指定内容 |
insertAfter() | 在被选元素之后插入 HTML 标记或已有的元素 |
insertBefore() | 在您指定的已有子节点之前插入新的子节点 |
replaceWith() | 指定的 HTML 内容或元素替换被选元素 |
replaceAll() | 指定的 HTML 内容或元素替换被选元素(replaceAll() 与 [replaceWith()]作用相同。差异在于语法:内容和选择器的位置,以及replaceWith() 能够使用函数进行替换。) |
remove() | 删除元素 |
empty() | 删除元素的内容 |
方法 | 描述 |
---|---|
addClass() | 向被选元素添加一个或多个类 |
removeClass() | 从被选元素删除一个或多个类 |
toggleClass() | 检查每个元素中指定的类。如果不存在则添加类,如果已设置则删除之 |
offset() | 返回或设置匹配元素相对于文档的偏移(位置) |
示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
div{
width:100px;
height:260px;
}
div.whiteborder{
border: 2px white solid;
}
div.redDiv{
background-color: red;
}
div.blueBorder{
border: 5px blue solid;
}
style>
<script src="../node_modules/jquery/dist/jquery.js">script>
<script >
$(function () {
let $div = $("div:first");
$("#btn01").click(function () {
//向被选元素添加一个或多个类
$div.addClass('redDiv blueBorder')
})
$("#btn02").click(function () {
//从被选元素删除一个或多个类
$div.removeClass();
})
$("#btn03").click(function () {
//对被选元素进行添加/删除类的切换操作
$div.toggleClass('redDiv blueBorder')
})
$("#btn04").click(function () {
//console.log($div.offset());
//返回或设置匹配元素相对于文档的偏移(位置)
$div.offset({
top:50,
left:100
})
})
})
script>
head>
<body>
<table>
<tr>
<td>
<div class="border">
div>
td>
<td>
<div class="btn">
<input type="button" value="addClass()" id="btn01"/>
<input type="button" value="removeClass()" id="btn02"/>
<input type="button" value="toggleClass()" id="btn03"/>
<input type="button" value="offset()" id="btn04"/>
div>
td>
tr>
table>
<br /> <br />
<br /> <br />
body>
html>
方法 | 描述 |
---|---|
show() | 如果被选元素已被隐藏,则显示这些元素 |
hide() | 如果被选的元素已被显示,则隐藏该元素 |
toggle() | 如果被选元素可见,则隐藏这些元素,如果被选元素隐藏,则显示这些元素 |
fadeln() | 方法使用淡入效果来显示被选元素,假如该元素是隐藏的。 |
fadeOut() | 使用淡出效果来隐藏被选元素,假如该元素是隐藏的 |
fadeTo() | 将被选元素的不透明度逐渐地改变为指定的值 |
fadeToggle() | 如果被选元素可见,则淡出这些元素,如果被选元素隐藏,则淡入这些元素 |
以上动画方法都可以添加参数。
1、第一个参数是动画执行的时长,以毫秒为单位
2、第二个参数是动画的回调函数(动画完成后自动调用的函崴)
事件 | 描述 |
---|---|
click() | 它可以绑定单击事件,以及触发单击事件 |
mouseenter() | 鼠标移入事件 |
mouseout() | 鼠标移出事件 |
bind() | 可以给元素一次性绑定一个或多个事件。 |
one() | 使用上跟bind一样。但是one方法绑定的事件只会响应一次。 |
unbind() | 跟bind 方法相反的操作,解除事件的绑定 |
live() | 也是用来绑定事件。它可以用来绑定选择器匹配的所有元素的事件。哪怕这个元素是后面动态创建出来的也有效 |
1.文档声明。
2.元素(标签)
3.xml 属性
4.xml注释
5.文本区域(CDATA区)
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。
XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。
元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。
<bookstore>
<book category="CHILDREN">
<title>Harry Pottertitle>
<author>J K. Rowlingauthor>
<year>2005year>
<price>29.99price>
book>
<book category="WEB">
<title>Learning XMLtitle>
<author>Erik T. Rayauthor>
<year>2003year>
<price>39.95price>
book>
bookstore>
在上例中, 和 都拥有元素内容,因为它们包含了其他元素。 只有文本内容,因为它仅包含文本。
在上例中,只有 元素拥有属性 (category=“CHILDREN”)。
示例:
book类
package com.atguigu.pojo;
import java.math.BigDecimal;
public class Book {
private String sn;
private String name;
private BigDecimal price;
private String author;
public Book() {
}
public Book(String sn, String name, BigDecimal price, String author) {
this.sn = sn;
this.name = name;
this.price = price;
this.author = author;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"sn='" + sn + '\'' +
", name='" + name + '\'' +
", price=" + price +
", author='" + author + '\'' +
'}';
}
}
books.xml文件
<books>
<book sn="SN1000001">
<name>荒野大镖客Ⅱname>
<price>399price>
<author>R星author>
book>
<book sn="SN1000002">
<name>刺客信条起源name>
<price>299price>
<author>育碧author>
book>
books>
dom4j解析xml文件
package com.atguigu.pojo;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.List;
public class Dom4jTest {
@Test
public void test1(){
//创建一个SAXReader输入流,去读取xml配置文件,生成Document对象
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read("src/books.xml");
System.out.println(document);
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 读取books.xml文件生成Book类
*/
@Test
public void Test2() throws DocumentException {
//1.读取books.xml文件
SAXReader saxReader = new SAXReader();
//2.通过Document对象获取根元素
Document document = saxReader.read("src/books.xml");
//3.通过根元素获取book标签对象
Element rootElement = document.getRootElement();
//4.遍历,处理每个book标签转换为Book类
List books = rootElement.elements("book");
for (Element book : books){
//asXML();把标签对象,转换为标签字符串
Element nameElement = book.element("name");
//getText();可以获取标签的文本内容
String nameText = nameElement.getText();
//elementText();直接获取指定标签的文本内容
String priceText = book.elementText("price");
String authorTest = book.elementText("author");
String snValue = book.attributeValue("sn");
System.out.println(new Book(snValue,nameText,new BigDecimal(priceText),authorTest));
}
}
}
Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web[服务端]和web[客户端]两部分。Java在客户端的应用有Java Applet,不过[使用]得很少,Java在[服务器端]的应用非常的丰富,比如[Servlet],[JSP]、第三方[框架]等等。Java技术对Web领域的发展注入了强大的动力。
JavaWeb是指,所有通过Java语言编写可以通过浏览器访问的程序的总称,叫JavaWeb
JavaWeb是基于请求和响应来开发的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrMYFnYX-1647142931683)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211220164233838.png)]
**静态资源:**html、css、JavaScript、txt、mp4、jpg 等
**动态资源:**JSP、Servlet程序
Tomcat:由Apache组织提供的一种web服务器,提供对 jsp和servlet的支持。它是一种轻量级的javaweb容器(服务器),也是当前应用最广的JavaWeb服务器〈免费〉。
Jboss:是一个遵从JavaEE规范的、开放源代码的、纯Java的EJ服务器,它支持所有的JavaEE规范(免费〉。
GlassFish: 由Oracle公司开发的一款JavaWeb服务器,是一款强健的商业服务器,达到产品级质量〈(应用很少)
Resin:是cAUCHO公司的产品,是一个非常流行的服务器,对servlet和JSP提供了良好的支持,性能也比较优良,resin自身采用JAVA语言开发(收费,应用比较多)。
webLogic:是oracle公司的产品,是目前应用最广泛的Web服务器,支持JavaEE规范,而且不断的完善以适应新的开发要求,适合大型项目(收费,用的不多,适合大公司)。
只需要把Web工程的目录拷贝到Tomcat的webapps目录即可
1.在webapps目录下创建项目工程文件夹
2.将文件拷贝到目录下即可
访问方式http://ip地址:端口号/路径/文件名.xxx
找到在 tomcat 下的\conf\Catalina\localhost 下新建一个.xml配置文件
.xml配置文件书写格式:
<Context path="/abc" docBase="I:\Wed\crm"/>
访问方式http://ip地址:端口号/工程名/路径/文件名.xxx
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFyf71Dc-1647142931684)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211220183631266.png)]
idea2021.3创建web项目步骤:https://www.jianshu.com/p/696211853dbe
Web动态工程目录介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CZ6kr2E2-1647142931685)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211221124150170.png)]
1、编写一个类去实现Servlet接口
2、实现service方法,处理请求,并响应数据
3、到web.xml中去配置servlet程序的访问地址
实现类:
package com.atguigu.servlet;
import javax.servlet.*;
import java.io.IOException;
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello servlet 已被访问!");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
访问地址配置:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>HelloServletservlet-name>
<servlet-class>com.atguigu.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
web-app>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YA5HYssl-1647142931685)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211221144442023.png)]
1、执行Servlet构造方法
2、执行init初始化方法
第一,第二步:是在第一次访问的时候创建Servlet程序会调用
3、执行service方法
第三步:每次访问都会调用
4、执行destroy销毁方法
第四步:Web工程停止的时候调用
一般实际项目开发中,都是继承HttpServlet类的方式去实现Servlet程序
1、编写一个类继承 HttpServlet类
2、根据业务需求重写doGet、doPost方法
3、到web.xml配置Servlet的访问地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YyTYiT5u-1647142931686)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211221175900607.png)]
ServletConfig类是Servlet程序的配置信息类
Servlet程序和ServletConfig对象是由Tomcat负责创建,我们负责使用
Servlet程序默认是第一次访问的时候创建,ServletConfig是每个程序创建时,就创建一个对应的ServleyConfig对象
ServletConfig类的三大作用
ServletConfig示例:
package com.atguigu.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println("1.构造函数");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2.初始化方法");
// - 1.可以获取Servlet的别名servlet-name的值
System.out.println("HelloServlet程序的别名" + servletConfig.getServletName());
// - 2.获取初始化参数init-param
System.out.println("初始化参数username的值" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值" + servletConfig.getInitParameter("url"));
// - 3.获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//类型转换(因为servletRequest有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
//获取请求的方式
String method = httpServletRequest.getMethod();
if (method.equals("POST")){
doPost();
}else {
doGet();
}
}
/**
* 做get请求的操作
*/
public void doGet(){
System.out.println("3.get 请求 service == hello servlet 已被访问!");
}
/**
* 做post请求的操作
*/
public void doPost(){
System.out.println("3.post 请求 service == hello servlet 已被访问!");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4.destroy销毁方法");
}
}
web.xml配置文件
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>HelloServletservlet-name>
<servlet-class>com.atguigu.servlet.HelloServletservlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>rootparam-value>
init-param>
<init-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql//127.0.0.1:3306/bjpowernodeparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet>
<servlet-name>HelloServlet2servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServlet2servlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
<servlet>
<servlet-name>HelloServlet3servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet3servlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServlet3servlet-name>
<url-pattern>/hello3url-pattern>
servlet-mapping>
web-app>
1、ServletContext是一个接口,它表示上下文对象
2、一个Web工程,只有一个ServletContext对象实例
3、ServletContext对象是一个域对象
4、ServletContext是在web工程启动的时候创建,在web工程停止的时候销毁
什么是域对象?
域对象,是可以像Map一样存储数据的对象,叫域对象。
这里的域指的是存储数据的操作范围
存数据 取数据 删除数据
-----------------------------------------------------------------
Map put() get() remove()
-----------------------------------------------------------------
域对象 setAttrlbute() getAttrlbute() removeAttrlbute()
ServletContext类的四个作用
1、获取web.xml中配置的上下文参数 context-paran
2、获取当前工程的路径,格式:/工程路径
3、获取工程部署在服务器硬盘上的绝对路径
4、像Map一样存储数据
示例:
package com.atguigu.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class ContextServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、获取web.xml中配置的上下文参数 context-paran
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("username的值是" + username);
String password = context.getInitParameter("password");
System.out.println("password的值是" + password);
//2、获取当前工程的路径,格式:/工程路径
String contextPath = context.getContextPath();
System.out.println("获取当前工程路径" + contextPath);
//3、获取工程部署在服务器硬盘上的绝对路径
/**
* /斜杠被服务器解析的地址为:http://ip:port/工程名/ 映射到IDEA代码的web目录
*/
String realPath = context.getRealPath("/");
System.out.println("获取当前工程部署的路径" + realPath);
System.out.println("获取当前工程部署的css目录的绝对路径" + context.getRealPath("/css"));
System.out.println("获取当前工程部署的yun.jpg的绝对路径" + context.getRealPath("/images/yun.jpg"));
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
web.xml配置文件
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>usernameparam-name>
<param-value>adminparam-value>
context-param>
<context-param>
<param-name>passwordparam-name>
<param-value>rootparam-value>
context-param>
<servlet>
<servlet-name>HelloServletservlet-name>
<servlet-class>com.atguigu.servlet.HelloServletservlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>rootparam-value>
init-param>
<init-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql//127.0.0.1:3306/bjpowernodeparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet>
<servlet-name>HelloServlet2servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServlet2servlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
<servlet>
<servlet-name>HelloServlet3servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet3servlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServlet3servlet-name>
<url-pattern>/hello3url-pattern>
servlet-mapping>
<servlet>
<servlet-name>ContextServletservlet-name>
<servlet-class>com.atguigu.servlet.ContextServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>ContextServletservlet-name>
<url-pattern>/ContextServleturl-pattern>
servlet-mapping>
web-app>
什么是Http协议
协议是指双方,或多方相互约定,大家需要遵守的规则,叫协议。
所谓Http协议,就是指,客户端与服务器之间通信时,发送的数据,需要遵守的规则,叫Http协议。
Http协议中的数据又叫报文
客户端给服务器发送数据叫请求
服务器给客户端回传数据叫响应
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SF6HTrLz-1647142931686)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224122946413.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cf5hU2Qh-1647142931687)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224124228227.png)]
**Accept:**表示客户端可以接收的数据类型
**Accept-Language:**表示客户端可以接收的语言类型
**Host:**表示请求时的服务器IP和端口号
GET请求有哪些
1、form标签 method = get
2、a标签
3、link标签引入css样式
4、script标签引入js文件
5、img标签引入图片
6、iframe引入html页面
7、在浏览器地址栏输入地址后敲回车
POST请求有哪些
1、form标签 method = post
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2N5GDJ2q-1647142931687)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224150629730.png)]
200 表示请求成功
302 表示请求重定向
404 表示请求服务器已收到,但你要的数据不存在(请求地址错误)
500 表示服务器已收到请求,但是服务器内部错误(代码错误)
MIME是HTTP协议中数据类型。
MIME的英文全称是"Mutipurpose Internet Mail Extensions”多功能Internet邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LmvqjpyO-1647142931688)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211224230352017.png)]
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的Http协议信息解析好封装到Request对象中。然后传递到service方法(doGet和doPost)中给我们使用,我们可以通过HttpServletRequest对象,获取到所有请求的信息。
方法 | 描述 |
---|---|
getRequestURI() | 获取请求资源路径 |
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
getRemoteHost() | 获取客户端的IP地址 |
getHeader() | 获取请求头 |
getMethod() | 获取请求的方式GET或POST |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数(获取多个值的时候使用) |
setCharacterEncoding() | 设置请求体的字符集(从而解决post请求的中文乱码问题) |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K9QK83Hu-1647142931688)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211225185052078.png)]
请求转发的特点:
示例:
Servlet1
package com.atguigu.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料):" + username);
//给材料盖一个章,并传递到Servlet2去(柜台2)
req.setAttribute("key","柜台1的章");
//问路Servlet怎么走
/**
* 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/资源名 , 映射到IDEA代码的web目录
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/Servlet2");
//访问WEB-INF目录下的form.html文件
// RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/form.html");
//走向柜台2
requestDispatcher.forward(req,resp);
}
}
Servlet2
package com.atguigu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料):" + username);
//查看柜台1是否有盖章
Object key = req.getAttribute("key");
System.out.println("柜台1是否有章:" + key);
System.out.println("Servlet2处理自己的业务");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cBdtXuNE-1647142931688)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211228164231746.png)]
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base href="http://localhost:8080/07_servlet/a/b/">
head>
<body>
这是 a 下的 b 下的 c.html 页面<br/>
<a href="../../index.html">跳回首页a><br/>
body>
html>
在 javaWeb 中,路径分为相对路径和绝对路径两种:
相对路径是:
绝对路径: http://ip:port/工程路径/资源路径
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。
1、绝对路径
2、base+相对
14.6 web 中 / 斜杠的不同意义
在 web 中 / 斜杠 是一种绝对路径。
/ 斜杠 如果被浏览器解析,得到的地址是:http://ip:port/
<a href="/">斜杠a>
/ 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径
1、<url-pattern>/servlet1url-pattern>
2、servletContext.getRealPath(“/”);
3、request.getRequestDispatcher(“/”);
特殊情况: response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到 http://ip:port
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传 递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息, 我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse 对象来进行设置
字节流 getOutputStream(); 常用于下载(传递二进制数据)
字符流 getWriter(); 常用于回传字符串(常用)
注意:
两个流只能使用一个。
使用了字节流,就不能使用字符流,反之亦然,否则报错
示例:
package com.atguigu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//-------------方法一
//设置服务器字符集UTF-8
resp.setCharacterEncoding("UTF-8");
//通过响应头 设置浏览器字符集UTF-8
resp.setHeader("content-Type","text/html;charset=UTF-8");
//-------------方法二
// 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html;charset=UTF-8");
//往客户端回传 字符串 数据
PrintWriter writer = resp.getWriter();
writer.write("张二狗");
}
}
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说,我给你一些地址,你去访问新的地址,叫请求重定向(因为之前的地址可能已经废弃)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PIG47CNO-1647142931689)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211229180235416.png)]
//请求重定向的第一种方案:
// 设置响应状态码 302 ,表示重定向,(已搬迁)
resp.setStatus(302);
// 设置响应头,说明 新的地址在哪里
resp.setHeader("Location", "http://localhost:8080");
//请求重定向的第二种方案(推荐使用):
resp.sendRedirect("http://localhost:8080");
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-njPZ1Uo8-1647142931689)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211229191216462.png)]
JSP的全称是 (Java Server Pages) Java的服务器页面
JSP的主要作用是代替Servlet程序回传html页面的数据
因为Servlet程序回传html页面数据是极其繁琐的事情,开发和维护成本极高
jsp的本质上是一个Servlet程序
当我们第一次访问jsp页面的时候,tomcat服务器会帮我们把jsp页面翻译成为一个Java源文件,并且对它进行编译成为.class字节码文件程序。打开Java源文件不难发现其里面的内容是:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T5Z64QLW-1647142931690)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220101153953673.png)]
跟踪源码发现,HttpJspBase类,它直接继承了HttpServlet类,也就是说,jsp翻译出来的类,它简介继承HttpServlet类,也就是说,翻译出来的是一个Servlet程序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WfvPee6U-1647142931690)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220101155407543.png)]
总结:通过翻译的 java 源代码我们就可以得到结果:jsp 就是 Servlet 程序。 可以去观察翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传 给客户端
jsp的page指令可以修改jsp页面中一些重要的属性,或者行为。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--language 属性 表示jsp翻译后是什么语言文件,暂时只支持Java--%>
<%--contentType 属性 表示jsp返回的数据类型是什么,也是源码中的中 response.setContentType()参数值--%>
<%--pageEnconding 属性 表示当前jsp页面文件本身的字符集--%>
<%--import 属性 跟Java源代码一样,用于导包,导类--%>
<%--=================================================两个属性是给out输出流使用===================================================--%>
<%--autoFlush 属性 设置当out输出流缓冲区满了之后,是否自动刷新冲级区。默认值是true--%>
<%--buffer 属性 设置out缓冲区的大小,默认是8kb--%>
<%--========================================================================================================================--%>
<%--errorPage 属性 设置jsp页面运行出错时,自动跳转去的错误页面路径--%>
<%-- isErrorPage 属性 设置当前 jsp 页面是否是错误信息页面。默认是 false。如果是 true 可以获取异常信息--%>
<%--session 属性 设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true。--%>
<%--extends 属性 设置 jsp 翻译出来的 java 类默认继承谁--%>
声明脚本的格式:<%! 声明Java代码 %>
作用:可以给jsp翻译出来Java类定义的属性和方法甚至是静态代码块,内部类等。
示例:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/1
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
这是html页面!!!
<%-- 声明类属性 --%>
<%!
private Integer id;
private String name;
private static Mapmap;
%>
<%-- 声明静态代码块 --%>
<%!
static {
map = new HashMap<>();
map.put("猿1","val1");
map.put("猿2","val2");
map.put("猿3","val3");
}
%>
<%-- 声明类方法 --%>
<%!
public int add(){
return 1;
}
%>
<%-- 声明内部类 --%>
<%!
public static class A{
private int id = 12;
private String name = "张二狗";
}
%>
jsp运行生成的Java源码文件
private Integer id;
private String name;
private static Map<String, Object>map;
static {
map = new HashMap<>();
map.put("猿1","val1");
map.put("猿2","val2");
map.put("猿3","val3");
}
public int add(){
return 1;
}
public static class A{
private int id = 12;
private String name = "张二狗";
}
表达式脚本格式:<%= 表达式 %>
表达式脚本的作用:在jsp页面上输出数据。
表达式脚本的特点:
示例:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/1
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
这是html页面!!!
<%-- 声明类属性 --%>
<%!
private Integer id = 12;
private String name = "hello";
private static Mapmap;
%>
<%-- 声明静态代码块 --%>
<%!
static {
map = new HashMap<>();
map.put("猿1","val1");
map.put("猿2","val2");
map.put("猿3","val3");
}
%>
<%-- 声明类方法 --%>
<%!
public int add(){
return 1;
}
%>
<%-- 声明内部类 --%>
<%!
public static class A{
private int id = 12;
private String name = "张二狗";
}
%>
<%--
1. 输出整型
2. 输出浮点型
3. 输出字符串
4. 输出对像
--%>
<%=12%>
<%=12.21%>
<%="张二狗"%>
<%=map%>
<%=id%>
<%=name%>
脚本格式:<% Java语句 %>
代码脚本的作用是:可以在jsp页面中,编写我们自己需要的功能(写的是Java语句)
代码脚本的特点:
示例:
<%@ page import="java.util.HashMap" %>
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/1
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--2.代码脚本----for 循环语句--%>
<%
for (int i = 1 ; i < 10 ; i++){
%>
<%=i%>
<%
}
%>
<%--3.翻译后java文件中_jspService方法内的代码都可以写--%>
<%
String username = request.getParameter("username");
System.out.printf(username);
%>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3FwhpSRI-1647142931690)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220102163237447.png)]
request 请求对象
response 响应对象
pageContext jsp的上下文对象
session 会话对象
application ServletContext对象
config ServletConfig对象
out jsp输出流对象
page 指向当前的jsp对象
exception 异常对象
pageContext (PageContextImol类) 当前jsp页面范围内有效
request (HttpServletRequest类) 一次请求内有效
session (HttpSessino类) 一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)
application (ServletContext类) 整个web工程范围内有效(只要web工程不停止,数据还在)
response中表示响应,我们经常用于设置返回客户端的内容(输出)
out也是给用户做输出使用的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b65dC411-1647142931691)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220103182545735.png)]
由于jsp翻译之后,底层源码都是使用out来进行输出,所以一般情况下,我们在jsp页面中统一使用out来进行输出,避免打乱页面输出的内容的顺序
out.write()输出字符串没有问题
out.print()输出任意数据都没有问题(都会转换成字符串后调用的write输出)
深入源码,浅出结论:在jsp页面中,可以统一使用out.print()来进行输出
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/3
Time: 18:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--
<%@ include file="" %> 就是静态包含
file 属性指定你要包含的jsp页面的路径
地址中的第一个斜杠 / 表示:http://ip:prot/工程路径/映射到代码的web目录
静态包含特点:
1.静态包含不会翻译被包含的jsp页面
2.静态包含其实是把被包含的jsp页面的jsp页面的代码拷贝到包含的位置执行输出
--%>
头部
主体
<%@ include file="/include/footer.jsp" %>
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/3
Time: 18:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--
page 属性指定你要包含的jsp页面的路径
地址中的第一个斜杠 / 表示:http://ip:prot/工程路径/映射到代码的web目录
动态包含特点:
1.动态包含会把包含的jsp页面也翻译成Java代码
2.动态包含底层代码使用如下代码去调用被包含的jsp页面执行输出。
JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false)
3.动态包含,还可以传递参数
--%>
头部
主体
动态包含的底层实现原理:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hDVHrJre-1647142931691)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220103192828863.png)]
<%--
是请求转发标签,它的功能就是请求转发
page 属性设置请求转发的路径
--%>
乘法口诀示例一:
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/3
Time: 20:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
for (int i = 1; i <= 9; i++) {%>
<%
for (int j = 1; j <= i; j++) {
%>
<%= j + "x" + i + "=" + (i * j)%>
<%
}
%>
<%
}
%>
输出一个表格,里面有 10 个学生信息示例二:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ez9w8ZeJ-1647142931692)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220109163331550.png)]
student类
package com.chan;
public class Student {
private int id;
private String name;
private int age;
private int phone;
//省略get、set、构造函数、toString方法
}
SearchStudentServlet类
package com.chan.servlet;
import com.chan.Student;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SearchStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求的参数
// 发 sql 语句查询学生的信息
// 使用 for 循环生成查询到的数据做模拟
List<Student> studentList = new ArrayList<>();
for (int i = 0 ; i < 10 ; i++){
int t = i + 1;
studentList.add(new Student(t,"name"+ t,10+t,185774565+t));
}
// 保存查询到的结果(学生信息)到 request 域中
req.setAttribute("studentList",studentList);
// 请求转发到 showStudent.jsp 页
req.getRequestDispatcher("/Test/showStudent.jsp").forward(req,resp);
}
}
showStudent.jsp页面
<%@ page import="java.util.List" %>
<%@ page import="com.chan.Student" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/3
Time: 21:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--获取保存在域中的数据--%>
<%
List studentList = (List)request.getAttribute("studentList");
%>
学号
名字
年龄
联系方式
操作
<%
for (Student student : studentList) {
%>
<%=student.getId()%>
<%=student.getName()%>
<%=student.getAge()%>
<%=student.getPhone()%>
删除
修改
<%
}
%>
ServletContextListener它可以监听ServletContext对象的创建和销毁
ServletContext对象在web工程启动的时候创建,在web工程停止时销毁
监听到创建和销毁之后都会分别调用ServletContextListener监听器的方法进行反馈。
两个方法分别是:
package javax.servlet;
import java.util.EventListener;
public interface ServletContextListener extends EventListener {
/*
*在ServletContext对象创建之后马上调用,做初始化
*/
void contextInitialized(ServletContextEvent var1);
/*
*在ServletContext对象销毁之后马上调用
*/
void contextDestroyed(ServletContextEvent var1);
}
如何使用ServletContextListener监听器监听ServletContext对象
使用步骤如下:
编写一个类实现ServletContextLisetener => 实现两个回调函数 => web.xml中配置监听器
实现类MyServletContextListenerImpl
package com.chan.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListenerImpl implements ServletContextListener {
//实现两个回调函数
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.printf("ServletContext对象被创建了------------------------------>>>");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.printf("ServletContext对象被销毁了------------------------------>>>");
}
}
web.xml中配置监听器
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<listener>
<listener-class>com.chan.listener.MyServletContextListenerImpllistener-class>
listener>
web-app>
EL表达式的全称是:Experssion Language,是表达式语言
EL表达式的作用:EL表达式作用主要代替jsp页面中的表达式脚本在jsp页面中进行数据的输出
因为EL表达式在输出数据的时候,要比jsp的表达式脚本要简洁
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/9
Time: 17:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
request.setAttribute("key1","");
%>
<%=request.getAttribute("key") == null ? "" : request.getAttribute("key1")%>
${key}
EL 表达式的格式是:${表达式}
EL 表达式在输出 null 值的时候,输出的是空串。jsp 表达式脚本输出 null 值的时候,输出的是 null 字符串
EL表达式主要是是在jsp页面输出数据
主要输出的是域对象中的数据
当四个域中都相同的key的数据的时候,EL表达式会按照从小到大的顺序去进行搜索,找打就输出
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/9
Time: 18:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%-- 往四个域中保存相同的key数据 --%>
<%
request.setAttribute("key","request");
session.setAttribute("key","session");
application.setAttribute("key","application");
pageContext.setAttribute("key","pageContext");
%>
${key}
需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性
package com.chan;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Person {
private String name;
private String[] phones;
private List cities;
private Map map;
private int age = 100;
//省略get、set、构造函数、toString方法
}
3.jsp输出的代码:
<%@ page import="com.chan.Person" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/9
Time: 18:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
Person person = new Person();
person.setName("张二狗");
person.setPhones(new String[]{"1857745874","184655412545","48216485184"});
List stringList = new ArrayList<>();
stringList.add("南宁");
stringList.add("广州");
stringList.add("上海");
person.setCities(stringList);
Map map = new HashMap<>();
map.put("key1",12341);
map.put("key2",12342);
map.put("key3",12343);
map.put("key4",12344);
person.setMap(map);
pageContext.setAttribute("p",person);
%>
输出person:${p}
输出person的name属性:${p.name}
输出person的phones数组属性:${p.phones[0]}
输出 Person 的 cities 集合中的元素值:${p.cities}
输出 Person 的 List 集合中个别元素值:${p.cities[0]}
输出 Person 的 Map 集合: ${p.map}
输出 Person 的 Map 集合中某个 key 的值: ${p.map.key2}
输出 Person 的 age 属性:${p.age}
语法:${运算表达式},EL表达式支持如下运算符:
关系运算符 | 说明 |
---|---|
== 或 eq | 等于 |
!= 或 ne | 不等于 |
< 或 lt | 小于 |
> 或 gt | 大于 |
<= 或 le | 小于等于 |
>= 或 ge | 大于等于 |
逻辑运算符 | 说明 |
---|---|
&& 或 and | 与 |
|| 或 or | 或 |
! 或 not | 取反 |
算数运算符 | 说明 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ 或 div | 除法 |
% 或 mod | 取模 |
示例:
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/9
Time: 19:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
关系运算:
${12 == 12} 或 ${12 eq 12}
${12 != 12} 或 ${12 ne 12}
${12 < 12} 或 ${12 lt 12}
${12 > 12} 或 ${12 gt 12}
${12 <= 12} 或 ${12 le 12}
${12 >= 12} 或 ${12 ge 12}
逻辑运算:
${12 == 12 && 12 == 12} 或 ${12 == 12 and 12 == 12}
${12 != 12 || 12 > 12} 或 ${12 != 12 || 12 > 12}
${!true} 或 ${not true}
算数运算:
${12 + 12}
${12 - 12}
${12 * 12}
${12 / 12} 或 ${12 div 12}
${15 % 12} 或 ${15 mod 12}
empty运算可以判断一个数据是否为空,如果为空,则输出true,不为空则输出false
以下几种情况为空:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/9
Time: 19:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
//值为null值的时候,为空
request.setAttribute("emptyNull",null);
//值为空串的时候,为空
request.setAttribute("emptyStr","");
//值是 Object 类型数组,长度为零的时候
request.setAttribute("emptyArr",new Object[]{});
//list 集合,元素个数为零
List list = new ArrayList<>();
request.setAttribute("emptyList",list);
//map 集合,元素个数为零
Map map = new HashMap<>();
request.setAttribute("emptyMap",map);
%>
${empty emptyNull}
${empty emptyStr}
${empty emptyArr}
${empty emptyList}
${empty emptyMap}
表达式一 ? 表达式二 : 表达式三
如果表达式 1 的值为真,返回表达式 2 的值,如果表达式 1 的值为假,返回表达式 3 的值
${12 == 12 ? "对的" : "假的"}
.运算,可以输出Bean对象中某个属性的值
[]中括号运算,可以输出有序集合中某个元素的值
并且中括号运算,还可以输出map集合中key里含有特殊字符的key的值
EL表达式中11个隐含对象,是EL表达式中自己定义的,可以直接使用
变量 | 类型 | 作用 |
---|---|---|
pageContext | PageContextimpl | 它可以获取jsp中的九大内置对象 |
pageScope | Map |
它可以获取pageContext域中的数据 |
requestScope | Map |
它可以获取Request域中的数据 |
sessionScope | Map |
它可以获取Session域中的数据 |
applicationScope | Map |
它可以获取ServletContext域中的数据 |
param | Map |
它可以获取请求参数的值 |
paramValues | Map |
它可以获取请求参数的值,获取多个值的时候使用 |
header | Map |
它可以获取请求头的信息 |
headerValues | Map |
它可以获取请求头的信息,获取多个请求头的时候使用 |
cookie | Map |
它可以获取当前请求的Cookie信息 |
initParam | Map |
它可以获取在web.xml中配置的上下文参数 |
获取四大域对象示例:
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/10
Time: 16:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
pageContext.setAttribute("key1","pageContext");
pageContext.setAttribute("key2","pageContext");
request.setAttribute("key2","request");
session.setAttribute("key2","session");
application.setAttribute("key2","application");
%>
${applicationScope.key2}
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/10
Time: 16:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--
request.getScheme(); 获取请求的协议
request.getServerName(); 获取服务器的IP或域名
request.getServerProt(); 获取服务器的请求端口号
request.getContextpath(); 获取当前的工程路径
request.getMethod(); 获取请求方式
request.getRemoteHost(); 获取客户端的IP地址
session.getID(); 获取会话的唯一标识
--%>
<%
pageContext.setAttribute("req",request);
%>
<%=request.getServerPort()%>
1.协议:${req.scheme}
2.服务器IP:${req.serverName}
3.服务器端口号:${req.serverPort}
4.工程路径:${req.contextPath}
5.请求方式:${req.method}
6.客户端ip:${req.remoteHost}
7.会话唯一标识:${req.session.id}
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/10
Time: 17:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
输出请求参数username的值:${param.username}
输出请求参数password的值:${param.password}
输出请求参数username的值:${paramValues.username[0]}
输出请求参数hobby的值:${paramValues.hobby[0]}
输出请求参数hobby的值:${paramValues.hobby[1]}
输出请求头【User-Agent】的值:${header['User-Agent']}
输出请求头【Connection】的值:${header.Connection}
输出请求头【User-Agent】的值:${headerValues['User-Agent'][0]}
获取Cookie的名称:${cookie.JSESSIONID.name}
获取Cookie的值:${cookie.JSESSIONID.value}
输出<Context-param>username的值:${initParam.username}
输出<Context-param>url的值:${initParam.password}
JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP 标 签库。
EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面 变得更佳简洁
JSTL由五个不同功能的标签库组成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-deoLhjPM-1647142931692)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220110175121020.png)]
在 jsp 标签库中使用 taglib 指令引入标签库
CORE 标签库
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
XML 标签库
<%@ taglib prefix=“x” uri=“http://java.sun.com/jsp/jstl/xml” %>
FMT 标签库
<%@ taglib prefix=“fmt” uri=“http://java.sun.com/jsp/jstl/fmt” %>
SQL 标签库 <%@ taglib prefix=“sql” uri=“http://java.sun.com/jsp/jstl/sql” %>
FUNCTIONS 标签库
<%@ taglib prefix=“fn” uri=“http://java.sun.com/jsp/jstl/functions” %>
JSTL 标签库的使用步骤
1、先导入 jstl 标签库的 jar 包。 taglibs-standard-impl.jar taglibs-standard-spe.jar
2、第二步,使用 taglib 指令引入标签库。 <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
示例:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="C" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/10
Time: 18:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%---------------------------------------------------------------- ---------------------------------------%>
<%--
作用:set标签可以往域中保存数据
域对象.setAttribute(key,value)
scope 属性设置保存到那个域
page表示pageContext域(默认值)
request表示Request域
session表示Session域
application表示ServletContext域
var属性设置key的值
value属性设置value的值
--%>
保存前:${sessionScope.abc}
保存后:${sessionScope.abc}
<%---------------------------------------------------------------- ---------------------------------------%>
<%--
if标签用来做if判断
test属性表示判断的条件(使用EL表达式输出)
--%>
12等于12
12不等于12
<%--
作用多路判断,跟switch...case...default非常接近
choose标签开始选择判断
when标签表示每一种的判断条件
otherwise标签表示when之外的条件
注意:
1.标签内不能使用html注释,要使用jsp注释
2.when标签的父标签一定要是choose标签
--%>
<%request.setAttribute("key",171);%>
身高:${requestScope.key}
一般
还行
正常
平均水平
forEach示例:
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="com.chan.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/12
Time: 23:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--
遍历1到10,输出
begin属性设置开始的索引
end 属性设置结束的索引
var 属性表示循环的变量(也是当前正在遍历到的数据)
for (int i = 1; i < 10; i++)
--%>
${i}
<%--
遍历Object数组
for (Object item: arr)
items 表示遍历的数据源(遍历的集合)
var 表示当前遍历到的数据
--%>
<%request.setAttribute("arr",new String[]{"18610541354","18688886666","18699998888"});%>
${item}
<%
Map map = new HashMap<>();
map.put("map1",1234561);
map.put("map2",1234562);
map.put("map3",1234563);
map.put("map4",1234564);
request.setAttribute("map",map);
%>
${maps}
${maps.key} --------- ${maps.value}
<%--
遍历List集合---list中存放 Student类,有属性:编号,用户名,密码,年龄,电话信息
--%>
<%
List studentList = new ArrayList<>();
for (int i = 1 ; i <= 10 ; i++ ){
studentList.add(new Student(00+i,"name" + i, 18 + i ,1857745497+i));
}
request.setAttribute("students",studentList);
%>
编号
名字
年龄
电话
操作
<%--
items 表示遍历的集合
var 表示遍历到的数据
begin表示遍历的开始索引值
end 表示结束的索引值
step 属性表示遍历的步长值
varStatus 属性表示当前遍历到的数据的状态
for(int i = 1; i < 10; i+=2)
--%>
${student.id}
${student.name}
${student.age}
${student.phone}
编辑
删除
文件的上传和下载,是非常常见的功能。很多的系统中,或者软件中都经常使用文件的上传和下载。 比如:QQ 头像,就使用了上传。 邮箱中也有附件的上传和下载功能。 OA 系统中审批有附件材料的上传
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N5BjTNWw-1647142931692)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220114182312182.png)]
commons-fileupload.jar 需要依赖 commons-io.jar 这个包,所以两个包我们都要引入
commons-fileupload.jar 和 commons-io.jar 包中,我们常用的类有哪些
fileupload和io类 | 描述 |
---|---|
ServletFileUpload类 | 用于解析上传的数据 |
FileItem类 | 表示每一个表单项 |
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request) | 判断当前上传的数据格式是否是多段的格式 |
public List parseRequest(HttpServletRequest request) | 解析上传的数据 |
boolean FileItem.isFormField() | 判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。 true 表示普通类型的表单项 false 表示上传的文件类型 |
String FileItem.getFieldName() | 获取表单项的 name 属性值 |
String FileItem.getString() | 获取当前表单项的值。 |
String FileItem.getName() | 获取上传的文件名 |
void FileItem.write( file ) | 将上传的文件写到 参数 file 所指向硬盘位置 |
文件上传示例:
servlet处理程序
package com.chan.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class UploadServlet extends HttpServlet {
/**
* 用来处理上传的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.先判断上传的数据是否是多段数据(只有多段数据才是文件上传)
if (ServletFileUpload.isMultipartContent(req)){
//创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
//创建用于解析上传数据的工具类ServletUpload类
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
try {
//解析上传的数据,得到每一个表单项FileItem , FileItem 表示每一个表单项
List list = servletFileUpload.parseRequest(req);
// 循环判断,每一个表单项,是普通类型,还是上传的文件
for (FileItem fileItem : list){
if (fileItem.isFormField()){
//普通表单项
System.out.println("表单项的name属性值:" + fileItem.getFieldName());
//参数UTF-8,解决乱码问题
System.out.println("表单项的value值:" + fileItem.getString("UTF-8"));
}else {
//上传的文件
System.out.println("表单项的name属性值:" + fileItem.getFieldName());
System.out.println("上传的文件名:" + fileItem.getName());
//将上传的文件写入硬盘
fileItem.write(new File("i:\\" + fileItem.getName()));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
jsp上传文件数据
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/14
Time: 17:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
下载的常用 API 说明:
response.getOutputStream();
servletContext.getResourceAsStream();
servletContext.getMimeType();
response.setContentType();
response.setHeader(“Content-Disposition”, “attachment; fileName=1.jpg”); 这个响应头告诉浏览器。这是需要下载的。而 attachment 表示附件,也就是下载的一个文件。fileName=后面, 表示下载的文件名。 完成上面的两个步骤,下载文件是没问题了。但是如果我们要下载的文件是中文名的话。你会发现,下载无法正确 显示出正确的中文名。 原因是在响应头中,不能包含有中文字符,只能包含 ASCII
方案一:URLEncoder 解决 IE 和谷歌浏览器的 附件中 文名问题。
如果客户端浏览器是 IE 浏览器 或者 是谷歌浏览器。我们需要使用 URLEncoder 类先对中文名进行 UTF-8 的编码 操作。 因为 IE 浏览器和谷歌浏览器收到含有编码后的字符串后会以 UTF-8 字符集进行解码显示。
// 把中文名进行 UTF-8 编码操作。
String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
// 然后把编码后的字符串设置到响应头中
response.setHeader("Content-Disposition", str);
方案二:BASE64 编解码 解决 火狐浏览器的附件中文名问题
如果客户端浏览器是火狐浏览器。 那么我们需要对中文名进行 BASE64 的编码操作。
这时候需要把请求头 Content-Disposition: attachment; filename=中文名
编码成为:Content-Disposition: attachment; filename==?charset?B?xxxxx?=
=?charset?B?xxxxx?= 现在我们对这段内容进行一下说明。
=?
charset
B
xxxx
?=
BASE64 编解码操作:
因为火狐使用的是 BASE64 的编解码方式还原响应中的汉字。
所以需要使用 BASE64Encoder 类进行编码操作。
// 使用下面的格式进行 BASE64 编码后
String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
// 设置到响应头中
response.setHeader("Content-Disposition", str)
文件下载示例:
package com.chan.servlet;
import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
public class Download extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取要下载的文件名
String downloadFileName = "1.jpg";
//读取要下载的文件内容(通过ServletContext对象可以读取)
ServletContext servletContext = getServletContext();
//获取要下载的文件类型
String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
System.out.println("下载的文件类型" + mimeType);
//在回传前,通过响应头告诉客户端返回的数据类型
resp.setContentType(mimeType);
//告诉客户端收到的数据是用于下载使用(通过响应头)
//Content-Disposition 响应头,表示收到的数据怎么处理
//attachment 表示附件,表示下载使用
// fileName= 表示指定的下载名
//url编码是把汉字转换成为%xx%xx的格式
if (req.getHeader("User-Agent").contains("Firefox")){
//如果是火狐浏览器使用Base64编码
resp.setHeader("Content-Disposition","attachment; fileName==?utf-8?B?" + new BASE64Encoder().encode("风铃.jpg".getBytes("UTF-8")));
}else {
//IE或谷歌使用URL编码操作
resp.setHeader("Content-Disposition","attachment; fileName=" + URLEncoder.encode("风铃.jpg","UTF-8"));
}
InputStream inputStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
//设置响应的输出流
OutputStream outputStream = resp.getOutputStream();
//把下载的文件内容回传给客户端
//读取输入流中的全部数据,复制给输出流,输出给客户端
IOUtils.copy(inputStream,outputStream);
}
}
BeanUtils 工具类,它可以一次性的把所有请求的参数注入到 JavaBean 中。
BeanUtils 工具类,经常用于把 Map 中的值注入到 JavaBean 中,或者是对象属性值的拷贝操作。
BeanUtils 它不是 Jdk 的类。
而是第三方的工具类。
所以需要导包。
1、导入需要的 jar 包: commons-beanutils.jar commons-logging.jar
2、编写 WebUtils 工具类使用:
示例:
package com.atguigu.utils;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
public class WebUtils {
/**
* 把 Map 中的值注入到对应的JavaBean属性中
* @param value
* @param bean
* @param
* @return 请求参数
*/
public static T copyParamToBean(Map value , T bean){
try {
System.out.println("注入前:" + bean);
//把所有的请求参数都注入user对象中
BeanUtils.populate(bean,value);
System.out.println("注入后:" + bean);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return bean;
}
}
MVC 全称:Model 模型、 View 视图、 Controller 控制器。
MVC 最早出现在 JavaEE 三层中的 Web 层,它可以有效的指导 Web 层的代码如何有效分离,单独工作。
**View 视图:**只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员和美工的分工合作—— JSP/HTML。
**Controller 控制器:**只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色——Servlet。 转到某个页面。或者是重定向到某个页面。
**Model 模型:**将与业务逻辑相关的数据封装为具体的 JavaBean 类,其中不掺杂任何与数据处理相关的代码—— JavaBean/domain/entity/pojo。
MVC 是一种思想 MVC 的理念是将软件代码拆分成为组件,单独开发,组合使用(目的还是为了降低耦合度)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1j2KYjtZ-1647142931693)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220122183913234.png)]
Servlet程序
package com.chan.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieServlet extends BaseServlet{
/**
* 创建Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("key1","value1");
//通知客户端保存Cookie
resp.addCookie(cookie);
resp.getWriter().write("Cookie已创建!!!");
}
}
服务器获取客户端的 Cookie 只需要一行代码:req.getCookies():Cookie[]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iRZJ5mW8-1647142931693)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220122190046532.png)]
package com.chan.Utils;
import javax.servlet.http.Cookie;
public class CookieUtils {
/**
* 查询指定名称的Cookie对象
* @param name
* @param cookies
* @return
*/
public static Cookie findCookie(String name , Cookie[] cookies){
if (name == null || cookies == null || cookies.length == 0){
return null;
}
for (Cookie cookie : cookies){
if (name.equals(cookie.getName())){
return cookie;
}
}
return null;
}
}
Servlet程序
package com.chan.servlet;
import com.chan.Utils.CookieUtils;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class CookieServlet extends BaseServlet{
/**
* 服务器获取Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
// getName 方法返回 Cookie 的 key(名)
// getValue 方法返回 Cookie 的 value
resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
");
}
Cookie iWantCookie = CookieUtils.findCookie("key1",cookies);
// 如果不等于 null,说明赋过值,也就是找到了需要的 Cooki
if (iWantCookie != null){
resp.getWriter().write("找到所需key");
}
}
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8"));
Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8"));
Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8"));
//通知客户端保存Cookie
resp.addCookie(cookie);
resp.addCookie(cookie2);
resp.addCookie(cookie3);
resp.getWriter().write("Cookie已创建!!!");
}
}
方案一:
package com.chan.servlet;
import com.chan.Utils.CookieUtils;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class CookieServlet extends BaseServlet{
/**
* 修改Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void upDateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
//1. 先创建一个要修改的同名(指的是key)的Cookie对象
//2. 在构造器,同时赋新的Cookie值
Cookie cookie = new Cookie("key1","newValue");
//3. 调用resp.addCookie(cookie);
resp.addCookie(cookie);
resp.getWriter().write("已修改");
}
/**
* 服务器获取Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
// getName 方法返回 Cookie 的 key(名)
// getValue 方法返回 Cookie 的 value
resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
");
}
Cookie iWantCookie = CookieUtils.findCookie("key1",cookies);
// 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie
if (iWantCookie != null){
resp.getWriter().write("找到所需key");
}
}
/**
* 创建Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8"));
Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8"));
Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8"));
//通知客户端保存Cookie
resp.addCookie(cookie);
resp.addCookie(cookie2);
resp.addCookie(cookie3);
resp.getWriter().write("Cookie已创建!!!");
}
}
方案二:
package com.chan.servlet;
import com.chan.Utils.CookieUtils;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class CookieServlet extends BaseServlet{
/**
* 修改Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void upDataCookie2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//方案二:
//1. 先查找到需要修改的 Cookie 对象
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
if (cookie != null){
//2. 调用 setValue()方法赋于新的 Cookie 值
cookie.setValue("newValue2");
//3. 调用 response.addCookie()通知客户端保存修改
resp.addCookie(cookie);
}
}
/**
* 修改Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void upDateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
//方案一
//1. 先创建一个要修改的同名(指的是key)的Cookie对象
//2. 在构造器,同时赋新的Cookie值
Cookie cookie = new Cookie("key1","newValue");
//3. 调用resp.addCookie(cookie);
resp.addCookie(cookie);
resp.getWriter().write("已修改");
}
/**
* 服务器获取Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
// getName 方法返回 Cookie 的 key(名)
// getValue 方法返回 Cookie 的 value
resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
");
}
Cookie iWantCookie = CookieUtils.findCookie("key1",cookies);
// 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie
if (iWantCookie != null){
resp.getWriter().write("找到所需key");
}
}
/**
* 创建Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8"));
Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8"));
Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8"));
//通知客户端保存Cookie
resp.addCookie(cookie);
resp.addCookie(cookie2);
resp.addCookie(cookie3);
resp.getWriter().write("Cookie已创建!!!");
}
}
Cookie的生命控制指的是如何管理Cookie什么时候被销毁(删除)
setMaxAge()
package com.chan.servlet;
import com.chan.Utils.CookieUtils;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class CookieServlet extends BaseServlet{
/**
* 设置存活一小时的Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("life3600","life3600");
cookie.setMaxAge(3600);
resp.addCookie(cookie);
resp.getWriter().write("存活一小时的Cookie已创建");
}
/**
* Cookie的生命控制 立即删除
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void deleteImmediately(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
Cookie cookie = CookieUtils.findCookie("key1",req.getCookies());
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
/**
* Cookie的生命控制 默认的会话级别
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
Cookie cookie = new Cookie("defaultLife","defaultLife");
cookie.setMaxAge(-1);
resp.addCookie(cookie);
}
/**
* 修改Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void upDataCookie2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//方案二:
//1. 先查找到需要修改的 Cookie 对象
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
if (cookie != null){
//2. 调用 setValue()方法赋于新的 Cookie 值
cookie.setValue("newValue2");
//3. 调用 response.addCookie()通知客户端保存修改
resp.addCookie(cookie);
}
}
/**
* 修改Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void upDateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
//方案一
//1. 先创建一个要修改的同名(指的是key)的Cookie对象
//2. 在构造器,同时赋新的Cookie值
Cookie cookie = new Cookie("key1","newValue");
//3. 调用resp.addCookie(cookie);
resp.addCookie(cookie);
resp.getWriter().write("已修改");
}
/**
* 服务器获取Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
// getName 方法返回 Cookie 的 key(名)
// getValue 方法返回 Cookie 的 value
resp.getWriter().write("Cookie["+cookie.getName()+"<=>"+cookie.getValue()+"]
");
}
Cookie iWantCookie = CookieUtils.findCookie("key1",cookies);
// 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie
if (iWantCookie != null){
resp.getWriter().write("找到所需key");
}
}
/**
* 创建Cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("key1", URLEncoder.encode("value1","UTF-8"));
Cookie cookie2 = new Cookie("key2",URLEncoder.encode("value2","UTF-8"));
Cookie cookie3 = new Cookie("key3",URLEncoder.encode("value3","UTF-8"));
//通知客户端保存Cookie
resp.addCookie(cookie);
resp.addCookie(cookie2);
resp.addCookie(cookie3);
resp.getWriter().write("Cookie已创建!!!");
}
}
Cookie的Path属性可以有效的过滤哪些Cookie 可以发送给服务器,哪些不发
Path属性是通过请求的地址来进行有效的过滤
示例:
CookieA path=/工程路径
CookieB path=/工程路径/abc
请求地址:
http://ip:port/工程路径/a.html
CookieA发送
CookieB不发送
http://ip:port/工程路径/abc/a.html
CookieA发送
CookieB发送
package com.chan.servlet;
import com.chan.Utils.CookieUtils;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
public class CookieServlet extends BaseServlet{
/**
* Cookie 有效路径 Path 的设置
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void textPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("path1","path1");
cookie.setPath(req.getContextPath() + "/abc"); // == /工程路径/abc
resp.addCookie(cookie);
resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYFdrvrI-1647142931694)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220123191650798.png)]
login.jsp
<%--
Created by IntelliJ IDEA.
User: 鬼
Date: 2022/1/23
Time: 19:18
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
LoginServlet程序
package com.chan.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
/**
* 面用户名登录模拟
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
//将用户名存入Cookie
Cookie cookie = new Cookie("username",username);
if ("admin".equals(username) && "password".equals(password)){
System.out.println("登陆成功");
//登陆成功通知浏览器保存信息
resp.addCookie(cookie);
}else {
System.out.println("登陆失败");
}
}
}
如何创建和获取Session,它们的API是一样的 request.getSession()
第一次调用是:Session会话创建的时候
之后调用的都是:获取前面创建好的Session会话对象
isNew(); 判断是否是新创建出来的
true:表示新创建
false:表示获取之前的
每个会话都有一个身份证号,也就是id值,而这个id值是唯一的
getId(); 得到Session的会话id值
示例:
package com.chan.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionServlet extends BaseServlet{
protected void getSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Session会话对象
HttpSession session = req.getSession();
//判断当前Session会话,是否是新创建出来的
boolean aNew = session.isNew();
//获取Session会话的唯一标识符
String id = session.getId();
resp.getWriter().write("得到Session的id是:" + id + "
");
resp.getWriter().write("Session是否新创建的" + aNew );
}
}
package com.chan.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionServlet extends BaseServlet{
/**
* 往Session中存储数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void setAttributes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("key1","value");
resp.getWriter().write("已经在Session中保存了数据");
}
/**
* 获取Session中的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getAttributes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object key1 = req.getSession().getAttribute("key1");
resp.getWriter().write("从Session中获取key1的数据是:" + key1);
}
}
public void setMaxInactiveInterval(int interval) 设置Session的超时时间(以秒为单位),指定超时的时长,Session就会被销毁
值为正数的时候,设定Session的超时时长
负数表示永不超时(极少使用)
public int getMaxInactiveInterval()获取 Session 的超时时长
public void invalidate() 让当前 Session 会话马上超时无效
Session的默认时长是多少
Session的默认时长是30分钟
因为Tomcat服务器的配置文件web.xml中默认有以下配置,它就是表示配置当前Tomcat服务器下所有的Session超时时长为30分钟
<session-config>
<session-timeout>30session-timeout>
session-config>
如果说。你希望你的 web 工程,默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做 以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长。
<session-config>
<session-timeout>20session-timeout>
session-config>
如果你只想修改某个Session的时长,就可以使用上面的API,setMaxInactiveInterval(int interval) 来进行单独的设置
session.setMaxInactiveInterval(int interval)单独设置超时时长
Session的超时概念介绍:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSoyMU3P-1647142931694)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220124112135867.png)]
package com.chan.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionServlet extends BaseServlet{
/**
* Session马上超时
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session对象
HttpSession session = req.getSession();
//设置Session马上超时时长
session.invalidate();
resp.getWriter().write("当前Session马上销毁");
}
/**
* Session三秒后超时
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session对象
HttpSession session = req.getSession();
//设置Session三秒超时时长
session.setMaxInactiveInterval(3);
resp.getWriter().write("当前Session三秒后销毁");
}
/**
* Session的默认时长
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getDefaultDuration(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
int maxInactiveInterval = session.getMaxInactiveInterval();
resp.getWriter().write("Session的默认时长:" + maxInactiveInterval + "秒");
}
}
Session 技术,底层实现其实是基于Cookie技术来实现的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCs7apyN-1647142931694)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220124113504686.png)]
Filter 过滤器是 Java Web三大组件之一,三大组件分别是Servlet程序、Listener监听器、Filter过滤器
Filter 过滤器是 JavaEE 的规范,也是接口
Filter 过滤器 它的作用是:拦截请求,过滤响应
拦截请求常见的应用场景:
权限检查
日记操作
事务管理
等等…
在 web 工程下,有一个 Filter 目录。这个 Filter 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必 须是用户登录之后才允许访问。
用户登录之后都会把用户登录的信息保存到 Session 域中。所以要检查用户是否 登录,可以判断 Session 中否包含有用户登录的信息即可!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HwHtQKQD-1647142931695)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220214145904509.png)]
Filter 的代码:
package com.chan.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class FilterServletTest implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* doFilter 方法,专门用于拦截请求。可以做权限检查
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
//判断用户是否登录
if (user == null){
//没有登录跳转登录页
servletRequest.getRequestDispatcher("/Filter/login.jsp").forward(servletRequest,servletResponse);
return;
}else {
//让程序继续访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
}
}
web.xml 中的配置:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>FilterServletTestfilter-name>
<filter-class>com.chan.servlet.FilterServletTestfilter-class>
filter>
<filter-mapping>
<filter-name>FilterServletTestfilter-name>
<url-pattern>/Filter/a.htmlurl-pattern>
filter-mapping>
web-app>
1、编写一个类去实现 Filter 接口
2、实现过滤方法 doFilter()
3、到 web.xml 中去配置 Filter 的拦截路径
Filter 的生命周期包含几个方法
构造器方法
init初始化方法
第1,2不,在web工程启动的时候执行(Filter已经创建)
doFilter 过滤方法
第3不,,每次拦截到请求,就会执行
destroy 销毁
第4不,停止web工程的时候,就会执行(停止web工程,也就会销毁Filter过滤器)
FilterConfig 类见名知意,它是Filter 过滤器的配置文件类
Tomcat每次创建Filter的时候,也会创建一个FilterConfig类,这里包含Filter配置文件的配置信息
FilterConfig类的作用是获取filter过滤器的配置内容
Java代码
package com.chan.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class FilterServletTest implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//1、获取 Filter 的名称 filter-name 的内容
System.out.println("filter-name的值" + filterConfig.getFilterName());
//2、获取在 web.xml 中配置的 init-param 初始化参数
System.out.println("初始化username的值是:" + filterConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是:" + filterConfig.getInitParameter("url"));
//3、获取 ServletContext 对像
System.out.println(filterConfig.getServletContext());
}
/**
* doFilter 方法,专门用于拦截请求。可以做权限检查
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
web.xml配置文件
<filter>
<filter-name>FilterServletTestfilter-name>
<filter-class>com.chan.servlet.FilterServletTestfilter-class>
<init-param>
<param-name>usernameparam-name>
<param-value>rootparam-value>
init-param>
<init-param>
<param-name>urlparam-name>
<param-value>jdbc://127.0.1.1/3306param-value>
init-param>
filter>
<filter-mapping>
<filter-name>FilterServletTestfilter-name>
<url-pattern>/Filter/a.htmlurl-pattern>
filter-mapping>
Filter 过滤器
Chain 链,链条
FilterChain就是过滤器链(多个过滤器协同工作)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8W1e3EM-1647142931695)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220214181942570.png)]
精确匹配
/target.jsp
以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/target.jsp
目录匹配
/admin/*
以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/admin/*
后缀名匹配
*.html
以上配置的路径,表示请求地址必须以.html 结尾才会拦截到
*.do
以上配置的路径,表示请求地址必须以.do 结尾才会拦截到
*.action
以上配置的路径,表示请求地址必须以.action 结尾才会拦截到
Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!
ThreadLocal的作用,它可以解决线程的数据安全问题
ThreadLocal它可以给当前线程关联一个数据(可以是普通变量、数组、集合)
ThreadLocal的特点:
测试类:
package com.chan.threadlocal;
import java.util.Hashtable;
import java.util.Map;
import java.util.Random;
public class ThreadLocalText {
//public static Map data = new Hashtable();
public static ThreadLocal
使用 ThreadLocal 来确保所有 dao 操作都在同一个 Connection 连接对象中完成
原理图分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tBVcfoRj-1647142931695)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220216170921101.png)]
Jdbc工具类的修改
package com.atchan.utils;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
private static DruidDataSource dataSource;
private static ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();
static {
try {
Properties properties = new Properties();
// 读取 jdbc.properties属性配置文件
InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("resources/jdbc.properties");
// 从流中加载数据
properties.load(inputStream);
// 创建 数据库连接 池
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接池中的连接
* @return 如果返回null,说明获取连接失败 / 有值就是获取连接成功
*/
public static Connection getConnection(){
Connection conn = connectionThreadLocal.get();
if (conn == null){
try {
//从数据库连接池中获取连接
conn = dataSource.getConnection();
//保存到ThreadLocal对象中,供后面的jdbc操作使用
connectionThreadLocal.set(conn);
//设置为手动提交事务
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
return conn;
}
/**
* 提交事务,并关闭释放连接
*/
public static void commitAndCols(){
Connection connection = connectionThreadLocal.get();
//如果不等于null,说明使用过连接,操作过数据库
if (connection != null){
try {
//提交事务
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
//关闭连接,释放资源
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//一定要执行remove操作,否则会出错 (因为Tomcat服务器底层使用了线程池技术)
connectionThreadLocal.remove();
}
/**
* 回滚事务事务,并关闭释放连接
*/
public static void rollbackAndClose(){
Connection connection = connectionThreadLocal.get();
//如果不等于null,说明使用过连接,操作过数据库
if (connection != null){
try {
//回滚事务
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
//关闭连接,释放资源
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//一定要执行remove操作,否则会出错 (因为Tomcat服务器底层使用了线程池技术)
connectionThreadLocal.remove();
}
/**
* 关闭连接,放回数据库连接池
* @param conn
*/
/*
public static void close(Connection conn){
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
*/
}
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON 采用完全独立于语言的文本格式,而且很多语言都提供了对 json 的支持(包括 C, C++, C#, Java, JavaScript, Perl, Python 等)。 这样就使得 JSON 成为理想的数据交换格式
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script type="text/javascript">
// json的定义
let jsonObj = {
"key1" : 12,
"key2" : "abc",
"key3" : true,
"key4" : [11, true, "arr"],
"key5" : {
"key5_1" : 551,
"key5_2" : "key5_2Value"
},
"key6" : [{
"key6_1_1":6611,
"key6_1_2":"key6_1_2_value"
},{
"key6_2_1":6621,
"key6_2_2":"key6_2_2_value"
}]
};
// json的访问
// json对象转字符串
// json字符串转json对象
script>
head>
<body>
body>
html>
JSON本身就是一个对象
JSON中的key我们可以理解为是对象的一个属性
JSON中的key访问就跟访问对象中的属性一样:json对象.key
JSON访问示例:
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script type="text/javascript">
// json的定义
let jsonObj = {
"key1" : 12,
"key2" : "abc",
"key3" : true,
"key4" : [11, true, "arr"],
"key5" : {
"key5_1" : 551,
"key5_2" : "key5_2Value"
},
"key6" : [{
"key6_1_1":6611,
"key6_1_2":"key6_1_2_value"
},{
"key6_2_1":6621,
"key6_2_2":"key6_2_2_value"
}]
};
// json的访问
let key1 = jsonObj.key1;
console.log(key1) //12
console.log(jsonObj.key2) //abc
console.log(jsonObj.key3) //true
//遍历json中的数组
for (let i = 0 ; i < jsonObj.key4.length ; i++){
let key4Element = jsonObj.key4[i];
console.log(key4Element)
}
let key51 = jsonObj.key5.key5_2; //"key5_2Value"
console.log(key51)
let key6Element
for (let i = 0 ; i < jsonObj.key6.length ; i++){
key6Element = jsonObj.key6[i];
console.log(key6Element.key6_2_1)
}
// json对象转字符串
// json字符串转json对象
script>
head>
<body>
body>
html>
json存在的两种形式
JSON.stringify() 把json对象转字符串
JSON.parse() json字符串转json对象
示例代码:
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script type="text/javascript">
// json的定义
let jsonObj = {
"key1" : 12,
"key2" : "abc",
"key3" : true,
"key4" : [11, true, "arr"],
"key5" : {
"key5_1" : 551,
"key5_2" : "key5_2Value"
},
"key6" : [{
"key6_1_1":6611,
"key6_1_2":"key6_1_2_value"
},{
"key6_2_1":6621,
"key6_2_2":"key6_2_2_value"
}]
};
// json对象转字符串
let stringify = JSON.stringify(jsonObj);
console.log(stringify)
// json字符串转json对象
let parse = JSON.parse(stringify);
console.log(parse)
script>
head>
<body>
body>
html>
package JSONTest;
import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaBeanJsonTest {
@Test
public void test1(){
Student student = new Student(1,"张三",18,15487894);
Gson gson = new Gson();
String toJson = gson.toJson(student);
System.out.println(toJson);
Object fromJson = gson.fromJson(toJson, Student.class);
System.out.println(fromJson);
}
}
package JSONTest;
import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaBeanJsonTest {
@Test
public void Test2(){
List studentList = new ArrayList<>();
studentList.add(new Student(1,"张三",18,1564564));
studentList.add(new Student(2,"李四",19,45645646));
Gson gson = new Gson();
String toJson = gson.toJson(studentList);
System.out.println(toJson);
Object o = gson.fromJson(toJson, new TypeToken>() {
}.getType());
System.out.println(o);
}
}
package JSONTest;
import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaBeanJsonTest {
@Test
public void Test3(){
Map<Integer, Student> studentMap = new HashMap<>();
studentMap.put(1, new Student(1,"张三",18,1564564));
studentMap.put(2, new Student(2,"李四",19,45645646));
Gson gson = new Gson();
String toJson = gson.toJson(studentMap);
System.out.println(toJson);
gson.fromJson(toJson , Map.class);
}
}
AJAX即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互网页应用的网页开发技术
Ajax是一种浏览器通过js异步发起请求,局部页面的更新技术
Ajax请求的局部更新,浏览器地址栏地址不会发送改变 局部更新不会舍弃原来页面的内容
原生Ajax请求示例:
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script>
// 在这里使用javaScript语言发起Ajax请求,访问服务器AjaxServlet中javaScriptAjax
function ajaxRequest() {
//1.首先创建xmlHttpRequest
let xmlHttpRequest = new XMLHttpRequest();
//2.调用open方法设置参数
xmlHttpRequest.open("GET","http://localhost:8888/Java_Web_Jsp/ajaxServlet?action=JavaScriptAjax",true);
//4.在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
let responseText = JSON.parse(xmlHttpRequest.responseText);
//把响应的数据响应在页面上
document.getElementById("div01").innerHTML = "编号:" + responseText.id + "姓名:" + responseText.name;
}
}
//3.调用send方法发送请求
xmlHttpRequest.send();
}
script>
head>
<body>
<button onclick="ajaxRequest()">ajax requestbutton>
<div id="div01">
div>
body>
html>
Servlet程序
package com.chan.servlet;
import com.chan.Student;
import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AjaxServlet extends BaseServlet{
protected void JavaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.printf("ajax请求");
Student student = new Student(1,"韦天才",18,17823123);
Gson gson = new Gson();
String toJson = gson.toJson(student);
resp.getWriter().write(toJson);
}
}
$.ajax方法
url 表示请求的地址
type 表示请求的类型GET或POST请求
data 表示发送给服务器的数据
格式有两种:
1.name=value&name=value
2.{key:value}
success 请求成功,响应的回调函数
dataType 响应的数据类型
常用的数据类型有:
text 表示纯文本
xml 表示xml数据
json b
"key5_2" : "key5_2Value"
},
"key6" : [{
"key6_1_1":6611,
"key6_1_2":"key6_1_2_value"
},{
"key6_2_1":6621,
"key6_2_2":"key6_2_2_value"
}]
};
// json对象转字符串
let stringify = JSON.stringify(jsonObj);
console.log(stringify)
// json字符串转json对象
let parse = JSON.parse(stringify);
console.log(parse)
```
package JSONTest;
import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaBeanJsonTest {
@Test
public void test1(){
Student student = new Student(1,"张三",18,15487894);
Gson gson = new Gson();
String toJson = gson.toJson(student);
System.out.println(toJson);
Object fromJson = gson.fromJson(toJson, Student.class);
System.out.println(fromJson);
}
}
package JSONTest;
import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaBeanJsonTest {
@Test
public void Test2(){
List studentList = new ArrayList<>();
studentList.add(new Student(1,"张三",18,1564564));
studentList.add(new Student(2,"李四",19,45645646));
Gson gson = new Gson();
String toJson = gson.toJson(studentList);
System.out.println(toJson);
Object o = gson.fromJson(toJson, new TypeToken>() {
}.getType());
System.out.println(o);
}
}
package JSONTest;
import com.chan.Student;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.testng.annotations.Test;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaBeanJsonTest {
@Test
public void Test3(){
Map<Integer, Student> studentMap = new HashMap<>();
studentMap.put(1, new Student(1,"张三",18,1564564));
studentMap.put(2, new Student(2,"李四",19,45645646));
Gson gson = new Gson();
String toJson = gson.toJson(studentMap);
System.out.println(toJson);
gson.fromJson(toJson , Map.class);
}
}
AJAX即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互网页应用的网页开发技术
Ajax是一种浏览器通过js异步发起请求,局部页面的更新技术
Ajax请求的局部更新,浏览器地址栏地址不会发送改变 局部更新不会舍弃原来页面的内容
原生Ajax请求示例:
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script>
// 在这里使用javaScript语言发起Ajax请求,访问服务器AjaxServlet中javaScriptAjax
function ajaxRequest() {
//1.首先创建xmlHttpRequest
let xmlHttpRequest = new XMLHttpRequest();
//2.调用open方法设置参数
xmlHttpRequest.open("GET","http://localhost:8888/Java_Web_Jsp/ajaxServlet?action=JavaScriptAjax",true);
//4.在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
let responseText = JSON.parse(xmlHttpRequest.responseText);
//把响应的数据响应在页面上
document.getElementById("div01").innerHTML = "编号:" + responseText.id + "姓名:" + responseText.name;
}
}
//3.调用send方法发送请求
xmlHttpRequest.send();
}
script>
head>
<body>
<button onclick="ajaxRequest()">ajax requestbutton>
<div id="div01">
div>
body>
html>
Servlet程序
package com.chan.servlet;
import com.chan.Student;
import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AjaxServlet extends BaseServlet{
protected void JavaScriptAjax(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.printf("ajax请求");
Student student = new Student(1,"韦天才",18,17823123);
Gson gson = new Gson();
String toJson = gson.toJson(student);
resp.getWriter().write(toJson);
}
}
$.ajax方法
url 表示请求的地址
type 表示请求的类型GET或POST请求
data 表示发送给服务器的数据
格式有两种:
1.name=value&name=value
2.{key:value}
success 请求成功,响应的回调函数
dataType 响应的数据类型
常用的数据类型有:
text 表示纯文本
xml 表示xml数据
json b