css操作,js(javascript),Servlet,jsp(Java Server Page),el表达式,练习:网页登录访问商品界面并对其增删查改

编程知识 更新时间:2023-05-03 01:21:16

CSS:Cascading Style Sheet层叠样式表

书写的样式属性一定是样式库存在的样式
                1)行内样式:不推荐
                    弊端:一次只能控制某一个标签,加入样式
                    任何html标签中都有style属性
                    style="样式属性名称1:属性值1;样式属性名称2:属性值2;..." 
                2)内联样式(内部样式)
                    使用选择器
                        标签名称选择器 
                        在head标签体中:style标签

选择器{
       样式属性名称1:属性值1;
       样式属性清楚2:属性值2;
       ....
      }

 弊端:style中样式代码和html标签在同一个页面使用,不利于后期管理!(优于第一种)   
                 3)使用外联样式(外部样式)
                        单独在当前项目下css文件夹
                                        书写关联当前html标签的css样式文件
                        在当前html页面要 使用css外部文件,需要导入

    <link href="css文件" rel="stylesheet" />
                        rel="stylesheet" 关联层叠样式表 固定写法

选择器分类:

             标签选择器
                    class:类选择器

就是当前html标签上面给定义class属性,给定一个属性值
                        在样式标签中

.class属性值{
             样式属性名称1:value1;
             样式属性名称2:value2;
            }  

特点:同一个html页面上,多个标签可以指定相同的class属性值     

    id选择器        

       在标签中指定id属性以及属性值
                        在style标签中   

  #id属性值{
            样式属性名称1:value1;
            样式属性名称2:value2;
            ...
           }

                         在同一个html页面,标签中id属性值必须唯一,否则后面通过javascript
                    的id属性值获取标签对象可能获取不到! 
                    优先级:id选择器 > class选择器 > 标签(element)选择器  

  子元素选择器

选择器1 选择器2{
                 属性样式:属性值;
              }
选择器2选中的元素是选择器1选中的元素的子元素

伪类选择器:

描述一个标签的状态,后面状态名称不区分大小写

selector(css选择器):link状态{} <!-- 未访问过当前标签的状态 -->
        selector:visited{} <!-- 已经访问过的状态(点击了,并且已经松开) -->
        selector:hover{} <!-- 鼠标悬停在标签的状态 -->
        selector:active{} <!-- 鼠标正在访问(激活状态) 点击标签,但是没有松开的状态 -->
 <style>
			/* 未访问过的状态link */
			a:link{
				font-size: 10px;
				color: red;
			}
			
			/* visited:鼠标访问过的状态 */
			a:visited{
				font-size: 35px;
				color: darkgray;
				text-decoration: none;
			}
			/* hover:鼠标悬停在标签的状态 */
			a:hover{
				font-size: 20px;
				color: blue;
				/* 去掉下划线 */
				text-decoration:none ;
			}
			/*active:激活状态:点击,没有松开状态*/
			a:active{
				font-size: 30px;
				color: greenyellow;
				/* 文本修饰:加入下划线 */
				text-decoration: underline;
			}
</style>
<!-- 
			循环状态效果:必须遵循下面的先后顺序
			在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后才能生效。
			在 CSS 定义中,a:active 必须位于 a:hover 之后才能生效。
-->
</head>
	<body>
		<a href="02_CSS选择器.html">伪类选择器</a>
	</body>

伪类的应用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>伪类应用</title>
		<!-- 
			书写一个表格,4行4列
			鼠标经过每一行,变成蓝色
					背景的css样式:background-color:blue/#00F
		 -->
		 <style>
			.trClass{
				/* 文本属性:文本对齐方式 */
				text-align: center;
			}
			/* 
				设置鼠标经过每一行:变成蓝色背景
			 */
			.trClass:hover{
				background-color: #0000FF;
				cursor: pointer;
			}
		 </style>
	</head>
	<body>
		<table border="1" width="500px" cellspacing="0" height="300px">
			<tr>
				<th>学号</th>
				<th>姓名</th>
				<th>性别</th>
				<th>住址</th>
			</tr>
			<tr class="trClass">
				<td>1</td>
				<td>张三</td>
				<td>男</td>
				<td>西安市</td>
			</tr>
			<tr  class="trClass">
				<td>2</td>
				<td>李四</td>
				
				<td>女</td>
				<td>咸阳市</td>
			</tr>
			<tr  class="trClass">
				<td>3</td>
				<td>王五</td>
				<td>男</td>
				<td>渭南市</td>
			</tr>
		</table>
	</body>
</html>

CSS的常用样式属性

背景样式:

background-color:背景颜色
background-image:背景图片
background-repeat:设置背景图片是否重复以及如何重复
background-position:设置背景图片的起始位置

边框样式

border:border-width:边框线宽度 
 /*设置边框宽度border-方向-width*/
			 /*border-left-width: 10px;
			   border-right-width: 20px;
			   border-top-width: 30px;
			   border-bottom-width: 40px; */

border-style 边框线属性
             /*光有颜色和宽度不行,必须指定四个边框的样式属性:border-方向-style
				  solid:单实线
				  double:双实现
				  dotted:点
				  dashed:虚线
			   */
/* border-left-style: double;
			  border-right-style: dotted;
			  border-top-style: solid;
			  border-bottom-style: dashed ; */

border-color:边框颜色
/*设置边框颜色 border-方向-color*/
			 /*border-left-color:#00F ;
			   border-right-color:#F00 ;
			   border-top-color:#0F0 ;
			   border-bottom-color:darkgray ; */
 /* 边框颜色,边框宽度,边框样式的简写属性:
				border-color/border-width/border-style:将四个颜色 都可以指定进去
				1)默认的方向:上 右 下 左
				2)如果某一边没有设置颜色,补齐对边的颜色
 */
边框的简写属性:border:border-width border-style(必需) border-color

			/*border: 5px solid #000;
			div中设置它的容量
			width: 100px;
			height: 100px;*/

浮动属性样式

float:left/right:左浮动或者右浮动
clear:both(清除两边都不浮动)
      left(左边不浮动)
      right(右边不浮动)

浮动属性的应用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			#logo{
				float:  left;
			}
			#header{
				float:  left;
				margin:0 0 0 100px ;
			}
			#my_btn{
				float: left;
				margin-left: 50px;
			}
			#part_one{
				height: 50px;
				line-height:60px ;
			}
			#part_two{
				background-color: #000;	
			}
			.li_class{
				color: white;
				margin: 10px;
				text-decoration: none;
				margin-left: 50px;
			}
			#clear{
				clear: both;
			}
		</style>
	</head>
	<body>
		<!-- 大的div -->
		<div>
				<!-- logo部分 -->
			<div id="part_one">
				<!-- 包含三个小的div --> 
				<div id="logo">
					<img src="image/logo2.png" width="100%" />
				</div>
				<div id="header">
					<img src="image/header.png" width="100%" />
				</div>
				<div id="my_btn">
					<a href="#">登录</a>
					<a href="#">注册</a>
					<a href="#">购物车</a>
				</div>
			</div>
			<div id="clear"></div>
			<!-- 第二部分:水平导航条件 -->
			<div  id="part_two">
				<a class="li_class" href="#">首页</a>
				<a class="li_class"  href="#">手机数码</a>
				<a class="li_class"  href="#">笔记本专区</a>
				<a class="li_class"  href="#">电脑办公</a>
				<input type="text" style="color: black;" /> 
			</div>
		</div>
	</body>
</html>

css字体样式:

font-family:字体类型("楷体","宋体","黑体"....)
font-size:字体大小(指定像素大小)
font-weight:字体粗细程度(适当加粗:bold  bolder)
font-style:italic(斜体)/默认值normal(正常体)

CSS文本样式

text-align:文本对齐方式
            left/center/right
text-decoriation:文本修饰
                 undline:下划线
                 none:去掉修饰
                 overline:上划线
                 line-through:中划线
letter-spacing:字符(字母)间距
word-spacing:字间距 (单词间距):两个汉字组成一个单词

CSS盒子模型

       边框border:盒子厚度(一般1px)
       width+height:盒子的容量大小
       padding:内边距: 盒子的内容和边框的之间的举例
       margin:外边距:盒子和盒子之间的距离

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>css盒子模型</title>
		<style>
			#d1{
				width: 150px;
				height: 150px;
				border: 1px solid #000;
				background-color: #00FF00;
				/* 内边距:
					简写属性:padding:pading-top padding-right pading-bottom padding-left
				 */
				/* padding:0 0 10px 10px ; */
				/* padding-top: 10px;
				padding-left: 10px; */
				/* margin-bottom: 10px; */
				/* 将div整体往浏览器中间移动 */
				margin: 220px 0 0 480px;
			}
			#d2{
				width: 150px;
				height: 150px;
				border: 1px solid #000;
				background-color: #FF0000;
				/* margin-top: 10px; */
			}
		</style>
	</head>
	<body>
		<div id="d1">div1</div>
		<!-- <div id="d2">div2</div> -->
	</body>
</html>

