使用CSS样式排版出如图所示的效果 每过3秒中切换一张图片的效果,一共5张图片,当显示到最后1张的时候,再次显示第1张。 window对象与location对象的综合案例应用 页面上显示一个倒计时5秒的数字,到了5秒以后跳转到另一个页面 页面上有两个按钮,一个开始按钮,一个暂停按钮。点开始按钮时间开始走动,点暂停按钮,时间不动。再点开始按钮,时间继续走动。 页面上有两个下拉列表框,页面加载的时候访问数据库,得到所有的省份显示在第1个列表框中。当选择不同的省份的时候,加载这个省份下所有的城市显示在第二个下拉列表中。 用户注册,需要进行如下验证,请在JS中使用正则表达式进行验证。 选中大于0的tr的偶数行的选择器怎么写? 设置某个复选框选中的方法是什么? 使用今天学习的内容制作一个购物车案例 了解原生的ajax如何去实现这个案例 用户注册时输入一个用户名,失去焦点以后,通过ajax后台判断用户名是否存在。服务器先不访问数据库,直接判断用户名,如果用户名为newboy,则表示用户已经存在,否则用户名可以注册使用。 准备数据文件 users.json 浏览器端的访问流程 在输入框输入关键字,下拉框中异步显示与该关键字相关的用户名称 search.json 链接下载文件存在的问题 技术点,需要设置以下响应头才可以实现下载 注:IE、Chrome下载中文采用的是URL编码,注:FireFox不能采用这种方式。 下载需要设置哪个响应头? 如果下载文件名中有汉字使用哪个方法编码? 如果用户是第一次访问,则输出:您好,您是第1次访问,欢迎您的加入!当前的时间是xxx 如果之前已经访问过,则从Cookie中得到上次访问的时间,显示:您好,欢迎您再次访问。 上次访问的时间是:xxxx,当前的时间是xxxxx。 无论是否是第一次访问,都要把这次访问服务器的时间写到Cookie中 能够使用Cookie保存用户名和密码 LoginServlet 浏览器端代码的实现 login.html commons.js 有一个商品页面,可以点击超链接将商品添加到购物车,并可以查看购物车中商品信息 购物车要保存在哪个作用域? 显示商品列表页面 添加到购物车的Servlet 查看购物车的Servlet 编写过滤器,过滤所有Servlet中使用POST方法提交的汉字的编码。 编写一个过滤器就可以对所有的Servlet进行汉字编码 当用户发帖的时候,如果发出敏感词汇就进行过滤,并提示发贴失败,否则显示正常的发贴内容。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLHsXleM-1592189481791)(C:UsersAdministratorDesktopstudyzimg1592189067781.png)] 过滤敏感词汇过滤器的开发步骤: 每当一个用户访问项目的时候,都会创建一个session会话。所以当前session会话被创建,当前在线用户+1,每当session会话被销毁,当前在线用户-1。 HttpSessionListener可以用来监听session对象的创建和销毁的。所以可以在HttpSessionListener中的监听session对象创建和销毁的方法中控制在线人数的加减。 创建一个监听器 SessionCountListener a) 监听会话创建的方法 i. 在会话创建的监听方法中,从上下文域中取出当前计数值 ii. 如果为空,表示是第1个用户,设置值为1 iii. 不为空则加1,并且更新上下文域 b) 监听会话销毁的方法 i. 从上下文域中得到当前在线的人数 ii. 减1后更新 创建一个注销的LogoutServlet a) 让会话失效 b) 打印输出:您已经安全退出网站 编写JSP a) 在JSP上取出上下文域中用户数显示 b) 显示安全退出的链接 考虑线程安全问题 通过案例学习文件上传组件file-upload的使用 复制jar包 按以下流程编写上传的代码即可 页面 上传的Servlet tResponse; @WebServlet(“/upload”) }
案例:黑马旅游注册
目标
效果
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>黑马旅游注册</title> <style> /*table居中,宽300px,高180px; 边框solid 1px gray*/ table { width: 300px; height: 180px; margin: auto; border: solid 1px gray; border-radius: 10px; /*table添加背景,不平铺,图片背景的宽度和高度与table的宽和高一样。*/ background-image: url("img/bg1.jpg"); background-size: 300px 180px; } /*td的文字对齐居中,字体大小14px*/ td { text-align: center; font-size: 14px; } /*用户名和密码文本框使用ID样式,也可以使用其它选择器。宽150px,高32px,边框用实线,圆角5px,1个宽度,黑色*/ #user,#password { width: 150px; height: 32px; border: solid 1px black; border-radius: 5px; } /*使用伪类样式,当鼠标移动到文本框上的时候,变成虚线橙色边框。得到焦点,背景色变成浅黄色*/ #user:hover,#password:hover { border: dashed orange 1px; } #user:focus,#password:focus { background-color: lightyellow; } /*文本框前面有头像,密码框前面有键盘,左内边距35*/ #user { background-image: url("img/head.png"); background-repeat: no-repeat; /*左内边距为32*/ padding-left: 32px; } #password { background-image: url("img/keyboard.png"); background-repeat: no-repeat; /*左内边距为32*/ padding-left: 32px; } </style> </head> <body> <table> <tr> <!--跨2列--> <th colspan="2">黑马旅游注册</th> </tr> <tr> <td>用户名:</td> <td> <input type="text" id="user"> </td> </tr> <tr> <td>密码:</td> <td> <input type="password" id="password"> </td> </tr> <tr> <td colspan="2"> <input type="image" src="img/regbtn.jpg"> </td> </tr> </table> </body> </html>
案例:轮播图
目标
方法说明
方法
描述
document.getElementById(“id”)
作用:通过id获取网页上唯一的元素(标签)
参数:ID的值
window.setInterval(“函数名()”,时间)
window.setInterval(函数名,时间)作用:每隔一段时间调用一次指定的函数
参数1:要调用的函数名
参数2:隔多久调用,单位是毫秒需求
步骤
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>轮播图案例</title> <style> body { background-color: black; text-align: center; } </style> </head> <body> <img src="img/0.jpg" width="800" id="game"> </body> <script type="text/javascript"> //过2秒调用一次下面的图片 window.setInterval("changePic()", 2000); let num = 1; /* 创建一个函数:换图片 技术点:修改img元素的src属性即可 */ function changePic() { //通过id得到一个元素,注:这个方法必须在网页已经加载完元素之后执行。要注意这个代码出现的位置 let imgObj = document.getElementById("game"); //alert(imgObj); //修改图片元素的src属性:对象名.属性名 imgObj.src = "img/" + num + ".jpg"; //文件名数字加1 num++; //如果等于5,设置为0 if (num == 5) { num = 0; } } </script> </html>
效果
案例:倒计时页面跳转
目标
window中计时器有关的方法
window中的方法
作用
setTimeout(函数名, 间隔毫秒数)
过一段时间后调用一次指定的函数,单位是毫秒,只调用一次。
返回值是一个整数类型,这就是计时器
clearTimeout(计时器)
清除上面的计时器,参数的计时器就是上面方法的返回值
setInterval(函数名, 间隔毫秒数)
每隔一段时间调用一次指定的函数,单位是毫秒,不停的调用。
返回值是一个整数类型,这就是计时器
clearInterval(计时器)
清除上面的计时器,参数的计时器就是上面方法的返回值
需求
效果
分析
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>跳转</title> </head> <body> <span id="counter">5</span>秒以后跳转 <script type="text/javascript"> /* 分析: 1.用到倒计时:window.setInterval() 2.页面跳转:location.href 3.修改标签中文字使用属性:innerText */ let count = 5; setInterval("countDown()", 1000); //每过1秒调用一次 //调用的函数 function countDown() { //1.将数字减1 count--; //2.更新span中数字 document.getElementById("counter").innerText = count; //3.判断数字是否为0 if (count == 0) { //4.如果为0就进行页面跳转 location.href = "https://www.itcast.cn"; } } </script> </body> </html>
案例:会动的时钟
目标
步骤
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>会动的时钟</title> </head> <body> <input type="button" value="开始" id="btnBegin"> <!--disabled就元素不可用--> <input type="button" value="暂停" id="btnPause" disabled="disabled"> <hr/> <h1 id="clock" style="color: darkgreen"></h1> <script type="text/javascript"> let timer; //计时器 //开始按钮的点击事件 document.getElementById("btnBegin").onclick = function() { timer = setInterval("showTime()", 1000); //每过1秒调用1次 //修改disabled的属性为true,表示不可用,false表示可用 //让开始按钮不可用,让暂停按钮可用 document.getElementById("btnBegin").disabled = true; document.getElementById("btnPause").disabled = false; } //暂停按钮的点击事件 document.getElementById("btnPause").onclick=function () { document.getElementById("btnBegin").disabled = false; //开始按钮可用 document.getElementById("btnPause").disabled = true; //暂停按钮不可用 //让计时器失效 clearInterval(timer); //计时器是setInterval()的返回值 } /** * 分析: * 每过1秒钟输出现在的时间 * 不能使用document.write方法 * 应该放在一个标签内部,修改标签内部的内容,使用innerText或innerHTML */ function showTime() { //得到现在的时间 let now = new Date().toLocaleString(); //在有些浏览器上,会覆盖整个网页,导致这些脚本都没有了 //document.write(now); //在h1中显示时间 document.getElementById("clock").innerText = now; } </script> </body> </html>
案例:省市级联
案例需求
案例效果
实现步骤
示例代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>省市联动</title> </head> <body> <select id="province"> <option>--请选择省份--</option> </select> <select id="city"> <option>--请选择城市--</option> </select> </body> <script> // 省份数据 var provinces= ["广东省","湖南省","广西省"]; // 城市数据,数据是一个二维数组,一维中每个元素是一个数组 var cities = [["深圳","广州","东莞"],["长沙市","郴州市","湘潭市"],["南宁市","桂林市","柳州市"]]; /* 在页面加载完毕以后读取所有的省份,并且填充到#province中 分析:动态创建option对象,并且设置 <option value="0">广东省</option> 这个value就是它对应的城市数组索引 */ window.onload = function () { //1.得到省份这个select对象 let selectProvince = document.getElementById("province"); //遍历省份这个数组 for (let i = 0; i < provinces.length; i++) { let province = provinces[i]; //i=0 province=广东省 //2.创建option对象 let optionElement = document.createElement("option"); //3.设置value和文本 optionElement.value = i; optionElement.innerText = province; //4.添加到select的最后一个子元素: 父元素.appendChild(子元素) selectProvince.appendChild(optionElement); } } /** * 省份下拉列表的改变事件 */ document.getElementById("province").onchange = function () { //alert(this.value); //value就是它的索引 var arr = cities[this.value]; //得到相应城市的数组 //得到城市下拉select对象 let city = document.getElementById("city"); //city下拉列表对象 //修改city中innerHTML city.innerHTML = "<option>--请选择城市--</option>"; //覆盖原来的HTML子元素 //向城市下拉列表添加option //1. 遍历城市数组 for (let i = 0; i < arr.length; i++) { let arrElement = arr[i]; //每个城市字符串 //2. 创建option对象 <option>广州市</option> let optionElement = document.createElement("option"); //3. 设置文本 optionElement.innerText = arrElement; //4. 添加到select的最后一个子元素: 父元素.appendChild(子元素) city.appendChild(optionElement); } } </script> </html>
案例:校验注册表单
目标
onsubmit事件说明
onsubmit事件,如果return false就可以阻止表单提交
案例需求
案例分析
代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="https://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>验证注册页面</title> <style type="text/css"> body { margin: 0; padding: 0; font-size: 12px; line-height: 20px; } .main { width: 525px; margin-left: auto; margin-right: auto; } .hr_1 { font-size: 14px; font-weight: bold; color: #3275c3; height: 35px; border-bottom-width: 2px; border-bottom-style: solid; border-bottom-color: #3275c3; vertical-align: bottom; padding-left: 12px; } .left { text-align: right; width: 80px; height: 25px; padding-right: 5px; } .center { width: 280px; } .in { width: 130px; height: 16px; border: solid 1px #79abea; } .red { color: #cc0000; font-weight: bold; } div { color: #F00; } span { color: red; } </style> <script type="text/javascript"> /** * 校验所有的表单项 */ function checkAll() { return checkUser() && checkMobile(); } /** * 检查用户名是否正确 * 由英文字母和数字组成,长度为4~16个字符,并且以英文字母开头 */ function checkUser() { //1.得到文本框的值 let value = document.getElementById("user").value; //2.创建正则表达式 let reg = /^[a-zA-Z][a-zA-Z0-9]{3,15}$/; //3.比较正则表达式与文本框的值是否匹配 if (reg.test(value)) { //4.如果匹配就通过,在后面显示打勾的图片,返回true document.getElementById("userInfo").innerHTML = "<img src='img/gou.png' width='15'/>"; return true; } else { //5.如果不匹配,在后面显示错误信息,返回false document.getElementById("userInfo").innerHTML = "用户名格式有误"; return false; } } /** * 判断手机号 */ function checkMobile() { //1.得到文本框的值 let value = document.getElementById("mobile").value; //2.创建正则表达式 let reg = /^1[3456789]d{9}$/; //3.比较正则表达式与文本框的值是否匹配 if (reg.test(value)) { //4.如果匹配就通过,在后面显示打勾的图片,返回true document.getElementById("mobileInfo").innerHTML = "<img src='img/gou.png' width='15'/>"; return true; } else { //5.如果不匹配,在后面显示错误信息,返回false document.getElementById("mobileInfo").innerHTML = "手机格式有误"; return false; } } </script> </head> <body> <!-- onsubmit事件,如果return false就可以阻止表单提交--> <form action="server" method="post" id="myform" onsubmit="return checkAll()"> <table class="main" border="0" cellspacing="0" cellpadding="0"> <tr> <td><img src="img/logo.jpg" alt="logo"/><img src="img/banner.jpg" alt="banner"/></td> </tr> <tr> <td class="hr_1">新用户注册</td> </tr> <tr> <td style="height:10px;"></td> </tr> <tr> <td> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <!-- 不能为空, 输入长度必须介于 5 和 10 之间 --> <td class="left">用户名:</td> <td class="center"> <!--文本框失去焦点进行验证--> <input id="user" name="user" type="text" class="in" onblur="checkUser()"/> <span id="userInfo"></span> </td> </tr> <tr> <!-- 不能为空, 输入长度大于6个字符 --> <td class="left">密码:</td> <td class="center"> <input id="pwd" name="pwd" type="password" class="in"/> </td> </tr> <tr> <!-- 不能为空, 与密码相同 --> <td class="left">确认密码:</td> <td class="center"> <input id="repwd" name="repwd" type="password" class="in"/> </td> </tr> <tr> <!-- 不能为空, 邮箱格式要正确 --> <td class="left">电子邮箱:</td> <td class="center"> <input id="email" name="email" type="text" class="in"/> </td> </tr> <tr> <!-- 不能为空, 使用正则表达式自定义校验规则,1开头,11位全是数字 --> <td class="left">手机号码:</td> <td class="center"> <input id="mobile" name="mobile" type="text" class="in" onblur="checkMobile()"/> <span id="mobileInfo"></span> </td> </tr> <tr> <!-- 不能为空, 要正确的日期格式 --> <td class="left">生日:</td> <td class="center"> <input id="birth" name="birth" type="text" class="in"/> </td> </tr> <tr> <td class="left"> </td> <td class="center"> <input name="" type="image" src="img/register.jpg"/> </td> </tr> </table> </td> </tr> </table> </form> </body> </html>
案例:表格隔行换色与全选全不选
目标
效果
步骤
隔行变色
全选全不选
代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>隔行换色/全选全不选</title> <style type="text/css"> table { border-collapse: collapse; } tr { height: 35px; text-align: center; } a:link { text-decoration: none; } </style> <script type="text/javascript" src="js/jquery-3.3.1.js"></script> <script type="text/javascript"> $(function () { //隔行变色,除了第1行之外,even表示偶数行,剩下的行中偶数行 $("tr:gt(0):even").css("background-color", "lightgreen"); $("tr:gt(0):odd").css("background-color", "lightyellow"); //全选,全不选 $("#all").click(function () { //最上面的复选框点击事件 //得到all的值是true或是false //选中所有下面的checkbox $("input[name=item]").prop("checked", $("#all").prop("checked")); //设置boolean类型的属性 }); }) </script> </head> <body> <table id="tab1" border="1" width="700" align="center"> <tr style="background-color: #999999;"> <td><input type="checkbox" id="all"></td> <td>分类ID</td> <td>分类名称</td> <td>分类描述</td> <td>操作</td> </tr> <tr> <td><input type="checkbox" name="item"></td> <td>1</td> <td>手机数码</td> <td>手机数码类商品</td> <td><a href="">修改</a>|<a href="">删除</a></td> </tr> <tr> <td><input type="checkbox" name="item"></td> <td>2</td> <td>电脑办公</td> <td>电脑办公类商品</td> <td><a href="">修改</a>|<a href="">删除</a></td> </tr> <tr> <td><input type="checkbox" name="item"></td> <td>3</td> <td>鞋靴箱包</td> <td>鞋靴箱包类商品</td> <td><a href="">修改</a>|<a href="">删除</a></td> </tr> <tr> <td><input type="checkbox" name="item"></td> <td>4</td> <td>家居饰品</td> <td>家居饰品类商品</td> <td><a href="">修改</a>|<a href="">删除</a></td> </tr> </table> </body> </html>
小结
tr:gt(0):even
jq对象.prop("checked",true)
案例:实现购物车
目标
需求
效果
代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>购物车的实现</title> <style type="text/css"> table { width: 400px; border-collapse: collapse; margin: auto; } td,th { text-align: center; height: 30px; } .container { width: 400px; margin: auto; text-align: right; } img { width: 100px; height: 100px; } th { background-color: lightgray; } tr:hover { background-color: lightyellow; } </style> <script type="text/javascript" src="js/jquery-3.3.1.js" ></script> <script type="text/javascript"> //添加到购物车的点击事件 function addRow() { //1.获取文本框中内容 let val = $("#pname").val().trim(); //去掉前后的空格 if (val == "") { //注:不同于Java alert("商品名字不能为空"); //让文本框获得焦点 $("#pname").focus(); return; } //2.创建tr let tr = "<tr>" + "<td><img src="img/girl.jpg" /></td>" + "<td>" + val + "</td>" + "<td><input type="button" value="删除" οnclick="deleteRow(this)"></td>" + "</tr>"; //3.创建好的tr的放到父元素tbody中 $("#cart").append(tr); //4.清空文本框内容 $("#pname").val(""); } //删除一行 function deleteRow(obj) { //obj其实就是一个按钮对象,这是JS对象,转成JQ对象 if (confirm("真的要从购物车中移除这件商品吗?")) { //按钮的父元素->td 的父元素 -> tr 删除tr即可 $(obj).parent().parent().remove(); //自己删除自己 } } </script> </head> <body> <div class="container"> <table border="1"> <tbody id="cart"> <tr> <th> 图片 </th> <th> 商品名 </th> <th> 操作 </th> </tr> <tr> <td><img src="img/sx.jpg" /></td> <td> 三星Note7 </td> <td> <!--this表示当前按钮--> <input type="button" value="删除" onclick="deleteRow(this)"> </td> </tr> </tbody> </table> <br /> 商品名: <input type="text" id="pname" value="" /> <input type="button" value="添加到购物车" onclick="addRow()" /> </div> </body> </html>
小结
1. 创建tr 2. 添加到tbody中 3. 删除元素remove() 4. 获取父元素:parent()
案例:原生的AJAX判断用户名是否存在
目标
需求
效果
服务器端
[ "Newboy", "Jack", "Rose", "Tom", "Lina" ]
客户端
步骤
a) 当 readyState 等于 4,并且服务器 status 响应码为 200 则表示响应成功
b) 通过 responseText 得到响应的字符串,服务器返回的是一个字符串数组。
c) 转成 JSON 数组,再与文本框中输出的值进行比较,如果存在就设置为 true,否则设置为 false。
d) 如果是 true,则表示用户存在,在后面的 span 显示”用户名已经存在”
e) 否则表示不存在,在后面的 span 中显示”恭喜你,可以注册”。代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户是否存在</title> </head> <body> 用户名:<input type="text" id="user"> <span id="info"></span> <script type="text/javascript"> /*用户注册时输入一个用户名,失去焦点以后,通过ajax后台判断用户名是否存在。 服务器先不访问数据库,直接判断用户名,如果用户名为newboy,则表示用户已经存在,否则用户名可以注册使用。 */ //用户名的改变事件 document.getElementById("user").onchange = function () { //创建XMLHttpRequest对象 let request = new XMLHttpRequest(); //打开服务器的连接,参数:GET或POST,服务器地址,true request.open("GET", "json/users.json", true); //发送请求给服务器 request.send(); //设置回调函数,准备状态发生改变时激活这个函数 request.onreadystatechange = function () { //准备状态等于4,服务器状态码等于200 if (request.readyState == 4 && request.status == 200) { //接收服务器返回的数据 let text = request.responseText; //字符串 //将字符串转成JSON let users = JSON.parse(text); //所有用户的数组 //得到用户在文本框中输入的数据 let user = document.getElementById("user").value; //设置标记 let exists = false; //遍历服务器返回的数组 for (let u of users) { if (u == user) { //当前元素等于输入的用户名 exists = true; //修改标记 break; } } //判断标记 if (exists) { //用户名已经存在 document.getElementById("info").innerText = "用户名已经存在"; } else { //不存在 document.getElementById("info").innerText = "恭喜,可以注册"; } } } } </script> </body> </html>
小结
案例:输入自动补全
需求
效果
服务器端代码
[ "张三", "李四", "王五", "赵六", "田七", "孙八", "张三丰", "张无忌", "李寻欢", "王维", "李白", "杜甫", "李贺", "李逵", "宋江", "王英", "鲁智深", "武松", "张薇", "刘小轩", "刘浩宇", "刘六" ]
流程分析
分析页面组成
步骤
拓展
代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>自动完成</title> <style type="text/css"> .content { width: 400px; margin: 30px auto; text-align: center; } input[type='text'] { box-sizing: border-box; width: 280px; height: 30px; font-size: 14px; border: 1px solid #38f; } input[type='button'] { width: 100px; height: 30px; background: #38f; border: 0; color: #fff; font-size: 15px; } #show { box-sizing: border-box; position: relative; left: 7px; font-size: 14px; width: 280px; border: 1px solid dodgerblue; text-align: left; border-top: 0; /*一开始是隐藏不可见*/ display: none; } #show div { padding: 4px; background-color: white; } #show div:hover { /*鼠标移上去背景变色*/ background-color: #3388ff; color: white; } </style> <script type="text/javascript" src="js/jquery-3.3.1.js"></script> </head> <body> <div class="content"> <img alt="传智播客" src="img/logo.png"><br/><br/> <input type="text" name="word" id="word"> <input type="button" value="搜索一下"> <div id="show"></div> </div> <script type="text/javascript"> /* alert(event.keyCode); //keyCode键盘码表,每个按键都会对应一个号码 */ //不能使用change事件,因为change要失去焦点才激活,只要松开任何一个键就激活 $("#word").keyup(function () { //判断文本框中是否有数据,如果不为空,才继续,去掉前后空格 let word = $("#word").val().trim(); if (word == "") { //如果文本框中没有内容,也要隐藏div $("#show").hide(); return; //不再继续 } //表示有数据的,开始访问服务器 $.get({ url: "json/search.json", //服务器的访问地址 success: function (users) { //返回服务器上所有的数据 //使用正则表达式,只保留指定字符串开头的用户名 let reg = new RegExp("^" + word); //创建一个数组,用来保存所有以word开头的用户 let arr = new Array(); //遍历整个数组 for (let user of users) { //判断每个字符串是否匹配正则表达式 if (reg.test(user)) { arr.push(user); //添加到数组中 } } //把arr数组显示在div中 //先判断数组中是否有元素,有元素才显示 if (arr.length > 0) { //拼接字符串 let html=""; for (let name of arr) { html+="<div>" + name + "</div>"; } //放在#show的div中 $("#show").html(html); //括号中是一个变量名html //显示div $("#show").show(); //如果点击每个小的div,就把div中文本赋值给文本框的value $("#show div").click(function () { //this相当于你点击的那个div $("#word").val($(this).text()); //隐藏大的div $("#show").slideUp("normal"); //加个动画 }); } else { //没有元素隐藏div $("#show").hide(); } } }); }); </script> </body> </html>
小结
案例:使用链接下载文件不足
目标
页面效果
下载页面
<!DOCTYPE html> <html> <head> <title>资源下载列表</title> <meta charset="utf-8"> </head> <body> <h2>文件下载页面列表</h2> <h3>超链接的下载</h3> <a href="download/file.txt">文本文件</a><br/> <a href="download/file.jpg">图片文件</a><br/> <a href="download/file.zip">压缩文件</a><br/> <hr/> <h3>手动编码的下载方式</h3> <!-- 注:down这里是下载的Servlet的访问地址 --> <a href="down?filename=file.txt">文本文件</a><br/> <a href="down?filename=file.jpg">图片文件</a><br/> <a href="down?filename=file.zip">压缩文件</a><br/> <a href="down?filename=美女.jpg">美女</a><br/> </body> </html>
小结:使用超链接下载的不足
案例:使用Servlet下载文件
目标
下载设置的响应头
设置响应头
参数说明
Content-Disposition:
attachment; filename=文件名Content-Disposition: 浏览器打开资源的方式
attachment: 表示以附件的方式下载,而不是打开
filename: 下载到浏览器端使用的文件名步骤
汉字乱码原理
下载的Servlet代码
package com.itheima.servlet; import org.apache.commons.io.IOUtils; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; 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.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; /** * 处理下载的Servlet * 在其实开发过程中,不建议在服务器上使用汉字 * 在Chrome和IE等浏览器中,文件名使用的URL编码 */ @WebServlet("/down") public class Demo5DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.得到下载的文件,filename与地址栏提交的名字相同 String filename = request.getParameter("filename"); //GET汉字没有乱码 System.out.println("下载的文件名是:" + filename); //必须设置响应头,考虑汉字的问题,对文件名使用URL编码 response.setHeader("content-disposition","attachment;filename=" + URLEncoder.encode(filename,"utf-8")); //1.得到上下文对象 ServletContext application = getServletContext(); //2.得到web目录下资源的输入流对象 InputStream inputStream = application.getResourceAsStream("/download/" + filename); //3.得到响应对象的字节输出流 OutputStream outputStream = response.getOutputStream(); //4.使用IOUtils复制流 IOUtils.copy(inputStream, outputStream); //5.关闭流 outputStream.close(); inputStream.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
小结
Content-disposition: attachment;filename=文件名
URLEncoder.encode("文件名","utf-8")
案例:得到用户上次访问的时间
目标
流程分析
代码
package com.itheima.servlet; import com.itheima.utils.CookieUtils; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; /** * 1. 如果用户是第一次访问,则输出:您好,您是第1次访问,欢迎您的加入!当前的时间是xxx * 2. 如果之前已经访问过,则从Cookie中得到上次访问的时间,显示:您好,欢迎您再次访问。 * 上次访问的时间是:xxxx,当前的时间是xxxxx。 * 3. 无论是否是第一次访问,都要把这次访问服务器的时间写到Cookie中 */ @WebServlet("/demo6") public class Demo6VisitedServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //0.创建现在的时间,不建议使用空格 String now = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date()); //1.获取浏览器端发送来的Cookie的值,假设这个键是visitedTime,使用工具类 String visitedTime = CookieUtils.getCookieValue(request, "visitedTime"); //2.判断是否为空,如果为空表示第1次访问 if (visitedTime == null) { out.print("<h1>您是第1次访问,现在的时间是:" + now + "</h1>"); } else { //不为空,表示从cookie中获取到指定的值,这就是上次访问的时间 out.print("<h1>欢迎您再次访问,上次访问的时间是:" + visitedTime + "</h1>"); out.print("<h2 style='color:green'>现在的时间是:" + now + "</h2>"); } //3.还要将现在的时间写回到浏览器,键与读取的要相同 Cookie cookie = new Cookie("visitedTime", now); //设置过期时间 cookie.setMaxAge(60 * 60 * 24 * 30); //保存1个月 //写到浏览器端 response.addCookie(cookie); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
小结
案例:利用cookie实现自动登录
案例part1:Cookie实现自动登录Servlet
目标
结构
分析
Servlet步骤
代码
package com.itheima.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; 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 doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1. 得到用户名和密码,判断是否正确 String username = request.getParameter("username"); String password = request.getParameter("password"); //2. 如果登录成功 if ("admin".equals(username) && "123".equals(password)) { //再判断是否勾选自动登录 String remember = request.getParameter("remember"); if (remember != null) { //不为空表示勾选了 //3. 把用户名和密码创建成Cookie Cookie cookieUsername = new Cookie("username", username); //4. 设置访问路径和过期的时间,发送给浏览器 cookieUsername.setPath(request.getContextPath() + "/login.html"); cookieUsername.setMaxAge(60 * 60 * 24 * 7); //保存1周 response.addCookie(cookieUsername); Cookie cookiePassword = new Cookie("password", password); //4. 设置访问路径和过期的时间,发送给浏览器 cookiePassword.setPath(request.getContextPath() + "/login.html"); cookiePassword.setMaxAge(60 * 60 * 24 * 7); //保存1周 response.addCookie(cookiePassword); } //表示登录成功,跳转到登录成功的页面 response.sendRedirect("success.html"); } else { response.sendRedirect("failure.html"); //登录失败 } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
案例part2:Cookie实现自动登录浏览器端
目标
JS代码步骤
代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>用户登录</title> <!--导入js文件--> <script src="js/commons.js"></script> </head> <body> <h2>用户登录</h2> <form action="login" method="post" id="loginForm"> <table> <tr> <td width="60">用户名</td> <td><input type="text" name="username" id="username"/></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password" id="password"/></td> </tr> <tr> <td>记住我</td> <!--没有value属性的前提下,点中它的值是on,如果没有勾上为null --> <td><input type="checkbox" name="remember"/></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="登录"/></td> </tr> </table> </form> </body> </html>
/** 页面加载完毕以后执行 */ window.onload = function () { //从cookie中得到用户名和密码 let username = getCookieValue("username"); let password = getCookieValue("password"); //如果字符串不为空,才将数据提交给服务器 if (username!="" && password!="") { //设置文本框的值 document.getElementById("username").value = username; document.getElementById("password").value = password; //提交表单 document.getElementById("loginForm").submit(); } } /** 通过键得到Cookie中的值 @param name表示要找的名字 */ function getCookieValue(name) { //可以得到当前路径下所有的cookie信息 let cookie = document.cookie; //username=admin; password=123 if (cookie!="") { //按分号进行拆分成数组,数组中有2个元素 let split = cookie.split("; "); for (let i = 0; i < split.length; i++) { //split[0] = "username=admin" split[1] = "password=123" let splitElement = split[i]; //每个元素 //再按等于号来拆分 let arr = splitElement.split("="); let key = arr[0]; //[0]号元素是username,[1]号元素admin let value = arr[1]; //如果name与key相等,就返回value if (key == name) { return value; } } } return ""; //没有找到 }
案例:商品购物车
目标
流程分析
步骤
添加到购物车的Servlet
查看购物车的Servlet
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>商品列表页面</title> <style> table { border-collapse: collapse; } td,th { text-align: center; padding: 3px; } </style> </head> <body> <table border="1" width="300"> <tr> <th>商品名称</th> <th>操作</th> </tr> <tr> <td>洗衣机</td> <td> <!--访问servlet中,add是servlet的访问地址--> <a href="add?name=洗衣机">添加到购物车</a> </td> </tr> <tr> <td>电视机</td> <td> <!--访问servlet中,add是servlet的访问地址--> <a href="add?name=电视机">添加到购物车</a> </td> </tr> <tr> <td>缝纫机</td> <td> <!--访问servlet中,add是servlet的访问地址--> <a href="add?name=缝纫机">添加到购物车</a> </td> </tr> <tr> <td>打火机</td> <td> <!--访问servlet中,add是servlet的访问地址--> <a href="add?name=打火机">添加到购物车</a> </td> </tr> </table> </body> </html>
package com.itheima.servlet; 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 javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; /** * 访问地址与html的链接地址相同 */ @WebServlet("/add") public class AddProductToServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获得会话对象 HttpSession session = request.getSession(); //2.从会话域中取出购物车对象(Map对象),购物车键是商品名,值是商品数量 HashMap<String, Integer> cart = (HashMap<String, Integer>) session.getAttribute("cart"); //3.判断购物车是否为空,如果为空创建一个购物车,表示第一次访问 if (cart == null) { cart = new HashMap<>(); } // 购物车对象是存在 //4.得到商品的名字 String name = request.getParameter("name"); //键:商品名 //5.如果商品不存在,向购物车中添加1件商品,如果存在,从购物车中取出商品的数量,加1再放进去 Integer num = cart.get(name); //值:数量 if (num == null) { //商品在购物车中不存在 cart.put(name, 1); //添加数量1到购物车中 } else { //商品在购物车中存在 cart.put(name, num + 1); //加1放进去 } //6. 更新会话域中购物车这个键 session.setAttribute("cart", cart); //7.输出操作结果和链接 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("添加1件" + name + "商品成功<hr/>"); out.print("<a href='productlist.html'>继续购物</a>"); out.print("<a href='cart'>查看购物车</a>"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
package com.itheima.servlet; 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 javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; /** * 显示购物车 * 与链接地址要相同 */ @WebServlet("/cart") public class CartServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //1.从会话中获取购物车 HttpSession session = request.getSession(); HashMap<String, Integer> cart = (HashMap<String, Integer>) session.getAttribute("cart"); //2.如果购物车为空输出空 if (cart == null) { out.print("购物车竟然是空的"); } //3.如果不为空,遍历Map集合输出购物车中每一项 else { out.print("<table border="1" width="300">"); out.print("<tr><th>商品名称</th><th>数量</th></tr>"); //每一行是一个tr,就是购物车中一项 cart.forEach((k,v) -> { out.print("<tr><td>"+ k +"</td><td>" +v + "</td></tr>"); }); out.print("</table>"); } out.print("<a href='productlist.html'>继续购物</a>"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
小结
方法
说明
Map<String,Integer> cart = new HashMap<>();
创建一个购物车,结构是Map结构
键是商品名,值商品数量
request.getSession()
获取会话对象,如果没有就是创建,如果有就获取
session.setAttribute()
向会话域中添加对象
案例:过滤全局汉字乱码
目标
分析
开发步骤
代码
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <form action="login" method="post"> 登录名:<input type="text" name="user"><br> <input type="submit" value="登录"> </form> </body> </html>
register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户注册</title> </head> <body> <h2>用户注册</h2> <form action="register" method="post"> 注册名:<input type="text" name="name"><br> <input type="submit" value="注册"> </form> </body> </html>
LoginServlet.java
package com.itheima.servlet; 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.io.PrintWriter; @WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取请求的数据 String username = request.getParameter("user"); //打印输出 out.print("登录成功:" + username); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
RegisterServlet.java
package com.itheima.servlet; 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.io.PrintWriter; @WebServlet("/register") public class RegisterServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //得到请求提交的数据 String name = request.getParameter("name"); out.print("注册成功:" + name); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
CharacterEncodingFilter.java
package com.itheima.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /* 过滤所有的资源 */ @WebFilter(filterName = "CharacterEncodingFilter", urlPatterns = "/*") public class CharacterEncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //0.将转成子接口才有这个方法 HttpServletRequest request = (HttpServletRequest) req; //1.判断是否是POST方法,注:这里是大写 if (request.getMethod().equals("POST")) { //2.如果是才进行编码 request.setCharacterEncoding("utf-8"); } //3.无论是否是POST方法都要放行 chain.doFilter(req, resp); } public void init(FilterConfig config) throws ServletException { } }
小结
案例:过滤敏感词汇
需求
案例效果
案例分析
分析
实现步骤
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>发贴</title> </head> <body> <form method="post" action="PostWordServlet"> 发贴:<input type="text" name="message"> <input type="submit" value="提交"> </form> </body> </html>
穷逼 笨蛋 白痴 王八 贱人 傻逼
package com.itheima.servlet; 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.io.PrintWriter; /** * 发贴显示的Servlet */ @WebServlet("/PostWordServlet") public class PostWordServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取到帖子的内容 String message = request.getParameter("message"); //显示在页面上 out.print("您的发贴内容如下:<hr/>" + message); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
package com.itheima.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.ArrayList; import java.util.List; /** * 只过滤发贴的Servlet */ @WebFilter(filterName = "IllegalWordFilter", urlPatterns = "/PostWordServlet") public class IllegalWordFilter implements Filter { //创建一个集合,保存所有的词汇 private List<String> illegalWords = new ArrayList<>(); //在初始化的方法中读取所有的词汇,这个方法只会执行1次 public void init(FilterConfig config) throws ServletException { //得到当前的类对象 -> 得到类加载器 -> 获取src目录下资源 InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("words.txt"); //将字节流使用utf-8转成字符流来使用,指定字符的编码 try(BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "utf-8"))) { String line = null; while((line = br.readLine())!=null) { //不为空就继续,每次读取一行 illegalWords.add(line); //将读取到的这一行添加到集合中 } } catch (IOException e) { e.printStackTrace(); } //在控制器上输出是否读取成功 System.out.println(illegalWords); } public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //设置汉字编码,不然会有乱码 req.setCharacterEncoding("utf-8"); //获取发贴的信息 String message = req.getParameter("message"); HttpServletResponse response = (HttpServletResponse) resp; //遍历所有词汇,发贴的内容中是否包含了这些词汇 for (String illegalWord : illegalWords) { //包含了这些词汇就拦截 if (message.contains(illegalWord)) { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("您的帖子中包含了非法的词汇,发贴失败"); return; //不再继续 } } //执行这句话才会放行 chain.doFilter(req, resp); } }
小结
案例:统计网站当前在线人数
执行效果
页面
服务器控制台信息
分析
步骤
代码
监听器
package com.itheima.listener; import javax.servlet.ServletContext; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * 统计会话的监听器 * 当前session会话被创建,当前在线用户+1,每当session会话被销毁,当前在线用户-1 * 人数最后是要放在上下文域中才能给所有的用户使用 * HttpSessionListener 接口用来监听会话的创建和销毁 */ @WebListener public class SessionCounterListener implements HttpSessionListener { //监听会话的创建 @Override public void sessionCreated(HttpSessionEvent event) { //获取当前会话对象 HttpSession session = event.getSession(); //在服务器上输出信息 System.out.println("创建会话:" + session.getId()); //得到上下文域,可以通过会话对象获取上下文对象 ServletContext application = session.getServletContext(); //从上下文对象中取number的值 Integer number = (Integer) application.getAttribute("number"); //因为第1个用户是没有值的 if (number == null) { //第1个用户向上下文域中添加1的值 application.setAttribute("number", 1); } else { //有值就加1,再放回去。这里要写成++number,不能写成number++ application.setAttribute("number", ++number); } } //监听会话的销毁 @Override public void sessionDestroyed(HttpSessionEvent event) { //向服务器输出信息 HttpSession session = event.getSession(); System.out.println("会话销毁:" + session.getId()); //得到上下文域 ServletContext application = session.getServletContext(); //得到number的值 Integer number = (Integer) application.getAttribute("number"); //减1再放进去,要先减 application.setAttribute("number", --number); } }
package com.itheima.listener; import javax.servlet.ServletContext; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import java.util.concurrent.atomic.AtomicInteger; /** * 统计会话的监听器 * 当前session会话被创建,当前在线用户+1,每当session会话被销毁,当前在线用户-1 * 人数最后是要放在上下文域中才能给所有的用户使用 * HttpSessionListener 接口用来监听会话的创建和销毁 * * 使用原子类,必须是同一个对象,无论是加或减都是操作同一个对象才正确 * 如果作用域中属性值是引用类型,我们直接修改引用类型的值,不需要重新更新作用域 */ @WebListener public class SessionCounterListener implements HttpSessionListener { private AtomicInteger number = null; //声明 //监听会话的创建 @Override public void sessionCreated(HttpSessionEvent event) { //获取当前会话对象 HttpSession session = event.getSession(); //在服务器上输出信息 System.out.println("创建会话:" + session.getId()); //得到上下文域,可以通过会话对象获取上下文对象 ServletContext application = session.getServletContext(); //从上下文对象中取number的值 number = (AtomicInteger) application.getAttribute("number"); //因为第1个用户是没有值的 if (number == null) { number = new AtomicInteger(1); //第1次赋值 //第1个用户向上下文域中添加1的值 application.setAttribute("number", number); } else { //把值取出来 number = (AtomicInteger) application.getAttribute("number"); //自己加1 number.incrementAndGet(); //更新这个值 //application.setAttribute("number",number); } } //监听会话的销毁 @Override public void sessionDestroyed(HttpSessionEvent event) { //向服务器输出信息 HttpSession session = event.getSession(); System.out.println("会话销毁:" + session.getId()); //得到上下文域 ServletContext application = session.getServletContext(); //得到number的值 number = (AtomicInteger) application.getAttribute("number"); //减1 number.decrementAndGet(); //减1再放进去,要先减 //application.setAttribute("number", number); } }
退出的Servlet
package com.itheima.servlet; 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.io.PrintWriter; /** * 退出 */ @WebServlet("/logout") public class LogoutServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("您已经安全退出"); //让会话过期 request.getSession().invalidate(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
显示人数的JSP
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>显示在线人数</title> </head> <body> <%--人数放在上下文域中,给所有的用户能访问--%> <h2>当前网站在线人数是:${applicationScope.number}</h2> <hr/> <a href="logout">安全退出</a> </body> </html>
案例:上传图片
目标
效果
流程
步骤
代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>文件上传</title> </head> <body> <h2>文件上传</h2> <%-- 文件上传表单的三要素: 1. 必须使用post方法(文件要在请求体中发送) 2. 必须指定属性:enctype="multipart/form-data",如果没有指定这个属性,默认是application/x-www-form-urlencoded application/x-www-form-urlencoded:表单中所有的参数是键=值的方式发送 multipart/form-data:将表单分成多个部分,每个部分使用一串数字进行分隔,不能通过servlet的getParameter()等方法去获取参数值 3. 要使用文件域 type="file",必须指定name属性 action是要提交的servlet地址 --%> <form enctype="multipart/form-data" action="upload" method="post"> 用户名: <input type="text" name="user"> <br/> 文件:<br/> <input type="file" name="file1"> <br/> <input type="file" name="file2"> <hr/> <input type="submit" value="上传文件"> </form> </body> </html>
package com.itheima.servlet; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.IOUtils; 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.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.List; @WebServlet("/upload") public class FileUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* 不能得到值 String user = request.getParameter("user"); System.out.println("用户名:" + user); */ response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //1.创建硬盘文件的工厂类 DiskFileItemFactory factory = new DiskFileItemFactory(); //2.创建一个文件上传的类,这是上传文件的核心类,需要上面的对象做为参数 ServletFileUpload fileUpload = new ServletFileUpload(factory); //3.通过上面这个类的方法解析请求的数据,生成一个List集合,集合中每个元素就是上传的一部分 try { List<FileItem> fileItems = fileUpload.parseRequest(request); //4. FileItem表示上传的每个部分 for (FileItem fileItem : fileItems) { //5. 判断是否是普通的文本值,是就返回true,不是表示这个是上传的文件 if (fileItem.isFormField()) { //普通文本框 //得到表单项的名字和值 String fieldName = fileItem.getFieldName(); String value = fileItem.getString("utf-8"); out.print("表单项名字:" + fieldName + ",表单项值:" + value + "<hr/>"); } else { //表示上传的文件 String name = fileItem.getName(); //得到文件名 InputStream inputStream = fileItem.getInputStream(); //得到文件输入流 //写到服务器上,得到文件的输出流,文件上传到out目录下/upload //获取upload真实地址,注:如果upload是一个空目录,idea不会在out目录下自动创建 String realPath = getServletContext().getRealPath("/upload"); //创建文件输出流: c:/xxx/upload/file1.txt FileOutputStream outputStream = new FileOutputStream(realPath + "/" + name); //使用工具类复制 IOUtils.copy(inputStream, outputStream); //关闭流 outputStream.close(); inputStream.close(); //打印上传成功 out.print("上传文件:" + name + "成功<hr/>"); } } } catch (FileUploadException e) { e.printStackTrace(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
public class FileUploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
不能得到值
String user = request.getParameter(“user”);
System.out.println(“用户名:” + user);
*/ response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //1.创建硬盘文件的工厂类 DiskFileItemFactory factory = new DiskFileItemFactory(); //2.创建一个文件上传的类,这是上传文件的核心类,需要上面的对象做为参数 ServletFileUpload fileUpload = new ServletFileUpload(factory); //3.通过上面这个类的方法解析请求的数据,生成一个List集合,集合中每个元素就是上传的一部分 try { List<FileItem> fileItems = fileUpload.parseRequest(request); //4. FileItem表示上传的每个部分 for (FileItem fileItem : fileItems) { //5. 判断是否是普通的文本值,是就返回true,不是表示这个是上传的文件 if (fileItem.isFormField()) { //普通文本框 //得到表单项的名字和值 String fieldName = fileItem.getFieldName(); String value = fileItem.getString("utf-8"); out.print("表单项名字:" + fieldName + ",表单项值:" + value + "<hr/>"); } else { //表示上传的文件 String name = fileItem.getName(); //得到文件名 InputStream inputStream = fileItem.getInputStream(); //得到文件输入流 //写到服务器上,得到文件的输出流,文件上传到out目录下/upload //获取upload真实地址,注:如果upload是一个空目录,idea不会在out目录下自动创建 String realPath = getServletContext().getRealPath("/upload"); //创建文件输出流: c:/xxx/upload/file1.txt FileOutputStream outputStream = new FileOutputStream(realPath + "/" + name); //使用工具类复制 IOUtils.copy(inputStream, outputStream); //关闭流 outputStream.close(); inputStream.close(); //打印上传成功 out.print("上传文件:" + name + "成功<hr/>"); } } } catch (FileUploadException e) { e.printStackTrace(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算