赞
踩
conf->logging.properties找到如下配置项:
java.util.logging.ConsoleHandler.encoding = UTF-8
将 UTF-8 修改为 GBK,修改后的效果为:
java.util.logging.ConsoleHandler.encoding = GBK
保存后,重启tomcat!
通过http://localhost:8080/访问服务器页面
访问页面时乱码:https://blog.csdn.net/weixin_39626745/article/details/110496357
bin->startup
点击启动窗口的×
部署项目的方式
直接将项目放到webapps下即可
重新启动Tomcat服务器
分别为端口号->目录->网页名
简化部署:
war包方式
配置conf/server.xml文件
在conf\Catalina\localhost创建任意名称的xml文件
静态项目和动态项目
将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目
IDEA会为一个tomcat部署的项目单独建立一份配置文件
tomcat部署的web项目
,它对应着工作空间项目
的web目录下的所有资源WEB-INF
目录下的资源不能被浏览器直接访问概念:运行在服务器端的小程序
实现Servlet接口,创建类
package com.example.javaWeb_Servlet; import javax.servlet.*; import java.io.IOException; /** * @author 玫瑰到了花期 * @data 2022/3/21 14:19 * @love 又偷偷看你了 * @V: CBWR-K */ public class Servlet01 implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
编写web.xml配置文件
<!--配置Servlet-->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>com.example.javaWeb.ServletDemo01</servlet-class>
</servlet>>
<!--映射Servlet-->
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
通过url-pattern映射的路径来访问
/**
* 初始化方法
* 在Servlet被创建时执行,只会执行一次
* 执行在控制台
* */
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init....");
}
/**
* 获取ServletConfig对象
* ServletConfig:Servlet的配置对象
* */
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 提供服务方法
* 每一次Servlet被访问时,执行,执行多次
* 执行在控制台
* */
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet....");
}
/**
* 获取Servlet的一些信息,版本,作者等等。
* */
@Override
public String getServletInfo() {
return null;
}
/**
* 销毁方法
* 在服务器正常关闭,执行,执行一次
* */
@Override
public void destroy() {
System.out.println("destroy....");
}
<load-on-startup>-5</load-on-startup>
<!--指定Servlet的创建时机
1.第一次被访问时,创建
<load-on-startup>的值为负数
2.在服务器启动时,创建
<load-on-startup>的值为0或正整数
-->
//uelpatterns="访问路径" -- 注解写在类前
@WebServlet(urlPatterns = "/demo")
//写法2
@WebServlet("/demo2")
//写法3,多条访问路径
@WebServlet({"/demo3","/demo4"})
Servlet – 接口
|
GenericServlet – 抽象类
|
HttpServlet – 抽象类
定义类继承HttpServlet
复写doGet/doPost方法
doGet->
doPost->
/xxx
资源目录,访问此路径
/xxx/xxx
多层路径,目录结构,需要输全路径才能访问
*.do
==万能路径,表示==后面的路径可以随意输入
.do表示必须以do结尾
请求方式 | 请求url | 请求协议 | 版本 |
---|---|---|---|
GET | /login.html | HTTP | 1.1 |
请求头名称:请求头值
客户端浏览器告诉服务器一些信息
请求头名称 | 使用 |
---|---|
Host:localhost | 端口 |
User-Agent: | 浏览器告诉服务器,访问你使用的浏览器版本信息 |
可以在服务端获取该头的信息,解决浏览器兼容问题 | |
Referer: | 告诉服务器,我(当前请求)从哪里来 |
作用: | 防盗链 |
统计 | |
Connection: | keep-alive 可以被复用 |
空行,就是用于分割POST请求的请求头和请求体的
空行 |
---|
获取请求消息数据
Get /day1/demo1?name=傻逼胡子洋 HTTP/1.1
方法:
功能 | 方法 |
---|---|
获取请求方式:GET | String getMethod() |
==*==获取虚拟目录:/day1 | String getContextPath() |
获取Servlet路径:/demo1 | String getServletPath() |
获取get方式请求参数:name=… | String getQueryString() |
==*==获取请求的url:/day1/demo1 | String getRetURL():/day1/demo1 |
StringBuffer getRequestURL():http://localhost/day1/demo1 | |
获取协议及版本:HTTP1.1 | String getProtocol() |
获取客户机的IP地址 | String getRemoteAddr() |
URL: | 统一资源定位符 – 中华人民共和国 |
URI: | 统一资源标识符 – 共和国 |
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1、获取请求方式 String method = request.getMethod(); System.out.println("请求方式为:"+method); //2、获取虚拟目录 String contextPath = request.getContextPath(); System.out.println("虚拟目录为:"+contextPath); //3、获取Servlet路径 String servletPath = request.getServletPath(); System.out.println("Servlet路径为:"+servletPath); //4、获取get方式请求参数 String queryString = request.getQueryString(); System.out.println("get方式请求参数为:"+queryString); //5、获取请求的url StringBuffer requestURL = request.getRequestURL(); System.out.println("URL为:"+requestURL); //6、获取协议及版本 String protocol = request.getProtocol(); System.out.println("协议版本为:"+protocol); //7、获取客户机的IP地址 String remoteAddr = request.getRemoteAddr(); System.out.println("客户机的IP地址为"+remoteAddr); }
功能 | 方法 |
---|---|
String contains(“”) | request对象判断字符串 |
String getHeader(String name) | ==*==通过请求头的名称获取请求头的值 |
Enumeration getHeaderNames() | 获取所有请求头的值 |
hasMoreElements() | 测试此枚举是否包含更多的元素(迭代器) |
nextElement() | 如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素 |
获取所有请求头以及值
获取指定请求头的值
请求体
步骤
获取流对象
从流对象中拿数据
方法 | 说明 |
---|---|
BufferedReader getReader() | 获取字符输入流,只能操作字符数据 |
ServletInputStream getInputStream() | 获取字节输入流,可以操作所有类型数据 |
在文件上传后讲解 | |
.readLine() | 读取数据 以字符串形式返回这一行的数据 |
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体 -- 请求参数
//1.获取字符流
BufferedReader br = request.getReader();
//2.读取数据
String line = null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
}
}
方法 | 说明 |
---|---|
String getParameter(String name) | 根据参数名称获取参数值 |
password=123456 | 参数传递"password"返回123456 |
String[] getParameterValues(String name) | 根据参数名称获取参数值的数组(多个数值) |
name=“1”&name=“2” | 参数传递"name"返回所有name值 |
getParameterNames() | 获取所有请求的参数名称 |
Map<String,String[]> getParameterMap() | 获取所有参数的map集合 |
.keySet() | 输出键集合 |
//post 获取请求参数
//根据参数名称获取参数值
String user = request.getParameter("User");
String password = request.getParameter("password");
System.out.println(user+password);
//post 获取请求参数
//根据参数名称获取参数数组
String[] names = request.getParameterValues("hobby");
for (String name:names) {
System.out.println(name);
}
//post 获取请求参数
//获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for (String name : keySet) {
//获取键获取值
String[] values = parameterMap.get(name);
System.out.println(name);
for(String value : values){
System.out.println(value);
}
System.out.println("-------------");
}
get方式:tomcat 8 已经将get方式乱码问题解决了
post方式:会乱码
解决:在获取参数前,设置request的编码
request.setCharacterEncoding("utf-8");
一种在服务器内部的资源跳转方式
方法 request | 说明 |
---|---|
getRequestDispatcher(String path) | 通过request对象获取请求转发器对象 |
forward(ServletRequest request,ServletResponse response) | 使用request对象进行转发 |
/*Demo6*/
System.out.println("Demo6666被访问了");
//转发到Demo7资源
RequestDispatcher requestDemo7 = request.getRequestDispatcher("requestDemo7");
requestDemo7.forward(request,response);
/*Demo7*/
System.out.println("Demo7777被访问了");
/*写法2*/ request.getRequestDispatcher("requestDemo7").forward(request,response);
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
方法 | 说明 |
---|---|
void setAttribute(String name,Object obj) | 存储数据 |
Object getAttitude(String name) | 通过键获取值 |
void removeAttribute(String name) | 通过键移除键值对 |
/*Demo6*/
System.out.println("Demo6666被访问了");
//存储数据到request域中
request.setAttribute("msg","hello");
//转发到Demo7资源
request.getRequestDispatcher("requestDemo7").forward(request,response);
/*Demo7*/
//获取request域的值
Object msg = request.getAttribute("msg");
System.out.println(msg);
System.out.println("Demo7777被访问了");
方法 | 说明 |
---|---|
ServletContext getServletContext() | 获取ServletContext对象 |
//获取servletContext对象
ServletContext servletContext = request.getServletContext();
System.out.println(servletContext);
用户登录案例:
链接:https://pan.baidu.com/s/1ApJyMdsI8sqJU6bQRXAeJw
提取码:1011
响应消息:服务器端发送给客户端的数据
组成
协议/版本 响应状态码 状态码描述
响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
状态码都是3位数字
分类:
状态码(百) | 说明 |
---|---|
1xx | 服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx多的状态码。 |
2xx | 成功。代表:200 |
3xx | 重定向。代表:302(重定向),304(访问缓存) |
4xx | 客户端错误。代表: |
404(请求路径没有对应的资源) | |
405:请求方式没有对应的doxxx方法 | |
5xx | 服务器端错误。代表:500(服务器内部出现异常) |
格式:头名称:值
常见的响应头
响应头 | 说明 |
---|---|
Content - Type: | 服务器告诉客户端本次响应体数据格式以及编码格式 |
text/html;charset=UTF-8 | |
Content - disposition: | 服务器告诉客户端以什么格式打开响应体数据 |
in - line:默认值,在当前页面内打开 | |
attachment;filename=xxx:以附件形式打开响应体。文件下载 | |
格式:HTTP/1.1 200 OK
方法 | 说明 |
---|---|
setStatus(int sc) | 设置状态码 |
方法 | 说明 |
---|---|
setHeader(String name,String value) | 设置响应头 |
使用步骤:
获取输出流
方法 | 说明 |
---|---|
PrintWriter getWriter() | 字符输出流 |
ServletOutputStream getOutputSteam() | 字节输出流 |
使用输出流,将数据输出到浏览器
方法 | 说明 |
---|---|
sendRedirect(String value) | 简单的重定向方法 |
//index
System.out.println("index");
//访问/ResponseIndex的时候自动跳转到/ResponseIndex2资源
//1.设置状态码为302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","ResponseIndex2");
//index2
System.out.println("index2");
//简单的重定向方法
response.sendRedirect("ResponseIndex2");
//可访问其他站点
response.sendRedirect("http://www.itcast.cn");
转发地址栏路径不变
转发只能访问当前服务器下的资源
转发是一次请求,可以使用request对象来共享数据
forward 和 redirct 区别
如:./index.html
不以 / 开头,以 . 开头的路径称之为相对路径
规则:找到访问当前资源和目标资源之间的相对位置关系
方法 | 说明 |
---|---|
/ | 根目录 |
./ | 当前目录 |
…/ | 上一级目录 |
方法 | 说明 |
---|---|
String n = request.getContextPath() | 动态获取虚拟目录 |
response.sendRedirect(n+“ResponseIndex2”) | 重定向方法 |
中文乱码问题解决
//获取流对象之前,设置流的默认编码:IOS-8859-1 设置为:GBK
response.setCharacterEncoding("GBK");
//告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码
response.setHeader("content-type","text/html;charset=utf-8");
//简单的形式,设置编码
response.setContentType("text/html;charset=utf-8");
方法 | 说明 |
---|---|
sos = response.getOutputStream() | 获取字节输出流 |
sos.write(“htllo”.getBytes(“utf-8”)) | 输出数据 |
获取字节对象之前,设置字节的默认编码:IOS-8859-1 设置为:GBK
response.setContentType("text/html;charset=utf-8");
//获取字节输出流
ServletOutputStream sos = response.getOutputStream();
//输出
sos.write("<h1>你好,baga</h1>".getBytes("utf-8"));
本质:图片
目的:防止恶意表单注册
方法 | 说明 |
---|---|
width=100 | 验证码画布的宽 |
height=50 | 验证码画布的高 |
bImg = BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); | 创建验证码图片对象 |
g = bImg.getGraphics() | 画笔对象 |
颜色获取 | |
g.setColor(Color.pink) | 设置画笔颜色 |
填充背景色 | |
g.fillRect(0,0,width,height) | 填充画布颜色 |
画边框 | |
g.drawRect(0,0,width-1,height-1) | 设置边框颜色 |
验证码 | |
g.drawString(字符,x坐标,y坐标) | 写入验证码 |
干扰线 | |
g.drawLine(x1,x2,x3,x4) | 设置干扰线 |
输出 | |
ImageIO.write(bImg,“jpg”,response.getOutputStream()) | 将图片输出到页面展示 |
int width = 100; int height = 50; //1.创建一对象,在内存中图片(验证码图片对象) BufferedImage bImg = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); //2.美化图片 //2.1、填充背景色 Graphics g = bImg.getGraphics();//画笔对象 g.setColor(Color.pink); //设置画笔颜色 g.fillRect(0,0,width,height); //2.2、画边框 g.setColor(Color.BLUE); g.drawRect(0,0,width-1,height-1); Random ram = new Random(); //随机验证码 for (int i = 1; i <= 4; i++) { String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; //生成随机角标 int index = ram.nextInt(str.length()); //获取字符 char ch = str.charAt(index);//随机字符 //2.3、写入验证码 g.drawString(ch+"",width/5*i,25); } //2.4、画干扰线 g.setColor(Color.GREEN); //随机生成坐标点 for (int i = 0; i < 4; i++) { int x1 = ram.nextInt(width); int x2 = ram.nextInt(width); int y1 = ram.nextInt(height); int y2 = ram.nextInt(height); g.drawLine(x1,x2,y1,y2); } //3.将图片输出到页面展示 ImageIO.write(bImg,"jpg",response.getOutputStream());
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <img src="CheckCodeServlet" alt=""> <a href="">看不清换一张</a> </body> <script> /* * 分析: * 点击链接或者图片,需要换一张 * 1.给图片和链接绑定单击事件 * 2.重新设置图片的src属性值 * */ window.onload = function () { let img = document.getElementsByTagName("img")[0]; img.onclick = function () { let date = new Date().getTime(); //加时间戳 img.src = "CheckCodeServlet?" + date } let a = document.getElementsByTagName("a")[0]; a.onclick = function () { let date = new Date().getTime(); img.src = "CheckCodeServlet?" + date } } </script> </html>
概念:代表整个web应用,可以和程序的容器(服务器)来通信
方法 | 说明 |
---|---|
request.getServletContext() | 通过request对象获取 |
this.getServletContext() | 通过HttpServlet获取 |
//ServletContext对象获取
//1.通过request对象获取
ServletContext servletContext = request.getServletContext();
//2.通过HttpServlet获取
ServletContext servletContext1 = this.getServletContext();
System.out.println(servletContext);
System.out.println(servletContext1);
System.out.println(servletContext==servletContext1);
方法 | 说明 |
---|---|
String getMimeType(String file) | 获取 |
//ServletContext功能
//MIME类型:在互联网通信过程中定义的一种文件数据类型
//2.通过HttpServlet获取
ServletContext servletContext = this.getServletContext();
//3.定义文件名
String fileName = "a.jpg";
//4.获取MIME类型
String mimeType = servletContext.getMimeType(fileName);
System.out.println(mimeType);
方法 | 说明 |
---|---|
setAttribute(String name,Object value) | 设置共享数据 |
getAttribute(String name) | 获取共享数据 |
removeAttribute(String name) | 删除共享数据 |
demo3
//2.通过HttpServlet获取
ServletContext servletContext = this.getServletContext();
//设置数据
servletContext.setAttribute("msg","hello");
demo4
//2.通过HttpServlet获取
ServletContext servletContext = this.getServletContext();
//获取数据
Object msg = servletContext.getAttribute("msg");
System.out.println(msg);
分别访问后:
方法 | 说明 |
---|---|
String getRealpath(String path) | 获取文件路径 |
//通过HttpServlet获取
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/b.txt");//web目录下资源访问
System.out.println(realPath);
//File file = new File(realPath);
String c = servletContext.getRealPath("/WEB-INF/c.txt");//web-inf目录下的资源访问
System.out.println(c);
String a = servletContext.getRealPath("/WEB-INF/classes/a.txt");//src路径下的资源访问
System.out.println(a);
//1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件进内存 //2.1、找到文件服务器路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/"+filename); //2.3、用字节流关联 FileInputStream file = new FileInputStream(realPath); //3.设置response响应头 //3.1设置response响应头类型:content-type //获取文件的MIME类型 String mimeType = servletContext.getMimeType(filename); response.setHeader("content-type",mimeType); //3.2设置响应头打开方式:content-disposition response.setHeader("content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到输出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; while ((file.read(buff)!=-1)){ outputStream.write(buff,0,len); } file.close();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/javaWeb_Response_Test_war_exploded/img/1.jpeg">图片1</a>
<a href="/javaWeb_Response_Test_war_exploded/video/1.mp4">视频1</a>
<hr>
<a href="/javaWeb_Response_Test_war_exploded/downLoadServlet?filename=1.jpeg">图片1</a>
<a href="/javaWeb_Response_Test_war_exploded/downLoadServlet?filename=2.webp">图片2</a>
<a href="/javaWeb_Response_Test_war_exploded/downLoadServlet?filename=1.mp4">视频</a>
</body>
</html>
解决思路:
//解决中文文件乱码问题
//1.获取User-agent请求头
String agent = request.getHeader("user-agent");
//2.工具类方法编码文件名即可
filename= DownLoadUtils.getFileName(agent, filename);
//1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件进内存 //2.1、找到文件服务器路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/"+filename); System.out.println("===>>"+realPath); //2.3、用字节流关联 FileInputStream file = new FileInputStream(realPath); //3.设置response响应头 //3.1设置response响应头类型:content-type //获取文件的MIME类型 String mimeType = servletContext.getMimeType(filename); response.setHeader("content-type",mimeType); //3.2设置响应头打开方式:content-disposition //解决中文文件乱码问题 //1.获取User-agent请求头 String agent = request.getHeader("user-agent"); //2.工具类方法编码文件名即可 filename= DownLoadUtils.getFileName(agent, filename); response.setHeader("content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到输出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; while (((len = file.read(buff))!=-1)){ outputStream.write(buff,0,len); outputStream.flush(); } outputStream.close(); file.close();
package utils; import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { if (agent.contains("MSIE")) { // IE浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filename = URLEncoder.encode(filename, "utf-8"); } return filename; } }
一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开位置
在一次会话的范围内的多次请求间,共享数据
概念:客户端会话技术,将数据保存到客户端
方法 | 说明 |
---|---|
new Cookie(String name,String value) | 创建Cookie对象,绑定数据 |
response.addCookie(Cookie cookie) | 发送Cookie对象 |
Cookie[] request.getCookies() | 获取Cookie,拿到数据 |
/*demo1*/
//1.创建Cookie对象
Cookie cookie = new Cookie("msg","hello");
//2.发送Cookie
response.addCookie(cookie);
/*demo2*/
//3.获取Cookie
Cookie[] cookies = request.getCookies();
//获取数据,遍历cookies
if (cookies!=null){
for (Cookie c : cookies){
String name = c.getName();
String value = c.getValue();
System.out.println(name+": "+value);
}
}
实现原理
//1.创建Cookie对象
Cookie c1 = new Cookie("msg","hello");
Cookie c2 = new Cookie("name","word");
Cookie c3 = new Cookie("live","你听得到");
//2.发送Cookie
response.addCookie(c1);
response.addCookie(c2);
response.addCookie(c3);
默认情况下,当浏览器关闭后,Cookie数据被销毁
以此可知,Cookie存在浏览器内存里面
方法 | 说明 |
---|---|
setMaxAge(int seconds) | 持久化存储 |
参数 单位/s: | |
正数 | 将Cookie数据写到硬盘的文件中。持久化储存。Cookie存活时间 |
负数 | 默认值 |
零 | 删除cookie信息 |
//1.创建Cookie对象
Cookie c = new Cookie("live","setMaxAge");
//2.设置cookie的存活时间
c.setMaxAge(30);//将cookie持久化到硬盘,30秒后自动删除cookie文件
c.setMaxAge(-1);
c.setMaxAge(0);
//3.发送Cookie
response.addCookie(c);
tomcat8之后,cookie支持中文数据
tomcat8之前,cookie不支持中文数据,需要将中文数据转码:
一般采用URL编码(%E3)
//URL编码
date = URLEncoder.encode(date,"utf-8");
//URL解码
value = URLEncoder.encode(value,"utf-8");
默认情况下cookie不能共享
方法 | 说明 |
---|---|
setPath(String path) | 设置cookie的获取范围。默认情况下设置当前的虚拟目录 |
如果要共享,要将path值设置为 “/” | |
//1.创建Cookie对象
Cookie c = new Cookie("live","你听得到");
//设置path,让当前服务器下部署的所有项目共享cookie信息
c.setPath("/");
//3.发送Cookie
response.addCookie(c);
不同的tomcat服务器间cookie共享问题
方法 | 说明 |
---|---|
setDomain(String path) | 如果设置一级域名相同,那么多个服务器之间cookie可以共享 |
举例 | |
setDomain(“.baidu.com”) | 那么tieba.baidu.com和news.baidu.com中cookie可以共享 |
作用:
记住上一次访问时间
package com.example.javaWeb_CookieServlet; /** * @author 玫瑰到了花期 * @data 2022/3/29 17:57 * @love 又偷偷看你了 * @V: CBWR-K */ import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @WebServlet("/ServletCookieIndex") public class ServletCookieIndex extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean isNaN = true; //设置中文乱码问题 response.setContentType("text/html;charset=utf-8"); //获取所有的cookie Cookie[] cookies = request.getCookies(); if (cookies!=null){ for (Cookie c : cookies){ String name = c.getName(); if ("listTime".equals(name)){ //有该cookie isNaN = false; //设置cookie的value //获取当前时间,重新定义cookie的值,重新发送cookie Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); String str_date = sdf.format(date); c.setValue(str_date); //设置cookie一个月的存活时间 c.setMaxAge(60*60*24*30); response.addCookie(c); //响应数据 String value = c.getValue(); response.getWriter().write("欢迎回来,上次访问时间:"+value); break; } } } if (cookies!=null|| isNaN == true){ //没有,第一次访问 //获取时间 Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); String str_date = sdf.format(date); //创建cookie,存储数据 Cookie cookie = new Cookie("listTime",str_date); //设置cookie的存活时间 cookie.setMaxAge(60*60*24*30); response.addCookie(cookie); //响应数据 response.getWriter().write("你好,欢迎首次访问"); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
Java Server Pages : java服务器端页面
可以理解为一个特殊的页面
其中既可以直接定义html标签
还可以定义java代码
用于简化书写
JSP定义JAVA代码的方式
方法 | 说明 |
---|---|
<% java代码 %> | 在%内写入java代码,也称之为jsp的脚本定义的java代码,在service方法中。 |
service方法中可以定义什么,该脚本就可以定义什么 | |
<%! java代码 %> | 第二种脚本,定义的java代码,在jsp转换后的java类的成员位置 |
<%= java代码 %> | 第三种脚本,定义的java代码,会输出到页面上 |
输出语句中可以定义什么,该脚本就可以定义什么 |
对象 | 说明 |
---|---|
request | 请求 |
response | 响应 |
out | 字符输出流对象,可以将数据输出到页面上。 |
和response.getWriter()类似 |
<%@ page import="java.util.Date" %> <%@ page import="java.text.SimpleDateFormat" %><%-- Created by IntelliJ IDEA. User: Administrator Date: 2022/3/31 Time: 8:47 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% boolean isNaN = true; //设置中文乱码问题 response.setContentType("text/html;charset=utf-8"); //获取所有的cookie Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie c : cookies) { String name = c.getName(); if ("listTime".equals(name)) { //有该cookie isNaN = false; //设置cookie的value //获取当前时间,重新定义cookie的值,重新发送cookie Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); String str_date = sdf.format(date); c.setValue(str_date); //设置cookie一个月的存活时间 c.setMaxAge(60 * 60 * 24 * 30); response.addCookie(c); //响应数据 String value = c.getValue(); %> <h1>"欢迎回来,上次访问时间:"<%=value%> </h1> <% break; } } } if (cookies != null && isNaN) { //没有,第一次访问 //获取时间 Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); String str_date = sdf.format(date); //创建cookie,存储数据 Cookie cookie = new Cookie("listTime", str_date); //设置cookie的存活时间 cookie.setMaxAge(60 * 60 * 24 * 30); response.addCookie(cookie); //响应数据 %> <h1>"你好,欢迎首次访问"</h1> <% } %> </body> </html>
方法 | 说明 |
---|---|
request.getSession() | 获取HttpSession对象 |
使用 | |
void setAttribute(String name,Object value) | 存储数据 |
Object getAttribute(String name) | 获取session |
void removeAttribute(String name) | 删除数据 |
默认情况下,不是
客户端关闭后,session也能相同
如果需要相同,可以创建Cookie,键位JSESSIONID,设置最大存活时间,让cookie持久化存储
//1.获取session
HttpSession session = request.getSession();
System.out.println(session);
//期望客户端关闭后,session也能相同
Cookie c = new Cookie("JSESSIONID",session.getId());
//持久化储存
c.setMaxAge(60*60);
//发送cookie
response.addCookie(c);
不是同一个
session地址不一样,但要确保数据不丢失
session的钝化系列化
session的活化反序列化
找到本项目的out包下的文件
解压并修改后缀名为.war
将war包复制到tomcat下的webapps下
关闭之前的服务器
手动开启tomcat下的启动服务器文件
打开浏览器,访问session文件
服务器关闭
session对象调用
方法 | 说明 |
---|---|
invalidate() | 自销毁 |
session默认失效时间
package sessionServlet.Servlet; /** * @author 玫瑰到了花期 * @data 2022/4/1 16:17 * @love 又偷偷看你了 * @V: CBWR-K */ import sessionServlet.UserDao.Dao.UserDao; import sessionServlet.UserDao.Dao.UserDaoImpl; import sessionServlet.UserDao.User; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); UserDao userDao = new UserDaoImpl(); boolean isCo = false; //从浏览器获取参数 String userName = request.getParameter("userName"); String password = request.getParameter("password"); String verification = request.getParameter("verification"); //获取验证码 HttpSession session = request.getSession(); String yzm = (String) session.getAttribute("yzm"); //删除验证码,防止后退后验证码被复用 session.removeAttribute("yzm"); System.out.println(yzm); System.out.println(verification); //判断验证码是否正确 User login = userDao.login(new User(userName, password)); if (yzm!=null&&yzm.equalsIgnoreCase(verification)){ if (login!=null){ //登陆成功 //储存信息,用户信息 session.setAttribute("userName",userName); //重定向到success.jsp response.sendRedirect(request.getContextPath()+"success.jsp"); }else { //登陆失败 //储存信息到request request.setAttribute("login_error","用户名或密码错误"); //转发到登陆页面 request.getRequestDispatcher("index.jsp").forward(request,response); } }else { //验证码不一致 //储存信息到request request.setAttribute("cc_error","验证码错误"); //转发到登陆页面 request.getRequestDispatcher("index.jsp").forward(request,response); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
package sessionServlet.Servlet; /** * @author 玫瑰到了花期 * @data 2022/4/1 14:22 * @love 又偷偷看你了 * @V: CBWR-K */ import javax.imageio.ImageIO; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; @WebServlet("/verifyServlet") public class verifyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //验证码制作 int width = 100; int height=50; BufferedImage bImg = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); Graphics g = bImg.getGraphics(); Graphics g1 = bImg.getGraphics(); g.setColor(Color.pink); //设置背景颜色 g.fillRect(0,0,width,height); g.setColor(Color.black); //设置边框线 g.drawRect(0,0,width-1,height-1); //生成验证码 String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; String str_verification = ""; for (int i = 0; i < 4; i++) { Random r = new Random(); int index = r.nextInt(str.length()); char c = str.charAt(index); //储存验证码 str_verification += c; //写入验证码 g.drawString(String.valueOf(c),width/4*i,25); //干扰线 g1.setColor(Color.GREEN); int x1 = r.nextInt(width); int x2 = r.nextInt(width); int y1 = r.nextInt(height); int y2 = r.nextInt(height); g1.drawLine(x1,x2,y1,y2); } //验证码图片输出至浏览器 ImageIO.write(bImg,"jpg",response.getOutputStream()); System.out.println("验证码:"+str_verification); HttpSession session = request.getSession(); session.setAttribute("yzm",str_verification); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
<%@ page import="java.awt.*" %> <%@ page import="java.util.Random" %> <%@ page import="javax.imageio.ImageIO" %> <%@ page import="java.awt.image.BufferedImage" %><%-- Created by IntelliJ IDEA. User: Administrator Date: 2022/4/1 Time: 14:21 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> span { color: red; } </style> </head> <body> <script type="text/javascript"> window.onload = function () { document.getElementById("img").src = "/verifyServlet"; document.getElementById("img").onclick = function () { this.src = "/verifyServlet?time=" + new Date().getTime(); document.getElementsByName("verification")[0].value = ""; } } </script> <form action="/LoginServlet" method="post"> 用户名:<input type="text" placeholder="输入用户名" name="userName"><span><%=request.getAttribute("login_error")==null? "":request.getAttribute("login_error")%></span><br> 密码:<input type="password" placeholder="输入密码" name="password"><span><%=request.getAttribute("login_error")==null? "":request.getAttribute("login_error")%></span><br> 验证码:<input type="text" placeholder="输入验证码" name="verification"><span><%=request.getAttribute("cc_error")==null? "":request.getAttribute("cc_error")%></span><br> <img src="" alt="" id="img" οnclick=""> <input type="submit" value="登陆"> </form> </body> </html>
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2022/4/1 Time: 17:52 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1><%=request.getSession().getAttribute("userName")%>,登陆成功</h1> </body> </html>
作用:用于配置JSP页面,导入资源文件
方法 | 说明 |
---|---|
<%@指令名称 属性名1=属性值1 …%> | 指令基本定义格式 |
方法 | 说明 |
---|---|
contentType | 等同于response.setContentType() |
1 | 设置响应体的mime类型以及字符集 |
2 | 设置当前jsp页面的编码(高级IDE才能生效如果使用低级工具需要设置pageEncoding属性设置当前页面的字符集编码) |
import | 导包 |
errorPage | 当前页面发生异常后,会自动跳转到指定的错误页面 |
isErrorPage | 标识当前页面是否是错误页面 |
true:是,可以使用内置对象exception | |
false:否,默认值,不可以使用内置对象exception |
<%@ page contentType="text/html;charset=UTF-8" errorPage="500.jsp" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <% int i = 3/0; %> </body> </html> |||||||||||||||||||||||||||||||||||||||||| <%@ page contentType="text/html;charset=UTF-8" isErrorPage="true" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>服务器正忙....</h1> <% System.out.println(exception.getMessage()); %> </body> </html>
方法 | 说明 |
---|---|
file | 导入页面 |
<!--jstl依赖--> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/taglibs/standard --> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency>
方法 | 说明 |
---|---|
prefix | 前缀:自定义的 |
uri | 对应标签名,资源路径 |
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- -->:只能注释html代码片段
<%-- --%>:可以注释所有
在jsp页面中不需要创建,直接使用的对象
一共有9个‘
变量名 | 真实类型 | 作用 |
---|---|---|
域对象 | ||
pageContext | PageContext | 当前页面共享数据,还可以获取其他八个内置对象 |
request | HttpServletRequest | 一次请求访问的多个资源(转发) |
session | HttpSession | 一次会话的多个请求间 |
application | ServletContext | 所有用户间共享数据 |
响应对象 | ||
response | HttpServletResponse | 响应对象 |
page | Object | 当前页面(Servlet)的对象 this |
out | JspWriter | 输出对象,数据输出到页面上 |
配置对象 | ||
config | ServletConfig | Servlet的配置对象 |
exception | Throwable | 异常对象 |
M:Mdel,模型 – javaBean
V:View,视图 – JSP
C:Controller:控制器 – Servlet
jsp中是默认支持el表达式的
语法 | |
---|---|
${表达式} | |
防止jsp默认解析el表达式 | |
配置jsp中page指令:isELIgnored=“true” | 忽略所有的el表达式 |
${表达式} | 忽略单个el表达式 |
替换和简化jsp页面中Java代码的编写 |
运算符 | |
---|---|
+ - * /(div) %(mod) | 算术运算符 |
> < >= <= == != | 比较运算符 |
&&(and) ||(or) !(not) | 逻辑运算符 |
empty | 空运算符 |
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> ${1>3} \${1>3} <hr> <h3>算术运算符</h3> ${3+4}<br> ${3/4}<br> ${3 div 4}<br> ${3%4}<br> ${3 mod 4}<br> <hr> <h3>比较运算符</h3> ${1==1} ${1==2} <hr> <h3>逻辑运算符</h3> ${1>2 && 1<2} ${1>2 and 1<2} ${1>2 || 1<2} ${1>2 or 1<2} ${!(1>2 and 1<2)} ${not(1>2 and 1<2)} <h3>空运算符</h3> <p>判断字符串、集合、对象、数组是否为Null并且长度为0</p> ${empty list} </body> </html>
语法 | |
---|---|
方式一: | |
${域名城.键名} | 从指定域中获取指定键的值 |
域名城 | pageScope – > pageContext |
requestScope --> request | |
sessionScope --> session | |
applicationScope --> application(ServletContext) | |
方式二: | |
${键名} | 表示依次从最小的域中查找是否有该键对应的值,直到找到为止 |
方式一 举例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el获取域中的数据</title>
</head>
<body>
<%
request.setAttribute("name","胡子洋");
session.setAttribute("age","18");
%>
${requestScope.name}
${sessionScope.age}
</body>
</html>
方式二 举例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el获取域中的数据</title>
</head>
<body>
<%
request.setAttribute("name","胡子洋");
session.setAttribute("name","乌鸦做胃镜");
%>
${name} <!--胡子洋-->
</body>
</html>
语法 | |
---|---|
${域名城.键名.属性名} | 本质上会去调用对象的getter方法 |
package ytzl; import java.text.SimpleDateFormat; import java.util.Date; /** * @author 玫瑰到了花期 * @data 2022/4/4 13:48 * @love 又偷偷看你了 * @V: CBWR-K */ public class User { private String name; private int age; private Date time; /** * 逻辑视图 * @return * */ public String getBitStr(){ if (time!=null){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return simpleDateFormat.format(time); }else { return ""; } } public User() { } public User(String name, int age, Date time) { this.name = name; this.age = age; this.time = time; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } }
<%@ page import="java.util.Date" %> <%@ page import="ytzl.User" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>el获取对象数据</title> </head> <body> <% User user = new User(); user.setName("周杰伦"); user.setAge(18); user.setTime(new Date()); request.setAttribute("u",user); %> <h3>获取对象中的值</h3> ${requestScope.u} <%-- 通过的是对象的属性来获取 *setter getter方法,去掉set或get然后再将剩余部分,首字母变小写 *setName -->Name -->name --%> ${requestScope.u.name}<br> ${u.age}<br> ${u.time}<br> ${u.time.month+1}<br> ${u.bitStr} </body> </html>
语法 | |
---|---|
list | |
${域名城.键名[索引]} | |
map | |
${域名城.键名.key名称} | |
${域名城.键名[“key名称”]} |
<%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page import="ytzl.User" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>el获取集合</title> </head> <body> <% User user = new User(); List list = new ArrayList(); list.add(1); list.add(2); list.add(user); user.setName("周杰伦"); request.setAttribute("list",list); %> <h3>获取list集合</h3> ${list}<br> ${list[0]}<br> ${list[1]}<br> ${list[2].name} </body> </html>
<%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>空运算符</title> </head> <body> <% String str = "123456"; String str1 = ""; request.setAttribute("str",str); request.setAttribute("str1",str1); List list = new ArrayList(); request.setAttribute("list",list); %> <%--${empty str} 判断字符串、集合、数组对象是否为null,或者长度为0--%> ${empty str} <%--${not empty str1} 判断字符串、集合、数组对象是否不为null,并且长度>0--%> ${not empty str1} ${not empty list} </body> </html>
el表达式中有11个隐式对象
对象 | 说明 |
---|---|
pageContext | 获取jsp其他8个内置对象 |
${pageContext.request.contextPath} | 动态获取虚拟目录 |
JavaServer Pages Tag Library JSP标准标签库
用于简化和替换jsp页面的java代码
标签 | 说明 |
---|---|
if | 相当于java代码的if语句 |
test | 必须属性,接收boolean表达式,如果为true则显示标签体内容 |
<c:if test=“${not empty list}”> | |
c:if标签没有else,想要else情况,则可以再定义一个c:if标签 | |
choose | 相当于java代码的switch语句 |
when | 相当于case,必须有test属性 |
otherwise | 相当于default |
foreach | 相当于java代码的for语句 |
普通for循环 | |
begin | 开始值 |
end | 结束值 |
var | 临时变量 |
step | 自增控制 |
varStatus | 循环状态对象 |
index: 当前下标,从0开始 | |
count: 循环次数,从1开始 | |
<c:forEach begin=“0” end=“9” var=“i” step=“1” varStatus=“s”> | |
遍历容器 | |
items | 容器对象 |
var | 容器中元素的临时变量 |
varStatus | 循环状态对象 |
index: 当前下标,从0开始 | |
count: 循环次数,从1开始 | |
<c:forEach items=“${list}” var=“number” varStatus=“s”> |
<%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>if</title> </head> <body> <%-- c:if标签 1.属性: test 必须属性,接受boolean表达式 如果为true则显示标签体内容 如果为false则不显示标签体内容 一般情况下,test属性值会结合el表达式一起使用 2.注意: c:if标签没有else,想要else情况,则可以再定义一个c:if标签 --%> <%--判断一个集合是否为空,不为空的话输出--%> <% List list = new ArrayList(); list.add("1"); list.add("2"); list.add("3"); request.setAttribute("list",list); request.setAttribute("number",3); %> <c:if test="${not empty list}"> <h1>遍历集合</h1> </c:if> <br> <c:if test="${number/2!=3}"> <h1>number/2!=3</h1> </c:if> <br> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>choose</title> </head> <body> <% request.setAttribute("number",2); %> <c:choose> <c:when test="${number==1}">星期一</c:when> <c:when test="${number==2}">星期二</c:when> <c:when test="${number==3}">星期三</c:when> <c:otherwise>我是傻逼</c:otherwise> </c:choose> </body> </html>
<%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>foreach</title> </head> <body> <% List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); request.setAttribute("list",list); %> <c:forEach begin="0" end="9" var="i" step="1" varStatus="s"> <h${i+1}>周杰伦</h${i+1}> <h3>${s.index}<h3> <h4>${s.count}<h4> </c:forEach> <c:forEach items="${list}" var="number" varStatus="s"> ${s.index} ${s.count} ${number} </c:forEach> </body> </html>
package ytzl; import java.text.SimpleDateFormat; import java.util.Date; /** * @author 玫瑰到了花期 * @data 2022/4/4 13:48 * @love 又偷偷看你了 * @V: CBWR-K */ public class User { private String name; private int age; private Date time; /** * 逻辑视图 * @return * */ public String getBitStr(){ if (time!=null){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return simpleDateFormat.format(time); }else { return ""; } } public User() { } public User(String name, int age, Date time) { this.name = name; this.age = age; this.time = time; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } }
<%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.Date" %> <%@ page import="ytzl.User" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html> <head> <title>table表格</title> </head> <body> <% List list = new ArrayList(); list.add(new User("周杰伦",18,new Date())); list.add(new User("胡子洋",19,new Date())); list.add(new User("葛霄",99,new Date())); request.setAttribute("list",list); %> <table width="500px" height="500px" cellpadding="0px" cellspacing="0px" border="1px solid black"> <tr> <td>编号</td> <td>姓名</td> <td>年龄</td> <td>创建时间</td> </tr> <c:forEach items="${list}" var="user" varStatus="s"> <tr> <td>${s.count}</td> <td>${user.name}</td> <td>${user.age}</td> <td>${user.bitStr}</td> </tr> </c:forEach> </table> </body> </html>
技术选型
数据库设计
开发
测试
部署运维
方法 | 说明 |
---|---|
chain.doFilter(request, response); | 过滤器放行 |
定义一个类,实现接口Filter
复写方法
配置拦截路径
<filter>
<filter-name>demo1</filter-name>
<filter-class>com.ytzl.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
/*拦截路径*/
<url-pattern>/*</url-pattern>
</filter-mapping>
package com.ytzl.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; /** * @author 玫瑰到了花期 * @data 2022/4/14 11:28 * @love 又偷偷看你了 * @V: CBWR-K */ @WebFilter("/*") public class FilterDemo1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("doFilter......"); //是否放行 //放行 chain.doFilter(request,response); } @Override public void destroy() { } }
路径 | 作用 | |
---|---|---|
具体资源路径 | /index.jsp | 只有访问index.jsp资源时,过滤器会被执行 |
拦截目录 | /user/* | 访问/user下的所有资源时,过滤器会被执行 |
后缀名拦截 | *.jsp | 访问所有后缀名为jsp资源时,过滤器会被执行 |
拦截所有资源 | /* | 访问所有资源时,过滤器会被执行 |
注解配置 | 说明 |
---|---|
设置dispatcherTypes属性 | |
REQUEST(request) | 默认值。浏览器直接请求资源 |
FORWARD(forward) | 转发访问资源 |
INCLUDE(include) | 包含访问资源 |
ERROR(error) | 错误跳转资源 |
ASYNC(async) | 异步访问资源 |
package com.ytzl.filter; /** * @author 玫瑰到了花期 * @data 2022/4/16 17:51 * @love 又偷偷看你了 * @V: CBWR-K */ import javax.servlet.*; import javax.servlet.annotation.*; import java.io.IOException; /**浏览器直接请求资源时,该过滤器会被执行转发不会被执行*/ //@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.REQUEST) /**只有转发时才会被执行*/ //@WebFilter(value = "/index.jsp",dispatcherTypes = DispatcherType.FORWARD) /**既可以转发访问,也可以直接请求*/ @WebFilter(value = "/index.jsp",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST}) public class FilterDemo5 implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { //放行 chain.doFilter(request, response); System.out.println("FilterDemo5...."); } @Override public void init(FilterConfig config) throws ServletException { } @Override public void destroy() { } }
配置 | 说明 |
---|---|
设置标签即可 | |
REQUEST(request) | 默认值。浏览器直接请求资源 |
FORWARD(forward) | 转发访问资源 |
INCLUDE(include) | 包含访问资源 |
ERROR(error) | 错误跳转资源 |
ASYNC(async) | 异步访问资源 |
package itcast.Service; /** * @author 玫瑰到了花期 * @data 2022/4/18 17:19 * @love 又偷偷看你了 * @V: CBWR-K */ import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @WebFilter("/*") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { //0.强制转换 HttpServletRequest request1 = (HttpServletRequest) request; //1.获取资源请求的路径 String uri = request1.getRequestURI(); //2.判断是否包含登陆相关路径,要注,排除掉 css/js/图片/验证码等资源 if (uri.contains("/login.jsp")||uri.contains("/LoginServlet")||uri.contains("/css/")||uri.contains("/js/")||uri.contains("/fonts/")||uri.contains("/VerificationCodeServlet")){ //包含,用户就是想登陆。放行 chain.doFilter(request, response); }else { //不包含,需要验证用户是否登陆 //3.从session中获取user Object user = request1.getSession().getAttribute("user"); if (user!=null){ //登陆了,放行 chain.doFilter(request, response); }else { //没有登陆,跳转登陆页面 request1.setAttribute("login_msg","您尚未登录,请登录"); request1.getRequestDispatcher("/login.jsp").forward(request1,response); } } } @Override public void init(FilterConfig config) throws ServletException { } @Override public void destroy() { } }
package itcast.Proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author 玫瑰到了花期 * @data 2022/4/18 17:58 * @love 又偷偷看你了 * @V: CBWR-K */ public class ProxyTest { public static void main(String[] args) { //1.创建真实对象 Lenovo lenovo = new Lenovo(); //2.动态代理,增强lenovo对象 /** * 三个参数 * 1.类加载器 lenovo.getClass().getClassLoader() * 2.接口数组 lenovo.getClass().getInterfaces() * 3.处理器 new InvocationHandler() * */ SaleComputer proxy_Lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() { /** * 代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行 * 参数: * 1、proxy:代理对象 * 2、method:代理对象调用的方法,被封装为的对象 * 3、args:代理对象调用方法时,传递的实际参数 * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* System.out.println("该方法执行了...."); System.out.println(method.getName()); System.out.println(args[0]);*/ //判断是否是sale方法 if (method.getName().equals("sale")){ //1.增强参数 double money = (double) args[0]; money = money * 0.85; System.out.println("专车接你..."); Object obj = method.invoke(lenovo, money); System.out.println("免费送货..."); //2.增强返回值 return obj+"_鼠标垫"; }else { Object obj = method.invoke(lenovo, args); return obj; } } }); //2.调用方法 String computer = proxy_Lenovo.sale(8000); System.out.println(computer); proxy_Lenovo.show(); } }
package itcast.Service; /** * @author 玫瑰到了花期 * @data 2022/4/18 18:22 * @love 又偷偷看你了 * @V: CBWR-K */ import javax.servlet.*; import javax.servlet.annotation.*; import java.io.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; @WebFilter("/*") public class SensitiveWordsFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8"); //1.创建代理对象,增强getParameter方法 ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //增强getParameter方法 //判断是否是getParameter方法 if (method.getName().equals("getParameter")) { //增强返回值 //获取返回值 String value = (String) method.invoke(request, args); if (value != null) { for (String str : list) { if (value.contains(str)) { System.out.println("str==>" + str); value = value.replaceAll(str, "笨蛋"); } } } request.getAttribute(""); return value; } return method.invoke(request, args); } }); //2放行 chain.doFilter(proxy_req, response); } private List<String> list = new ArrayList<String>();//敏感词汇集合 @Override public void init(FilterConfig config) throws ServletException { try { //1.获取文件的真实路径 ServletContext servletContext = config.getServletContext(); String realPath = servletContext.getRealPath("/WEB-INF/敏感词汇.txt"); System.out.println("realPath==>" + realPath); //2.读取文件 BufferedReader br = new BufferedReader(new InputStreamReader(servletContext.getResourceAsStream("/WEB-INF/敏感词汇.txt"), "utf-8")); //BufferedReader br = new BufferedReader(new FileReader(realPath)); //3.将文件的每一行数据设置添加到list中 String line = null; while ((line = br.readLine()) != null) { list.add(line); } System.out.println("list.toString()==>" + list.toString()); br.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public void destroy() { } }
事件监听机制 | 说明 |
---|---|
事件 | 一件事情 |
事件源 | 事件发生的地方 |
监听器 | 一个对象 |
注册监听 | 将事件、事件源、监听器绑定在一起。 |
当事件源上发生某个事件后,执行监听器代码 |
ServletContextListenter | 监听ServletContext对象的创建和销毁 |
---|---|
void contextDestroyed(ServletContextEvent sce) | ServletContext对象被销毁之前会调用该方法 |
void contextInitialized(ServletContextEvent sce) | ServletContext对象创建后会调用该方法 |
定义一个类,实现ServletContextListener接口
复写方法
配置
web.xml
<!-- 配置监听器-->
<listener>
<listener-class>com.ytzl.Listener.ListenerDemo1</listener-class>
</listener>
注解
@WebFilter
<dependencies> <!-- jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- jsp --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/taglibs/standard --> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。