盒子模型应用:网页登录  

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>盒子模型应用</title>
		<style>
			#formDiv{
				/* 指定大div边框 */
				border: 1px solid #000;
				/* 设置宽和高度容量 */
				width: 450px;
				height: 260px;
				/* 设置div的外边距 */
				margin: 150px 0 0 400px;
				/* css背景属性 */
				/* background: darkgray url(./image/index_3.jpg) no-repeat center top; */
				background: darkgray  no-repeat center top;
			}
			/* 修饰用户名所在div */
			#user_div{
				margin: 50px 0 0 100px;
			}
			/* 修饰密码所在div */
			#password_div{
				margin: 20px 0 0 100px;
			}
			/* 修饰复选框所在div */
			#checkbox_div{
				margin: 20px 0 0 150px;
			}
			/* 修饰id="btn_div"的div*/
			#btn_div{
				margin: 20px 0 0 170px;
			}
			/* 修饰id="reg_btn"的外边距" */
		#reg_btn{
			margin-left: 30px;
		}
		</style>
	</head>
	<!-- 
		大的div中 包含三个div
				用户名所在div
				密码所在div
				特殊按钮div
				div+css:盒子模型 进行层级布局
	 -->
	<body>
		<div id="formDiv">
			<form>
				<div id="user_div">
					用户名:<input type="text" name="username" placeholder="请输入用户名" />
				</div>
				<div id="password_div">
						密&ensp;&ensp;码:<input type="password" name="password" placeholder="请输入密码" />
				</div>
				<div id="checkbox_div">
					<input type="checkbox" value="remember me" />remember me
				</div>
				<div id="btn_div">
					<input  type="submit" value="登录" /><input type="submit" id="reg_btn" value="注册" />
				</div>
			</form>
		</div>
	</body>
</html>

CSS定位属性   

定位属性:position
                    left:向右移动
                    top:向下移动
绝对定位:absolute
                    针对他的父元素进行移动:body父元素进行移动
相对定位:relative
                    针对当前元素以前的位置进行移动
固定定位:fixed(使用居多)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>CSS定位属性</title>
 <style>
			.di1{
				border:1px solid #000 ;
				background-color: cornflowerblue;
				width: 150px;
				height: 150px;
			}
			.di2{
				border:1px solid #000 ;
				background-color: seagreen;
				width: 150px;
				height: 150px;	
			}
			.di3{
				border:1px solid #000 ;
				background-color: bisque;
				width: 150px;
				height: 150px;
				
				/* 定位属性 */
			     /* 绝对定位position: absolute; */
				 /* 相对定位*/
				/* position: relative; */
				 /* 向右移动30*/
			/* 	left: 30px;
				top:50px */
			}
			/* 设置class="adv"的样式 */
			.adv{
				border: 2px solid #000;
				background-color: plum;
				width: 150px;
				height: 150px;
				
				/* 固定定位 */
				position: fixed;<!--使用fixed来固定-->
				left: 550px;
				top:200px;
			}
			
		 </style>
	</head>
	<body>
		<div class="di1">div1</div>
		<div class="di2">div2</div>
		<div class="di3">div3</div>
		网站内容网站内容网站内容网站内容网站内容网站内容网站内容网站内容网站内容网站内容网站内容
		网站内容网站内容网站内容网站内容网站内容网站内容网站内容网站内容网站内容
		网站内容网站内容网站内容网站内容网站内容网站内容网站内容
		网站内容网站内容网站内容网站内容网站内容网站内容<br/><br/><br/><br/><br/><br/><br/><br/>
		<br/><br/><br/><br/><br/><br/><br/>
		<br/><br/><br/><br/><br/>
		<div class="adv">
			<a href="#" style="text-decoration: none;">立刻咨询</a>
		</div>
	</body>
</html>

javascript的使用方式

1)内部方式
   在当前内部位置:一般head标签体中
           <script>
                   //常用的几个函数
                   window.alert("消息对话框") ;
                window.confirm("确认提示框") ;
                //文档对象document
                //想浏览器写入内容
                document.write("hello,javascript") ;

                //在浏览器内置很多对象
                console.log("hello,javascript") ;//在浏览器控制台打印日志
       </script>

   2)外部方式:

      前端开发人员使用这种方式:js代码和html代码分离了
            单独定义js文件  
            写入js代码
            在当前html页面引入js文件
            <script src="导入外部js文件"></script>

js变量定义以及数据类型划分

1)在js中,定义变量是var定义,var可以省略不写,(前期学习阶段不建议)
                 js是一个弱类型语言(语法以及语句不严谨),可以重复定义变量,后面的值将前面的值覆盖
2)var可以定义任何数据类型, 如何查看数据类型 typeof(变量名)
                 js中数据类型:通过值判定的
3)基本数据类型划分:
                 无论整数还是小数,都是number类型 -----提升为js的内置对象Number(引用类型)
                 无论是字符串还是字符,都是string类型----提升为js的内置对象String(引用类型)
                 boolean类型----提升js内置对象Boolean(引用类型)
                 undefined:未定义类型,没有给变量赋值(毫无意义)
                 object---自动提示js内置对象 (引用类型:代表任意Javascript内置对象的模板)

 js中的运算符

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>js中的运算符</title>
		<!-- 
			算术运算符
			比较
			逻辑
			三元...
		 -->
		 <script>
			var a = 10 ;
			var b = 20 ;
			var c = 5 ;
			
			document.write("(a+b):"+(a+b)+"<br/>") ;
			document.write("(a-b):"+(a-b)+"<br/>") ;
			document.write("(a*b):"+(a*b)+"<br/>") ;
			document.write("(a/b):"+(a/b)+"<br/>") ;
			document.write("(a%b):"+(a%b)+"<br/>") ;
			document.write("<hr/>") ;
			//弱类型语言: true代表 数字1  false 数字 0 (实际开发:仅仅代表 逻辑判断)
			document.write(a+false) ;
			document.write("<hr/>") ;
			document.write((a>b)+"<br/>") ;
			document.write((a==b)+"<br/>") ;
			document.write((a>b) && (c>b)+"<br/>") ; 
			
			document.write("<hr/>") ;
			//三元运算符
			var age = 18 ;
			document.write((age>=18)?"成年人":"未成年人") ;
		 </script>
	</head>
	<body>
	</body>
</html>

选择语句之if

js中弱类型语言:
                    boolean的值:true,成立;false不成立
                    表达式中如果是非0的number类型,条件成立,否则不成立;
                    表达式中如果是string类型,非空字符串,条件成立,否则不成立;
                    表达式如果是object类型,非null对象,条件成立,否则不成立;
                    实际开发中,if语句中表达式(通过一些逻辑运算符 || &&)

if(new Object()){
		alert("条件成立") ;
}else{
		alert("条件不成立") ;
}

    switch:弱类型语言的switch中的case后面 既可以是变量,也可以是常量
    java语言:强类型语言:case后面只能常量

swich语句

                var week = 4 ;
				var b = 4 ;
				switch(week){
			    case 1:
						alert("星期一") 
						break ;
				case 2:
						alert("星期二") 
						break ;
				case 3:
						alert("星期三") 
						break ;			
				case b:
						alert("星期四") 
						break 
				case 5:
						alert("星期五") 
						break ;
				default:	
						alert("非法数据") 
						break
				 }

for语句

 for(var i = 0 ; i  < 10 ; i++ ){
		document.write(i+"<br/>") ;
}

for-in语句:遍历数组或者自定义对象的数据
     

for(var 变量名 in  数组对象/自定义对象){ //类似于Java中增强for循环
                  使用变量名 
                  如果是数组 数组对象[变量名]
       }

js中定义数组
静态初始化的简写方式

 var arr = [10,20,30,40,50] ;
				 //普通for循环
				 for(var i = 0 ; i < arr.length ; i++){
					 document.write(arr[i]+"&ensp;")
				 }
				 document.write("<hr/>") ;
				 			 
				 for(var x in arr){
					 document.write(arr[x]+"&ensp;");
				 }

js中函数定义

注意事项:
             1)形式参数列表:只需要书写参数名称即可,不需要带var
             2)js中定义函数的时候,可以书写return,也可以不书写
             3)js是弱类型语言,没有函数重载的概念,函数名称相同,后面的函数将前面函数就覆盖了
                            如果形式参数个数大于实际参数列表,函数会被调用,只不过值NaN
                                    有某个形参没赋值:导致结果是NaN
                            如果形式参数个数小于实际参数列表,函数会被调用,会将多余的实际参数去掉
                            然后将前面的实际参数分别绑定给形式参数,进行计算...
             4)js中函数中默认存在一个数组对象:arguments        
                        作用:就是将实际参数赋值给形式参数
                function 函数名称(形式参数列表){
                    (1)可以写return语句
                    (2)直接输出
                }
                调用
                    1) var 结果 = 函数名称(实际参数列表) ;
                    输出结果
                    2)单独调用 函数名称(实际参数列表) ;

<script>
			//定义求两个数据之后的函数
			//function add(var a, var b ){ //不需要数据类型
			function add(a,b){
				//return语句
				//return a + b ;
				var result = a+ b ;
				document.write("两个数据之和是:"+result)  ;
			}
			function add(a,b,c){//a=20,b=30,c=10
				//默认存在arguments数组对象
				for(var i = 0 ; i<arguments.length ; i++){
					alert(arguments[i]) ;
				}
				var result = a+ b+ c ;
				document.write("三个数据之和是:"+result)  ;	
			}
			//调用
			//var result = add(10,20) ;
			//document.write("reuslt:"+result) ;
			
			//方式2调用
			//单独调用
			add(20,30,10) ;
</script>

js时事件编程的三要素

            1)事件源
                    html标签
            2)编写事件监听器
                    编写一个js函数
            3)绑定事件监听器
                    利用html一些事件属性和js函数进行关
                    on事件="js函数()"
            dom操作:浏览器加载html页面 ---内置js引擎将标签都封装对象,然后形成"树结构"
                    想办法获取某个标签对象,然后改变属性

示例练习

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>练习</title>
<!-- 事件源 -->
		<input type="text" id="month"  /><input type="button" value="点击查询" onclick="checkButton()" />
	</body>
	<script>
		/* 编写一个js函数 */
		function checkButton(){
			//alert("触发点击事件...") ;
			
			//业务:需要通过文本输入框的id属性值"month"获取所在的标签对象
			//oElement = document.getElementById(sIDValue) :通过id属性值获取标签对象
			/* var textInput = document.getElementById("month") ; //原生js对象
			//alert(textInput);
			//获取标签属性
			var content = textInput.value ;
			alert(content) ; */
			
			//一步走
			var content = document.getElementById("month").value ; //content---->String
			//alert(content) ;
			//document.write("content的数据类型:"+typeof(content)) ;
			
			//if..else if...else...
			//if中的string和number比较,string---自动转换number然后在和number比较
			/* if(content<0 || content>12){
				alert("非法数据") ;
			} else if(content>=3 && content<=5){
				alert("春季") ;
			}else if(content>=6 && content<=8){
				alert("夏季") ;
			}else if(content>=9 && content<=11){
				alert("秋季") ;
			}else{
				alert("冬季") ;
			} */
			
			//switch语句  :content:表单输入的内容string 不能自动转换number
			//alert(typeof(content)) ;
			content = parseInt(content) ; //类型转换函数:将string--->number
			//alert(typeof(content)) ;
			switch(content){
			case 3:
			case 4:
			case 5:
			     alert("春季") ;
				 break ;
			case 6:
			case 7:
			case 8:
				alert("夏季") ;
				break ;
			case 9:
			case 10:
			case 11:
				alert("秋季") ;
				break ;
			case 12:
			case 1:
			case 2:
				alert("冬季") ;
				break ;
			default:
				alert("非法数据");
				break ;
			}
		}
	</script>
</html>

内置对象String

基本类型:无论字符还是字符串 string---- String内置对象

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>内置String</title>
		<!-- 
			基本类型:无论字符还是字符串 string---- String内置对象
		 -->
		 <script>
			//语法格式
			// var newString = new String(["stringLiteral"])
			var s1 = new String("hello") ;
			var s2 = new String("hello") ;
			/* 
				==:比较的是地址值是否相同
			 */
			document.write((s1==s2)+"<br/>");
			/* 
				js内置String对象:valueOf()获取指定对象的原始值。(字符串本身的内容值)
				比较两个字符串的内容是否一致
			 */
			document.write((s1.valueOf()==s2.valueOf())+"<br/>") ;
			document.write("<br/>") ;
			//简化格式:  js中创建String对象
			var str1 = "world" ;
			var str2 = "world" ;
			document.write((str1==str2)+"<br/>");
			document.write("<hr/>") ;
			
			var str = "hellojavascript" ;
			//获取指定索引处的字符:charAt(var index)
			document.write("charAt():"+str.charAt(5)+"<br/>") ;
			//concat(var str):拼接功能
			document.write("concat():"+str.concat("javaee")+"<br/>") ;
			//indexOf(var childStr):查找指定子字符串第一次出现索引值
			document.write("indexOf():"+str.indexOf("oja")+"<br/>") ;
			//lastIndexOf(var childStr):子字符串最后一次出现的索引值
			//fontcolor(颜色单词/或者RGB的写法#字符值)
			document.write("fontcolor():"+str.fontcolor("#ffaa00")+"<br/>") ; 
			//截取substring(start,end):[start,end-1]
			document.write("substring():"+str.substring(5,9)+"<br/>") ;
			//substr(start [, length ]):参数1:起始索引,参数2:指定截取长度
			document.write("substr():"+str.substr(5,4)+"<br/>") ;
			document.write("<hr/>") ;
			//分割功能(拆分)spilt("分隔符号")
			var strs = "JavaEE-Python-Php-Hadoop-R-Go" ; 
			var strArray = strs.split("-") ;//字符串数组
			for(var i = 0 ; i < strArray.length;  i++){
				document.write(strArray[i]+"&ensp;") ;
			}	
		 </script>
	</head>
	<body>
	</body>
</html>

内置对象Date

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>内置对象Date</title>
		<script>
			//js创建Date对象
			// var dateObj = new Date()
			var date = new Date() ;
			//document.write(date) ; //当前系统时间
			//获取年  
			//getYear():获取当前系统时间年份和1900之间的差值
			//getFullYear()
			//document.write(date.getYear()+"年") ;
			document.write(date.getFullYear()+"年") ;
			
			//获取月
			//getMonth():0-11之间的整数
			document.write(date.getMonth()+1+"月") ;
			
			//获取月中的日期getDate()
			document.write(date.getDate()+"日&ensp;&ensp;") ;
			
			//获取时getHours
			document.write(date.getHours()+":") ;
			
			//获取分钟getMinutes()
			document.write(date.getMinutes()+":") ;
			//获取秒getSeconds()
			document.write(date.getSeconds()) ;
		</script>
	</head>
	<body>
	</body>
</html>

示例:网页时钟

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>网页时钟</title>
	</head>
	<body>
		<font>当前系统时间是:</font><span id="spanTip"></span>
		<!-- 事件源 -->
		<input type="button" value="清除定时器" onclick="clearTask()" />
	</body>
	<script>
		function genDate(){
			//1)创建当前Date对象:拼接当前系统时间
			var date = new Date() ;
			//2)拼接日期字符串
			var dateStr = date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate()+"&ensp;&ensp;"+
			date.getHours()+":"+date.getMinutes()+":"+date.getSeconds() ;
			//alert(dateStr)
			
			//通过id属性值获取span标签对象
			var spanObject = document.getElementById("spanTip") ;
			
			//设置span标签对象的innerHTML属性: 添加文本内容(可以加入html标签 渲染)
			//innerText属性:只是添加普通文本: 如果添加标签体,不会将标签进行转义
			
			 spanObject.innerHTML = "<h4>"+dateStr +"</h4>";
		}
		 //window对象(可以省略不写)中有网页定时器 
		 //window.setInterval(vCode, iMilliSeconds ): 每经过iMilliSeconds毫秒值重复执行vCode
		 //参数1:任务函数
		 //参数2:毫秒数  
		var taskId = setInterval("genDate()",1000) ;//每经过1000毫秒执行这个任务
		 
		 //window.setTimeout(vCode, iMilliSeconds):经过iMilliSeconds毫秒值后执行一次vCode
		 //参数1:任务函数
		 //参数2:毫秒数  
		 //清除定时器
		 //window.clearInterval(iIntervalID) :参数任务id
		 function clearTask(){
			//alert("触发点击...");
			window.clearInterval(taskId) ;
		 }
	</script>
</html>

js常用事件分类(示例)

点击相关的事件

  • 单击:click

  • 双击:dbclick

和焦点相关的事件

  • 获取焦点:focus

  • 失去焦点:blur

  • 和选项卡发生变化事件相关的change(下列菜单 选择子选项...)

  • 和鼠标相关的:鼠标经过mouseover,鼠标移出mouseout...

  • 页面载入事件load

  • 键盘按下:keyup ----参考文档...

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>js常用事件分类</title>
		<style>
			#div1{
				border: 1 solid #000;
				background-color: olivedrab;
				width: 100px;
				height: 100px;
			}
		
		</style>
		<!-- 
			点击相关的事件
					单击:click
					双击:dbclick
					
			和焦点相关的事件
					获取焦点:focus
					失去焦点:blur
			和选项卡发生变化事件相关的change(下列菜单 选择子选项...)
			和鼠标相关的:鼠标经过mouseover,鼠标移出mouseout...
			页面载入事件load 
			键盘按下:keyup ----参考文档...
			
		 -->
	</head>
	<!-- 将整个body内容加载完毕之后,触发一个函数 -->
	<body onload="testLoad()">
<input type="button" value="单击" onclick="testClick()" /><br/>
<input type="button" value="双击" ondblclick="testDbClick()" /><br/>
用户名:<input type="text" id="username" value="请输入用户名" onblur="testBlur()" onfocus="testFocus()" /><span id="usernameSpan"></span><br/>

籍贯:
<select id="province" onchange="testChange()">
	<option value="请选择">请选择</option>
	<option value="陕西省">陕西省</option>
	<option value="山西省">山西省</option>
	<option value="江西省">江西省</option>
	<option value="广东省">广东省</option>
</select>
<select id="city">
	<!-- <option value="西安市">西安市</option> -->
</select>
<br />
<div id="div1" onmouseover="testMouseOver()" onmouseout="testMouseOut()">
	div
</div>
	</body>
<script>
	/* 编写事件监听器 */
	function testClick(){
		alert("触发了单击点击事件...") ;
	}
	
	function testDbClick(){
		alert("双击点击事件触发了...") ;
	}
	
	//获取焦点
	function testFocus(){
		//alert("触发获取焦点事件...");
		//需要通过id="username"获取input标签对象
		var inputObj = document.getElementById("username") ;
		inputObj.value = "" ; //清空掉			
	}	
	//失去焦点函数
	function testBlur(){
		需要通过id="username"获取input标签对象并且同时获取文本框的内容
		var username = document.getElementById("username").value ;
		//alert(username) ;
		//id="usernameSpan"所在的标签对象
		var spanObj = document.getElementById("usernameSpan") ;
		if(username !="马三奇"){
			//设置span标签对象的innerHTML内容
			spanObj.innerHTML="对不起,用户名不可用".fontcolor("red") ;
		}else{
			spanObj.innerHTML="√".fontcolor("green") ;
		}
	}
	//选项卡发生变化的事件函数
	function testChange(){
		//alert("change事件触发了...") ;
		//获取当前的省份内容:
		
		//id="province"获取的标签对象同时内容
		var jiguan = document.getElementById("province").value;
		//alert(jiguan) ;
		
		//获取id="city"所在的标签对象
		var city = document.getElementById("city") ;
		
		//每次选项卡变化,将之前的innerHTML清空掉
		city.innerHTML = "" ;
		
		//选择某个省份之后,出现城市 :省市联动
		//判断如果jiguan如果是陕西省
		if(jiguan=="陕西省"){
			
			//创建数组 :arrayObj = [element0[, element1[, ...[, elementN]]])简写格式
			var arr = ["西安市","宝鸡市","咸阳市","渭南市","神木市"] ;
			//遍历
			for(var i = 0 ; i <arr.length; i ++){
				//获取到每一个元素
				//设置城市所在的select标签对象的innerHTML属性
				city.innerHTML+="<option value='"+arr[i]+"'>"+arr[i]+"</option>";
			}
		}
		if(jiguan=="山西省"){
			//创建数组 :arrayObj = [element0[, element1[, ...[, elementN]]])简写格式
			var arr = ["太原市","运城市","晋中市","吕梁市","大同市"] ;
			//遍历
			for(var i = 0 ; i <arr.length; i ++){
				//获取到每一个元素
				//设置城市所在的select标签对象的innerHTML属性
				city.innerHTML += "<option value='"+arr[i]+"'>"+arr[i]+"</option>";
			}
		}
		if(jiguan=="江西省"){
			//创建数组 :arrayObj = [element0[, element1[, ...[, elementN]]])简写格式
			var arr = ["赣州市","南昌市","上饶市","滨海市","宜春市"] ;
			//遍历
			for(var i = 0 ; i <arr.length; i ++){
				//获取到每一个元素
				//设置城市所在的select标签对象的innerHTML属性
				city.innerHTML += "<option value='"+arr[i]+"'>"+arr[i]+"</option>";
			}
		}
		if(jiguan=="广东省"){
			//创建数组 :arrayObj = [element0[, element1[, ...[, elementN]]])简写格式
			var arr = ["深圳市","广州市","东莞市","惠州市","中山市"] ;
			//遍历
			for(var i = 0 ; i <arr.length; i ++){
				//获取到每一个元素
				//设置城市所在的select标签对象的innerHTML属性
				city.innerHTML += "<option value='"+arr[i]+"'>"+arr[i]+"</option>";
			}
		}
	}
	//鼠标经过事件的函数
	function testMouseOver(){
		//alert("触发鼠标经过事件...") ;
		window.open("03_js中的运算符.html") ;
	}
	function testMouseOut(){
		alert("鼠标移出事件触发...") ;
	}
	//页面载入事件load 一般用在body里面
	/* function testLoad(){
		//alert("body加载完比了") ;		
	} */
	/* 绑定onLoad事件 */
	window.onload = function(){
		alert("页面载入事件触发了") ;
	}
	
</script>	
</html>

js的正则表达式

  • 正则表达式:能够浏览器(js引擎)进行解析的 限定用户输入数据的时候的一种约束!

js正则表达式常用语法

  • X字符:X代表字符

数量词相关的语法:

  • X+:表示X字符出现一次或者多次

  • X?:表示X字符出现0次或者一次

  • X*:表示X字符出现零次或多次

范围相关的

  • \w 等价于 [A-Za-z0-9_] :任意的大小写字母或者数字字符

  • X{n,}:表示至少n次

  • X{n}: 表示恰好出现n次

  • X{n,m}:X字符串至少出现n次,不超过m次

正则表达对象:

  • var 变量名 = /正则语法/;

  • 变量名.test(被校验的字符串)---返回true,匹配成功,否则匹配失败

<script>
            var str = "asdf12abc" ;
            //定义正则
            var pattern = /^[0-9]{2}$/ ;
            if(pattern.test(str)){
                alert("条件成立") ;
            }else{
                alert("条件不成立") ;
            }
    </script>

js的原生表单校验

用户名:8-16位的数字或者字母

密码:6-16位的数字字母组成

确认密码和密码一致

邮箱符合邮箱格式: 数字或字母@数字字母.(com//)

<style>
        #formDiv{
            border: 1px solid #000;
            width: 420px;
            height: 240px;
            margin: 150px 0 0 400px;
        }
        #userDiv{
            margin: 30px 0 0 60px;
        }
        #pwdDiv{
            margin: 10px 0 0 60px;
        }
        #repwdDiv{
            margin: 10px 0 0 60px;
        }
        #emailDiv{
            margin: 10px 0 0 60px;
        }
        #btnDiv{
            margin: 10px 0 0 80px;
        }
    </style>
</head>
<body>
    <div id="formDiv">
        <!--
            表单是否能够提交取决于当前onsbumit事件(绑定一个函数:将所有的表单项都必须校验)的返回值如果true,表示能够提交
            否则false,不能提交
        -->

       <!-- <h3>GET方式提交</h3>-->
        <div>
            <h3>Post方式提交</h3>
        </div>

        <!--action:servlet后台地址-->
        <form action="http://localhost:8080/Web_02/args" method="post" onsubmit="return checkAll()">
            <div id="userDiv">
                用户名:<input type="text" name="username" id="username" onblur="checkUserName()" placeholder="请输入用户名"><span id="userTip"></span>
            </div>
            <div id="pwdDiv">
                密&ensp;&ensp;码:<input type="password" name="password" onblur="checkPassword()" id="password" placeholder="请输入密码"><span id="pwdTip"></span>
            </div>

            <div id="repwdDiv">
                确认密码:<input type="password" name="repwd" id="repwd" onblur="checkRePassword()" placeholder="请输入密码"><span id="repwdTip"></span>
            </div>
            <div id="emailDiv">
                 邮箱:<input type="text" name="email" id="email" onblur="checkEmail()" placeholder="请输入邮箱"><span id="emailTip"></span>
             </div>
            <div id="btnDiv">
              <input type="submit" value="注册"><input type="button"  style="margin-left: 30px" value="登录">
            </div>
        </form>
    </div>
    <hr/>

<script>
    //校验用户名:
    function checkUserName(){
        //通过 id="username"获取当前用户名所在的文本框的标签对象并获取它的内容
       var username =  document.getElementById("username").value ;
       //密码:6-16位的数字字母组成
       //定义正则表达式
       var reg = /^[A-Za-z0-9_]{6,16}$/ ;
       //获取id="userTip"的span标签对象
       var spanTip =  document.getElementById("userTip") ;

       //校验用户名
        if(reg.test(username)){
            //成立
            spanTip.innerHTML = "恭喜您,可用".fontcolor("green") ;
            return true ;
        }else{
            //不成立
            spanTip.innerHTML = "×".fontcolor("red") ;
            return false ;
        }
    }
    //校验用户名:
    function checkPassword(){
        //通过 id="password"获取当前密码所在的文本框的标签对象并获取它的内容
        var password =  document.getElementById("password").value ;
        //用户名:8-16位的数字或者字母
        //定义正则表达式
        var reg = /^[A-Za-z0-9_]{8,16}$/ ;
        //获取id="pwdTip"的span标签对象
        var spanTip =  document.getElementById("pwdTip") ;

        //校验用户名
        if(reg.test(password)){
            //成立
            spanTip.innerHTML = "√".fontcolor("green") ;
            return true ;
        }else{
            //不成立
            spanTip.innerHTML = "×".fontcolor("red") ;
            return false ;
        }
    }
    //确认密码和密码一致
    function  checkRePassword() {
        //通过 id="password"获取当前密码所在的文本框的标签对象并获取它的内容
        var password =  document.getElementById("password").value ;
        //获取当前确认密码框的内容id="repwd"
       var repassword =  document.getElementById("repwd").value;
       //获取span标签对象
        // id="repwdTip"
        var spanTip = document.getElementById("repwdTip");
       if(repassword==password){
           spanTip.innerHTML="√".fontcolor("green") ;
           return true ;
       }else{
           spanTip.innerHTML = "×".fontcolor("red") ;
           return false ;
       }
    }
    //校验邮箱
    function  checkEmail() {
        // id="email"的输入的内容
        var email = document.getElementById("email").value ;
        // 邮箱符合邮箱格式:
        //数字或字母@数字字母.(com//.ISTone/)
        //纯QQ邮箱  数字@qq
        //本身字符:就是.----转义 \.
         var reg = /^[A-Za-z0-9]+@[A-Za-z0-9]+(\.[A-Za-z]{2,3}){1,2}$/ ;

         //获取id="emailTip"的span标签对象
        var spanTip = document.getElementById("emailTip");
        //校验
        if(reg.test(email)){
            spanTip.innerHTML="√".fontcolor("green") ;
            return true ;
        }else{
            spanTip.innerHTML="×".fontcolor("red") ;
            return false ;
        }
    }
    //表单能否提交
    function  checkAll() {
        //将所有的表单项都必须满足规则
        if(checkUserName() && checkPassword() && checkRePassword() && checkEmail()){
            return true ;
        }else{
            return false ;
        }
    }
</script>

DOM(基于文档对象模型编程)

  • 浏览器解析HTML页面:代码从上往下加载标签,将标签封装"标签对象",就会树状结构

DOM宗旨:

  • 1)通过特殊的方式获取标签对象(节点)

  • 2)通过标签对象改变属性,控制效果

js的DOM操作

  • document.getElementById("id属性值") ;id属性值必须唯一,获取某个标签对象

  • document.getElementsByName("name属性值") ---获取的是当前列表标签对象(集合)

  • document.getElementsByClassName("所有的同名class属性值")---获取的是当前列表标签对象(集合)

  • document.getElenentsBtTagName("所有的同名的标签名称") ;-----获取的是当前列表标签对象(集合)

  • 通过dom操作:获取文本框输入的内容:文本框失去焦点,将获取的内容弹框出来

<body>
<!--<h3>hello,tomcat...</h3>-->

用户名:<input type="text" id="username"  name="user" class="user_class" onblur="getUserName()" />

</body>
<script>
    function getUserName() {
        //方式1:document.getElementById("id属性值") ;
       var username = document.getElementById("username");

        //方式2:document.getElementsByName("name属性值");获取的标签对象列表
        //var username = document.getElementsByName("user")[0];//通过name属性值获取标签对象

        //方式3:document.getElementsByClassName("所有的同名class属性值")---获取的是当前列表标签对象(集合)
       // var username = document.getElementsByClassName("user_class")[0];

        //方式4:document.getElenentsBtTagName("所有的同名的标签名称") ;-----获取的是当前列表标签对象(集合)
        //var username = document.getElementsByTagName("input")[0] ;

        //获取标签对象的文本内容
        alert(username.value) ;
    }
</script>

Servlet(Servlet Applet)

  • 针对服务端的程序的开发(服务端的连接器)

Servlet的本质

  • 狭义的规范 接口

  • 广义的规范:是一个能够实现Servlet接口的一个类

Servlet执行流程

  • 1)Web客户端向服务器发送请求 http://loclhost:8080/web工程名称/hello

  • 2)服务器接收请求,解析访问路径uri: /web工程/hello找当前web工程是否存在url-pattern为"/hello",web.xml去查找

  • 3)如果找不到,404---->找不到路径 如果找到了,解析servlet-mapping 获取url-pattern对应的servlt-name 在通过servlt-name找servlet的基本配置里面servlet-class : 当前servlet的全限定名称:包名.类名

  • 4)反射的方式Class.forName("包名.类名")--->Class clazz

  • 5)创建当前类实例----clazz.newIntance()---->Object obj

  • 6)获取当前字节码文件对象中Method类对象 Method method = clazz.getDeclaredMethod("doGet()",HttpServletRequest.class,HttpServletResponse.class) ;

  • 7)调用方法 method.setAccessiable(true) ; method.invoke(obj,request,response) ;

Servlet使用步骤(xml配置方式)

  • 1)导入servlet-api.jar

  • 2)在src下面创建一个类 MyServlet

    继承自HttpServlet (javax.servlet.http.HttpServlet)

  • 3)重写HttpServlt的doGet():执行前台get请求的提交/doPost()方法(执行前台post提交)

  • 4)需要在当前web工程WEB-INF的web.xml文件去配置servlet

<!--servlet的基本配置-->
<servlet>
<!--servlet的名称-->
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.qf.servlet_01.MyServlet</servlet-class>
</servlet>
<!--servlet的映射配置 访问的请求路径-->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<!--映射路径必须以"/指定的路径"-->
<url-pattern>/myFirst</url-pattern>
</servlet-mapping>

  •  5) 访问路径: http://localhost:8080/Web_02/myFirst       URL 属于URI子集

                        /Web_02/myFirst  :URI

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp/xml/ns/javaee"
         xmlns:xsi="http://www.w3/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp/xml/ns/javaee http://xmlns.jcp/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--servlet的基本配置-->
    <servlet>
        <!--servlet的名称
            当前类名
            -->
        <servlet-name>MyServlet</servlet-name>
        <!--
            指定当前servlet的全限定名称
        -->
        <servlet-class>com.qf.servlet_01.MyServlet</servlet-class>
    </servlet>
    <!--servlet的映射配置 访问的请求路径-->
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <!--映射路径必须以"/指定的路径"-->
        <url-pattern>/myFirst</url-pattern>
    </servlet-mapping>

使用idea自动创建Servlet(默认注解)

public class HelloServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("响应成功...");
        //解决响应给浏览器的中文乱码
        response.setContentType("text/html;charset=utf-8");

        //servlet完成的事情:并不是输出html页面...
        response.getWriter().write("<html>");
        response.getWriter().write("<head>");
        response.getWriter().write("<title>");
        response.getWriter().write("这是我的servlet");

        response.getWriter().write("</title>");
        response.getWriter().write("</head>");
        response.getWriter().write("<body><h3>Hello,Servlet</h3></body>");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

Servlet入门----执行get/post提交

public class MyServlet  extends HttpServlet {

    //执行get提交
    @Override
                        //Http协议:在请求的时候就创建了,服务器响应的时候就创建了
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //1)访问servlet---给tomcat发送请求
        //2)tomcat需要给浏览器进行相应:将响应数据封装到HttpServletResponse 响应对象
       //解决响应的中文乱码
        //void setContentType(String var1);
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("hello,这是我第一个Servlet");
    }
    //执行post提交
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        doGet(req,resp);
    }
}

Servlet的生命周期

  • void init(ServletConfig var1) throws ServletException;初始化

  • void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;业务服务方法

  • void destroy();servlet的销毁

Servlet的是一个单例的,线程不安全

当前我们定义的servlet就被创建一次,初始化也是一次

service方法是业务方法方法,不断被调用,因为我们使用具体的get提交还是post提交,覆盖的应该具体的doXXX()方法

public class ServletLife extends HttpServlet {

    /**
     * 提供无参构造方法
     */
    public ServletLife(){
        System.out.println("servletLife对象被创建了...");
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        //ServletConfig:接口  servlet的配置对象:每一个servlet都会自己的配置对象:
        // 获取servlet名称以及当前servlet的初始化参数
        System.out.println("servletLife初始化了...");
    }

    //servlet入口:业务方法服务方法
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("程序的入口service方法被调用了...");
    }

    //servlet销毁

    @Override
    public void destroy() {
        System.out.println("当前servlet被销毁了...");
    }
}

get提交和post提交

  • get提交和post提交后台接收参数的都是相同,所以后台在doPost将doGet()复用(get提交方式居多)或者是在doGet()/复用doPost

  • get提交tomcat8.0不会出现中文乱码(优化了)

  • post提交tomcat8.0必须解决中文乱码

public class GetArgsServlet extends HttpServlet {

    //doGet:接收get提交参数
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //前提一提交:
        //http://localhost:8080/Web_02/args?username=zhangsanfeng123&password=12345678&repwd=12345678&email=zhangsan%40qq

        //HttpServletRequest接口
        //String getParameter(String var1);接收前台提交过来的参数 (在doPost通用)  通过参数名称获取参数值
        // Enumeration<String> getParameterNames(); 获取所有的参数名称
        //前提要求:必须在页面上指定name属性的属性值:给后台标记内容

       String username = request.getParameter("username");
        System.out.println("username:"+username);
        String password = request.getParameter("password");
        System.out.println("password:"+password);
        String email = request.getParameter("email");
        System.out.println("email:"+email);

       //Enumeration<String> getParameterNames();
        Enumeration<String> enums = request.getParameterNames();
        while(enums.hasMoreElements()){
            //获取下一个元素
            String parameterName = enums.nextElement();
            //在通过参数名称获取参数值
            String value = request.getParameter(parameterName);
            System.out.println(parameterName+"----"+value);
        }
    }

    //接收post提交
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //将doGet()复用
        doGet(request,response);

       一次获取单个参数
        String getParameter(String var1);接收前台提交过来的参数
         String username = request.getParameter("username");
        System.out.println("username:"+username);
        String password = request.getParameter("password");
        System.out.println("password:"+password);
        String email = request.getParameter("email");
        System.out.println("email:"+email);

          //  Enumeration<String> getParameterNames();
      Enumeration<String> enums = request.getParameterNames();
        while(enums.hasMoreElements()){
            //获取下一个元素
            String parameterName = enums.nextElement();
            //在通过参数名称获取参数值
            String value = request.getParameter(parameterName);
            System.out.println(parameterName+"----"+value);
        }
    }
}

doGet()和doPost()关于中文乱码

  • doPost()必须解决前提提交的中文乱码(dopost提交的文件是加密状态所以会乱码)

  • doget()不需要解决中文乱码,tomcat8.0以后优化了

public class ServletResolveEncoding extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //解决post提交乱码
        request.setCharacterEncoding("utf-8");
        //解决响应给浏览器的中文乱码
        response.setContentType("text/html;charset=utf-8");

        //获取前提提交参数:中文格式
        //获取用户名
        String username = request.getParameter("username");
        System.out.println("username:"+username);

    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //HttpServletReuqest它的父接口中有就这个方法
        //void setCharacterEncoding(String var1) throws UnsupportedEncodingException;
     /*   request.setCharacterEncoding("utf-8");*/

        //获取前提提交参数:中文格式
       /* //获取用户名
        String username = request.getParameter("username");
        System.out.println("username:"+username);*/

       doGet(request,response);
    }
}

Servlet默认访问的时候创建当前类对象

  • web容器反射的方式创建

  • 配置:初始化时机:默认的时候访问serlvet的创建

  • 在web容器启动的时候,就创建Servlet对象

  • 数字越小,优先级越大(默认1)

public class MyServlet extends HttpServlet {
   /* public MyServlet(){
        System.out.println("MyServlet对象创建了...");
    }*/

   //初始化: 就可以配置对象获取初始化参数
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init方法被调用了...");

        //获取ServletConfig对象:接口 代表每一个servlet的配置对象
        //在父类中的父类有一个成员方法
        //ServletConfig getServletConfig()
        //this:代表当前Servlet对象的地址值引用(web容器创建)

        //public String getServletName()
        String servletName = config.getServletName();
        System.out.println(servletName);
        System.out.println("------------------------");

        //作用2;获取初始化参数init-param参数值
        //String getInitParameter(String var1);通过初始化参数名称的参数值
        String path = config.getInitParameter("path");
        System.out.println(path);
        //后面:进行io流文件传输(复制)
    }
   
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("业务方法service调用了....");
    }

    @Override
    public void destroy() {
        System.out.println("servlet被销毁了...");
    }

   @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取ServletConfig对象:接口 代表每一个servlet的配置对象
        //在父类中的父类有一个成员方法
        //ServletConfig getServletConfig()
        //this:代表当前Servlet对象的地址值引用(web容器创建)
        ServletConfig servletConfig = this.getServletConfig();
        //public String getServletName()
        String servletName = servletConfig.getServletName();
        System.out.println(servletName);
        System.out.println("------------------------");

        //作用2;获取初始化参数init-param参数值
        //String getInitParameter(String var1);通过初始化参数名称的参数值
        String path = servletConfig.getInitParameter("path");
        System.out.println(path);
        //后面:进行io流文件传输(复制)

        //获取当前servlet的名称
        //获取初始化参数
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

ServletContext(全局对象)

ServletContext作用1

获取上下文路径 jsp/html :href/src(写路径:最好使用全局路径):绝对不会出现404 html:http://localhost:8080/URI

public class ServletContextDemo1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        1)先获取ServletContext 接口(web容器反射创建)
        //public ServletContext getServletContext()
        ServletContext servletContext = this.getServletContext();
        2)获取上下文路径 String getContextPath();
        String contextPath = servletContext.getContextPath();
        //URI:/Servlet_jsp_war_exploded/contextDemo1
        System.out.println(contextPath); //是URI的一部分 /Servlet_jsp_war_exploded*/

       //HttpServletRequest
        //请求信息: 请求行+key(请求头):value)内容)
        //GET /Servlet_jsp_war_exploded/contextDemo1 HTTP/1.1
        // 获取url和uri
        //String getRequestURI();
        //    StringBuffer getRequestURL();
        String url = request.getRequestURL().toString();
        System.out.println("url:"+url);
        String uri = request.getRequestURI();
        System.out.println("uri:"+uri);
        String protocol = request.getProtocol();//获取协议版本号(Http/1.1反复请求)

        System.out.println("protocol:"+protocol);
        //获取默认提交方式
        String method = request.getMethod();
        System.out.println("method:"+method);

        //获取请求头信息
        //String getHeader(请求头名称)---> 获取内容
        String header = request.getHeader("User-Agent");//用户使用的浏览器类型
        if(header.contains("Chrome")){
            System.out.println("你使用的谷歌浏览器");
        }else if(header.contains("firefox")){
            System.out.println("你使用的火狐浏览器");
        }else{
            System.out.println("浏览器未知...");
        }
        System.out.println("----------------------");

       简化格式
        //HttpServletRequest
        //获取上下文
        // 路径 String getContextPath();
        String contextPath = request.getContextPath();
        System.out.println(contextPath);

    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

ServletContext作用2

  • 获取全局配置参数
public class ServletContextDemo2 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
        //获取全局参数
        //String getInitParameter(String var1);
        String value = servletContext.getInitParameter("characterEncoding");
        System.out.println("value:"+value);
        //解决post提交的中文乱码
        request.setCharacterEncoding(value);
        //解决响应的乱码
        response.setContentType("text/html;charset="+value+"");
        response.getWriter().write("Servletcontext的作用2,获取全局参数配置");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

ServletContext作用3

  • 请求转发 本质属于"服务器行为"

  • 当前请求当前后台/contextDemo3 跳转到前前台 login.html 登录页面中

public class ServletContextDemo3 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //获取全局对象
      /*  ServletContext servletContext = this.getServletContext();

        //public RequestDispatcher getRequestDispatcher(String path)
        //获取当前项目的请求分发器(接收web客户端的请求之后,将请求通过服务器进行转发到指定的页面上)
        //路径必须"/"
        RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/login.html");
        //public void forward(ServletRequest request, ServletResponse response)
        //从当前servlet后台转发到前台资源地址上
        requestDispatcher.forward(request,response);*/

      //请求转发的简写格式
        //public RequestDispatcher getRequestDispatcher(String path)被封装请求对象中
        //请求转发不需要携带上下文路径
        //request.getRequestDispatcher("/login.html").forward(request,response);
        request.getRequestDispatcher("/WEB-INF/hello.html").forward(request,response);

        System.out.println("请求转发成功...");

    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

ServletContext作用4

  • 作为"域对象"

User实体类

public class User{
    private String username ;
    private String password ;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

保存数据

public class ServletDemo1 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1)获取全局对象
        ServletContext servletContext = this.getServletContext();
        //2)public void setAttribute(String name, Object object)
       /* List<String> list = new ArrayList<>() ;
        list.add("eric") ;
        list.add("jakcy") ;
        list.add("Lee") ;
          servletContext.setAttribute("list",list);
        */

        User user = new User() ;
        user.setUsername("张三");
        user.setPassword("123456");
        //将属性名称对应的值进行绑定
        servletContext.setAttribute("user",user);
        System.out.println("保存数据成功...");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

获取数据

public class ServletDemo2 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //1)获取全局对象
        ServletContext servletContext = this.getServletContext();
        //2)当前域对象中获取数据
        //public Object getAttribute(String name):获取在域对象中绑定的内容,通过属性名称
     /*   List<String> list = (List<String>) servletContext.getAttribute("list");
        for (String s : list) {
            System.out.println(s);
        }*/

        User user = (User) servletContext.getAttribute("user");
        System.out.println("用户名是:"+user.getUsername());

        System.out.println("获取数据成功...");

    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

使用注解方式

  • name 属性:指定当前servlet名称--- 等价于xml配置方式 servlet-name

  • url-patterns 和value属性都是一样:返回值String[]

//@WebServlet(urlPatterns = {"/user"})
@WebServlet("/user") //必须以"/开头"
public class UserServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //创建User对象
        User user  = new User() ;
        //设置用户名和密码
        user.setUsername("张三");
        user.setPassword("123456");

        //将user对象存储在request域中
        request.setAttribute("user",user);

        //请求转发到/el/02_el.jsp
        request.getRequestDispatcher("/el/02_el.jsp").forward(request,response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

web.xml文件

<servlet>
        <servlet-name>ServletDemo1</servlet-name>
        <servlet-class>com.qf.servletcontext_04.ServletDemo1</servlet-class>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ServletDemo2</servlet-name>
        <servlet-class>com.qf.servletcontext_04.ServletDemo2</servlet-class>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>ServletDemo2</servlet-name>
        <url-pattern>/demo2</url-pattern>
    </servlet-mapping>

请求转发的特点

  • 1)地址栏没有明显变化:始终访问后台某个地址.

  • 2)请求转发只能访问当前项目下的资源文件(html/jsp),以及包含WEB-INF的资源文件,将jsp/html放在WEB-INF:为了数据安全(只能通过请求转发来访问)

  • 3)请求转发的整个过程:是服务器行为:有web容器内部通过RequestDispatcher分发器来完成的事情,请求对象request对象一致

  • 4)请求转发不能跨工程访问别的资源文件,只能在当前项目下

域对象

  • 就是可以在不同的servlet之间进行"数据共享"----web容器(tomcat')

四种域对象

数据类型/对象名称范围(从小到大)
PageContext(page域)在某一个jsp页面中有效
HttpServletRequest(request域)在一次请求中有效
HttpSession(session域)在一次会话中有效(存储在服务器端)
ServletContext(context/application)全局对象:在整个web工程下有效(web容器一直处于运行状态)

5个非域对象

数据对象/对象名称意思
ServletConfig(config)配置对象
JspWriter(out)字符输出流,向浏览器写内容
Object(this)代表当前jsp对象(类)地址值引用
Throwable(t)异常:当jsp中出现异常,获取异常信息
HttpServlerResponse

HttpServletRequest域对象

public class RequestServletDemo extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //通过request 作为域对象,给里面存储一些数据
        request.setAttribute("name","高圆圆");
        System.out.println("存储成功...");

        //需要请求转发到01_jsp的引入.jsp页面中
        request.getRequestDispatcher("/01_jsp的引入.jsp").forward(request,response);

    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

web.xml文件

<servlet>
        <servlet-name>RequestServletDemo</servlet-name>
        <servlet-class>com.qf.request_04.RequestServletDemo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RequestServletDemo</servlet-name>
        <url-pattern>/requestDemo</url-pattern>
    </servlet-mapping>

Jsp(Java Server Page)(Java服务页面)

  • 能够处理后台的业务数据 (能够书写代码/提供很多标签库去使用)

  • 只限定于Java语言,能够和后台服务器端程序进行交互 :主要展示视图层,服务端程序,获取数据

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsp的引入</title>
</head>
<body>
<%--
    jsp能够书写java代码
    jsp的脚本
--%>
<%
    //jsp脚本
    String name = (String) request.getAttribute("name");
    //jsp的内置对象   Writer----out给浏览器书写内容
    out.write("name:"+name);
    //System.out.println("name:"+name);

    int i  = 10 ;

%>
<%--jsp的输出表达式--%>
<%=i%>

<hr/>
${requestScope.name}
<%--jsp的el表达式 去替代jsp的输出表达式--%>
<h3>name</h3>${name}

</body>
</html>

Jsp的执行两个阶段

1)hello.jsp---->通过web容器 "翻译"  成  hello_jsp.java文件


            会将当前jsp页面中所有内容通过JspWriter:输出对象给浏览器中拼接内容
class hello_jsp    ---->规定了jsp的生命周期 :_jspInit()  _jspService(请求对象,响应对象)
                                           _jspDestory()
                                           
 2)第二个阶段:需要将hello_jsp.java----hello_jsp.class   ---字节码文件对象         (web容器通过


 反射机制(内省机制)获取当前类对象,调用_jspservice:程序入口方法)   
 Jsp本质就是 Servlet
 public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase{}
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {}

Jsp的三大指令

指令1:%@page%

  • import:导入java的一些核心类或者接口

  • contentType="text/html;charset=UTF-8" 设置jsp的内容格式以及编码

  • language="java":只支持Java语言

  • buffer:jsp默认的缓冲区大小(jsp中可以不断向浏览器输出:写数据过去):默认8kb(一般不用设置)

  • errorPage:当jsp发生异常,跳转到错误页面上

  • session:是否启用HttpSession域对象, (不用去设置,默认就是自动启动)

  • isErrorPage:当前页面是否为错误页面 默认false

<html>
<head>
    <title>Title</title>
</head>
<body>
<%--jsp的脚本--%>
<%
        //定义变量
        int i = 100 ;
        System.out.println("i:"+i);//控制台打印
        //向浏览器写入内容
        out.write("i:"+i);

        int b = 10 / 0 ;
%>
<%--jsp的输出表达式--%>
i的值是:
<%=i%>
</body>
</html>

指令2:<%@include jsp静态导入%>

  • file属性:导入资源文件

  • 原理 不会将被导入的jsp文件单独进行翻译和编译,而只是将当前被导入jsp文件的内容加载进来,节省内存!

指令3:<%@taglib 导入jsp的核心标签库jstl%>

el表达式

  • el表达式就是为了简化书写方式,代替<%=jsp的输出表达式%>

  • ${域.属性名称} ----获取预对象中该属性名称绑定的实际内容

<body>
<h3>没有使用el表达式之前的写法</h3>
<%
        //给pageContext域中绑定数据
        //pageContext.setAttribute("name","lucy");
        //给reqest域中绑定数据
        request.setAttribute("name","eric");
        //给session域中绑定数据
       // session.setAttribute("name","zhangsan");

        //给applictation域中绑定数据
       // application.setAttribute("name","蒋乐乐") ;

%>
<%=request.getAttribute("name")%>

<hr/>

<h3>使用el表达式</h3>
<%--   ${域.属性名称} --%>
<%--name是:${requestScope.name}  -   name是:${sessionScope.name}--%>
<%--name是:${pageScope.name}<br/>
name是:${applicationScope.name}--%>

<%--最终的简化格式
        直接将域的写法省略了
        ${域对象中绑定参数名称}---就会从四个域对象中搜索,从小到大,
            绑定到这个参数名称,先使用这个数据: 使用最多的域对象就是request!
--%>
${name}
</body>

el语法(JavaBean)

  • JavaBean导航:操作实体 JavaBean设计规范:

  • 1)当前类是具体类(公共的类)

  • 2)具备私有字段(私有的成员变量

  • 3)提供setXXX()/getXXX()公共方法,暴露出来

  • 4)实现序列化接口serializable

${user.username}   -   ${user.password}

//@WebServlet(urlPatterns = {"/user"})
@WebServlet("/user") //必须以"/开头"
public class UserServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //创建User对象
        User user  = new User() ;
        //设置用户名和密码
        user.setUsername("张三");
        user.setPassword("123456");

        //将user对象存储在request域中
        request.setAttribute("user",user);

        //请求转发到/el/02_el.jsp
        request.getRequestDispatcher("/el/02_el.jsp").forward(request,response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

练习:网页登录访问商品界面并对其增删查改

管理员类(Admin)

public class Admin {
    private int id ;//编号
    private String name ;//管理员名称
    private String password ;//密码


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Admin{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

商品实体类(Product)

public class Product {
    /**
     * id INT PRIMARY KEY AUTO_INCREMENT,
     * 	pname VARCHAR(20),
     * 	pprice int,
     * 	pdesc VARCHAR(50)
     */
    private int id ;
    private String pname ;
    private int pprice ;
    private String pdesc ;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public int getPprice() {
        return pprice;
    }

    public void setPprice(int pprice) {
        this.pprice = pprice;
    }

    public String getPdesc() {
        return pdesc;
    }

    public void setPdesc(String pdesc) {
        this.pdesc = pdesc;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", pname='" + pname + '\'' +
                ", pprice=" + pprice +
                ", pdesc='" + pdesc + '\'' +
                '}';
    }
}

用户的数据访问接口(UserDao)

import com.qf.pojo.Admin;

public interface UserDao {

    /**
     * 通过管理员的用户名查询当前管理员实体
     * @param name  管理员的用户名
     * @return  返回Admin实体对象
     */
    Admin selectUserByName(String name ) ;
}

用户的数据访问接口实现(UserDaoImpl)

import com.qf.dao.UserDao;
import com.qf.pojo.Admin;
import com.qf.utils.DruidJdbcUtils;
import org.apachemons.dbutils.QueryRunner;
import org.apachemons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

public class UserDaoImpl  implements UserDao {

    /**
     * 通过管理员的用户名查询当前管理员实体
     * @param name  管理员的用户名
     * @return  返回Admin实体对象
     */
    @Override
    public Admin selectUserByName(String name) {
        try {
            //创建执行对象
            QueryRunner qr  = new QueryRunner(DruidJdbcUtils.getDataSource()) ;
            //准备sql语句
            String sql = "select * from admin where name = ?" ;
            //将查询某一条记录封装到是一个实体类中
            Admin admin = qr.query(sql, new BeanHandler<Admin>(Admin.class), name);
            return  admin ;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

访问商品数据的接口(ProductDao )

import com.qf.pojo.Product;

import java.util.List;

public interface ProductDao {
    /**
     * 查询所有的商品数据
     * @return
     */
    List<Product> selectProductAll() ;
}

商品访问接口实现(ProductDaoImpl )

import com.qf.dao.ProductDao;
import com.qf.pojo.Product;
import com.qf.utils.DruidJdbcUtils;
import org.apachemons.dbutils.QueryRunner;
import org.apachemons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

public class ProductDaoImpl implements ProductDao {
    @Override
    public List<Product> selectProductAll() {
        try {
            //创建执行对象
            QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource()) ;
            String sql = "select * from product" ;
            List<Product> list = qr.query(sql, new BeanListHandler<Product>(Product.class));
            return list ;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

登录前端界面(login.html)

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2021/8/27
  Time: 11:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="utf-8">
    <title>盒子模型应用</title>
    <style>
        #formDiv{
            /* 指定大div边框 */
            border: 1px solid #000;
            /* 设置宽和高度容量 */
            width: 450px;
            height: 300px;

            /* 设置div的外边距 */
            margin: 150px 0 0 400px;
            /* css背景属性 */
            /* background: darkgray url(./image/index_3.jpg) no-repeat center top; */
            background: darkgray  no-repeat center top;
        }

        /* 修饰用户名所在div */
        #user_div{
            margin: 50px 0 0 100px;
        }
        /* 修饰密码所在div */
        #password_div{
            margin: 20px 0 0 100px;
        }
        /* 修饰复选框所在div */
        #checkbox_div{
            margin: 20px 0 0 150px;
        }
        /* 修饰id="btn_div"的div*/
        #btn_div{
            margin: 20px 0 0 170px;
        }
        /* 修饰id="reg_btn"的外边距" */
        #reg_btn{
            margin-left: 30px;
        }

        #spanTip{
            font-size: 20px;
            color: red;
            text-align: center;
        }
        #msgTip{
            margin: 5px 0 0 10px;
        }
    </style>
</head>
<!--
    大的div中 包含三个div
            用户名所在div
            密码所在div
            特殊按钮div

            div+css:盒子模型 进行层级布局
 -->
<body>
<div id="formDiv">

    <div id="msgTip">
        <p style="text-align: center">管理员登录</p>
        <span id="spanTip">${msg}</span>
    </div>
    <form action="${pageContext.request.contextPath}/login" method="post">
<%--
            表单项中的name属性必须和Javabean的实体的属性名称一致
--%>
        <div id="user_div">
            用户名:<input type="text" name="name" placeholder="请输入用户名" />
        </div>
        <div id="password_div">
            密&ensp;&ensp;码:<input type="password" name="password" placeholder="请输入密码" />
        </div>
        <div id="checkbox_div">
            <input type="checkbox" value="remember me" />remember me
        </div>
        <div id="btn_div">
            <input  type="submit" value="登录" /><input type="submit" id="reg_btn" value="注册" />
        </div>

    </form>
</div>
</body>
</html>

商品表格界面(list.jsp)

<%@taglib prefix="c" uri="http://java.sun/jsp/jstl/core" %>
<html>
<head>
    <title>获取表格数据</title>
</head>
<body>
    <table style="border-collapse: collapse" border="1px" width="500px" height="400px">
        <tr>
            <th>商品编号</th>
            <th>商品名称</th>
            <th>商品价格</th>
            <th>商品描述</th>
        </tr>
        <c:forEach var="product" items="${list}">   <%--每一个都实体对象 --%>
            <tr>
                <td>${product.id}</td>  <%--getXXX()  get()去掉 xxxbean属性--%>
                <td>${product.pname}</td>
                <td>${product.pprice}</td>
                <td>${product.pdesc}</td>
            </tr>
        </c:forEach>
       <%-- <tr>
            <td>1</td>
            <td>华为mate30</td>
            <td>5999</td>
            <td>为照相而生</td>
        </tr>

        <tr>
            <td>2</td>
            <td>小米10</td>
            <td>4999</td>
            <td>为发烧而生</td>
        </tr>--%>
    </table>
</body>
</html>

连接池工具类(DruidJdbcUtils)

package com.qf.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author Kuke
 * @date 2021/8/18
 * 工具类---->DataSource----->获取数据库的连接对象 Connection以及后期管理事务
 *
 * 获取连接对象----静态方法
 * 关闭资源-----静态方法
 */
public class DruidJdbcUtils {

    //成员变量位置
    private  static DataSource ds ;
    //为了保证线程安全:每一线程使用自己的Connection (张三/李四)
    private static ThreadLocal<Connection>  t1 = new ThreadLocal<>() ; //提供线程的局部变量保存连接对象



    //构造方法私有化
    private DruidJdbcUtils(){}

    //静态代码块
    static{
        try {
            //读取数据库连接池的配置文件----->通过DruidDataSourceFactory工厂类创建DataSource
            //创建一个属性集合列表
            Properties prop = new Properties() ;
            //读取druid.properties
            InputStream inputStream = DruidJdbcUtils.class.getClassLoader().
                    getResourceAsStream("druid.properties");

            //将资源文件所在的输入流加载列表中
            prop.load(inputStream);
            ds = DruidDataSourceFactory.createDataSource(prop); //底层子实现类:DruidDataSource
            //System.out.println("数据源获取成功");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //提供静态方法:单独获取数据源
    public static DataSource getDataSource(){
        return ds ;
    }


    //获取连接对象Connection静态功能

    public static Connection getConnection(){
        //从ThreadLocal中获取局部变量的副本:Connection
        /**
         *   public T get()  :从线程中获取局部变量的副本!
         */
        Connection conn =  null ;
        try {
            conn  =  t1.get();
            if(conn==null){
                //如果空,需要从数据库的连接池中获取连接对象
                 conn  = ds.getConnection();
                //获取到之后,每一线程执行自己的Connection
                //将获取到的连接对象 绑定到当前线程中
                t1.set(conn);
            }
            //如果不为空,说明ThreadLocal线程中已经存在Connection
            return conn ; //
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null ;

    }

    //关闭(释放资源)资源
    public static void close(ResultSet rs, Statement stmt,Connection conn)  {
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
                //关闭之后,归还到连接池中,需要从当前线程中解绑
                t1.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void close( Statement stmt,Connection conn)  {
        close(null,stmt,conn);
    }

    //事务管理代码 --- 加入

    public static void main(String[] args) {
       // DataSource ds = DruidJdbcUtils.getDataSource();
        //System.out.println(ds);


        Connection connection = DruidJdbcUtils.getConnection();
        System.out.println(connection);
    }
}

配置文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb_01?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000

数据库部分(Mysql)

create table admin(
 id int primary key auto_increment,
 name varchar(20),
 password varchar(20)

);

insert into admin(name,password) values('admin','admin'),('hjl','123456');

create table product(
id int primary key auto_increment,
pname varchar(20),
pprice int,
pdesc varchar(50)
);

insert into product(pname,pprice,pdesc) values('华为mate30',4299,'牛逼克拉斯'),('ipone11',4799,'垃圾苹果'),('小米',4299,'友商是sb'),('锤子',3299,'又不是不能用');

用户登录的控制器(LoginServlet)

package com.qf.controller;

import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //解决post提交的中文乱码
        request.setCharacterEncoding("utf-8");
        //设置响应乱码
        response.setContentType("text/html;charset=utf-8");

        //1)接收前台的参数
        String name = request.getParameter("name");
      //  System.out.println(name);
        String password = request.getParameter("password");

        //2)创建Service层接口对象
        UserService userService = new UserServiceImpl() ;
        boolean flag = userService.getUser(name, password);

        //3)判断结果
        if(flag){
            //true:登录成功
            //给request域对象中存储数据
            // request.setAttribute("msg","恭喜你,登录成功!");
            //跳转到主页
         //   request.getRequestDispatcher("/index.jsp").forward(request,response);
                                                    //@WebServlet("/findAllproduct")
            //跳转查询所有商品的页面--->跳转后台地址 ProductServlet
            request.getRequestDispatcher("/findAllproduct").forward(request,response);
        }else{
            request.setAttribute("msg","用户名或者密码输入错误");
            //4)请求转发到login.jsp
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

针对的商品模块后台入口(ProductServlet)

import com.qf.pojo.Product;
import com.qf.service.ProductService;
import com.qf.service.impl.ProductServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/findAllproduct")
public class ProductServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //调用service
        ProductService productService = new ProductServiceImpl() ;
        List<Product> list = productService.getAllProduct();

        //将list存储request域中
        request.setAttribute("list",list);
        //请求转发到list.jsp
        request.getRequestDispatcher("/list.jsp").forward(request,response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

更多推荐

css操作,js(javascript),Servlet,jsp(Java Server Page),el表达式,练习:网页登录访问商品界面并对其增删查改

本文发布于:2023-04-29 20:34:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/f1a93ef569c16159cc937bdb6fbe2cd7.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:对其   表达式   界面   操作   网页

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 112130文章数
  • 28535阅读数
  • 0评论数