JavaWeb,Tomcat(Apa
JavaWeb,Tomcat(Apa
JavaWeb
什么是JavaWeb?
- JavaWeb就是指所有通过Java语言编写可以通过浏览器访问的程序的总称;
- 一个JavaWeb程序由多个静态web资源和动态资源组成,web程序开发完成后,若要被外界访问,就要把web应用所在的目录交给web服务器管理(虚拟目录的映射);
- JavaWeb是基于请求和响应来开发的;
静态Web
- 指任何时候访问的内容都一致的Web界面,没有交互;
- 静态资源:html、CSS、js、txt、mp4...
动态Web
- 只访问内容随时间改变的Web界面,有交互,一般是与数据库交互;
- 动态资源:jsp页面、Servlet程序...
什么是请求和响应?
请求
- 请求是指客户端向服务器发送数据,Request;
响应
- 响应是指服务器给客户端返回数据,Response;
请求和响应是成对出现的,有请求就有响应;
常用的Web服务器
Web服务器主要用来接收客户端发送的请求和响应客户端的请求;
-
Web服务器主要用来接收客户端发送的请求和响应客户端请求。
-
Tomcat(Apache)( 我们主要撸这只猫 ):当前应用最广的JavaWeb服务器;
-
JBoss(Redhat红帽):支持JavaEE,应用比较广EJB容器 –> SSH轻量级的框架代替
-
GlassFish(Orcale):Oracle开发JavaWeb服务器,应用不是很广;
-
Resin(Caucho):支持JavaEE,应用越来越广;
-
Weblogic(Orcale):要钱的!支持JavaEE,适合大型项目;
-
Websphere(IBM):要钱的!支持JavaEE,适合大型项目
Tomcat服务器
安装教程:
目录介绍
安装教程:
- backup:存放配置文件,是在第一次运行了Tomcat服务器之后产生的,和conf目录下的内容基本一致;
- bin:存放Tomcat服务器的可执行程序,核心包;
- conf:存放Tomcat服务器的配置文件;
- lib:存放Tomcat服务器的jar包;
- logs:存放Tomcat服务器运行时输出的日记信息;
- temp:存放Tomcat服务器运行时产生的临时数据;
- webapps:存放部署的Web工程,里面的一个文件夹就是一个Web工程;
- work:是Tomcat工作时的目录,用来存放Tomcat运行时jsp翻译为Servlet的源码,和Session钝化的目录;
启动Tomcat服务器
- 找到Tomcat安装目录下的bin目录下的startup.bat文件,双击即可启动Tomcat服务器;
- cmd命令行下,进入bin目录下,输入catalina run回车,即可启动;
启动Tomcat一闪而过问题解决:检查JDK的环境配置
测试Tomcat服务器是否开启成功
- 在浏览器中输入以下地址进行测试:
- http://localhost:8080
- http://127.0.0.1:8080
- http://真实IP:8080
关闭Tomcat服务器
- 右上角X号;
- 快捷键Ctrl+C;
- Tomcat的bin目录下的shutdown.bat,双击;
修改Tomcat的端口号
- 找到Tomcat目录下的conf目录下的server.xml配置文件;
- 找到Connector标签,port就是端口号设置,修改它;
- Tomcat默认的端口号是8080;
- HTTP协议默认的端口号是:80;
将web工程部署到Tomcat服务器上
-
将Web工程拷贝到Tomcat安装路径的webapps目录中
- 访问Tomcat中的web工程:浏览器中输入http://ip:port/工程名/目录名/文件名
-
找到Tomcat安装目录中的conf目录下的Catalina目录下的localhost下,创建配置文件XXX.xml
-
<!-- 文件内容: Context 表示一个工程上下文 path 表示工程的访问路径:/abc docBase 表示你的工程目录在哪里--> <Context path="/abc" docBase="E:\book" />
-
访问Tomcat中的web工程:浏览器中输入http://ip:port/abc/ 就代表进入到了E:\book目录下,先要继续访问book文件中的信息,就继续/输入
-
手托html页面到浏览器与在浏览器输入框http://ip:port:工程名/访问的区别
地址栏的默认访问
- 浏览器地址栏如果输入http://ip:port/ 没有工程名,默认访问的就是Tomcat中的webapps目录下的ROOT工程
- 浏览器地址栏中输入http://ip:port/工程名/ 没有资源名,默认访问的就是该工程下的index.html文件
部署在IDEA或者eclipse上
https://blog.csdn.net/weixin_44775516/article/details/109522779
Web工程的目录介绍
- src:存放java代码;
- web:存放web工程的资源文件,html、css...
- WEB-INF:是一个受服务器保护的目录,浏览器无法直接访问到此目录中
- lib:存放第三方jar包,jar包需要配置
- web.xml:是整个动态web工程的配置部署文件,可以配置Servlet程序、Filter过滤器、Listener监听器、Session超时...组件
Web 中的相对路径和绝对路径
-
相对路径是:
- . 表示当前目录
- .. 表示上一级目录
- 资源名 表示当前目录/资源名
-
绝对路径:
- http://ip:port/工程路径/资源路径
web 中/ 斜杠的不同意义
- 在web中,/斜杠是一种绝对路径
- /斜杠在浏览器中被解析,地址是:http://ip:port/
- <a href="/">斜杠</a>
- / 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
- <url-pattern>/servlet1</url-pattern>
- servletContext.getRealPath(“/”);
- request.getRequestDispatcher(“/”);
- 特殊情况: response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到http://ip:port/
Servlet
什么是Servlet?
- Servlet(Server Applet),全称Java Servlet;
- Servlet是JavaEE规范之一,就是接口,是用java编写的服务端程序;
- Servlet是JavaWeb三大组件之一,都有:Servlet程序、Filter过滤器、Listener监听器;
- Servlet是运行在服务器上的一个Java小程序,它可以接受客户端发送过来的请求,并响应数据给客户端;
第一个Servlet程序
- 编写一个类要实现Servlet接口
- 实现接口中的service()方法,用于处理请求与响应数据
- 在web.xml中配置Servlet程序的访问地址
这种方式一般不使用,我们继承他的实现类HttpServlet
这种方式一般不使用,我们继承他的实现类HttpServlet
JAVA代码:
public class Servlet1 implements Servlet {
@Override//初始化
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法是用来专门处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override//销毁
public void destroy() {
}
}
web.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--welcome-file-list标签是当Tomcat服务启动时,默认跳到哪个资源,
其实这个不用设置,默认也会跳转到index.html或者index.jsp资源的
-->
<welcome-file-list>
<!--welcome-file标签就是要跳转的资源-->
<welcome-file>HolleWord.html</welcome-file>
</welcome-file-list>
<!--service标签是给Tomcat配置Servlet程序的 -->
<servlet>
<!--servlet-name标签是给Servlet程序起一个别名-->
<servlet-name>Servlet1</servlet-name>
<!--servlet-class标签是Servlet程序的全类名-->
<servlet-class>com.mlyr.Servlet1</servlet-class>
</servlet>
<!--servlet-mapping标签给Servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签的作用是告诉服务器,当前配置的地址给谁用-->
<servlet-name>Servlet1</servlet-name>
<!--
url-pattern标签配置访问地址
/ 在服务器解析时,会被解析为http://ip:port/工程名
/servlet1表示地址为:http://ip:port/工程名/servlet1
-->
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
</web-app>
URL地址到Servlet程序的访问
Servlet的生命周期
- 第一步:执行Servlet构造器方法;
- 第二步:执行init()初始化方法;
- 第三步:执行service()方法;
- 第四步:执行destroy()销毁方法;
第一部与第二步,只在第一次访问,创建Servlet程序的时候会执行;
第三步,每次访问Servlet程序的时候都会执行;
第四步,只当web工程停止的时候,会执行;
GET、POET请求的分发处理
- getMethod():可以获取请求过来的方式,是GET请求还是POST请求
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//类型转换,HttpServletRequest有getMethod()方法,
HttpServletRequest request = (HttpServletRequest) servletRequest;
//可以获取请求的方式
String method = request.getMethod();
//将不同的请求,分为两个方法,分别处理
if (method.equals("GET")){
doGet();
}else if (method.equals("POST")){
doPost();
}
}
private void doPost() {
System.out.println("POST请求");
}
private void doGet() {
System.out.println("GET请求");
}
主要类与方法
HttpServlet类
- 一般实现Servlet程序,都是使用继承HttpServlet类的方式来开发;
- 它在Servlet接口的基础上,分开了请求方式,还有一系列方法;
- 编写一个类继承HttpServlet类
- 重写它的doGet()、doPost()方法;
- 到web.xml文件中配置Servlet程序的访问地址
HttpServlet类的方法:
- doPost():处理post请求;
- doGet():处理get请求;
java代码
public class Servlet2 extends HttpServlet {
/**
* 只有在post请求时调用
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet2 doPost 方法");
}
/**
* 只有在get请求时调用
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet2 doGet 方法");
}
}
web.xml文件配置
<servlet>
<servlet-name>Servlet2</servlet-name>
<servlet-class>com.mlyr.Servlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet2</servlet-name>
<url-pattern>/servlet2</url-pattern>
</servlet-mapping>
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="servlet2" method="post">
<input type="submit">
</form>
</body>
</html>
- 当表单请求是post方法,只会调用Servlet2类中的doPost()方法!
IDEA中能够一键生成Servlet程序:右击包->点击NEW->Create New Servlet(在下面找)->Name框(自定义类名)
根据IDEA版本不同,会注解声明访问地址或者web.xml文件中声明
@WebServlet(name="Servlet3",urlPatterns = "/servlet3")这就是注解声明访问地址,idea自动生成的有问题,要自行修改
Servlet类的继承体系
ServletConfig类
- ServletConfig类是Servlet程序的配置信息类;
- Servlet程序和ServletConfig对象都是由Tomcat负责创建的,Servlet程序是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象;
ServletConfig类的作用
- 可以获取Servlet程序的别名,就是servlet-name标签中的值;
- 获取初始化参数init-param标签中的值;
- init-param标签只能在servlet标签中定义,它只属于它所在的Servlet程序;
- 只能被ServletConfig对象获取;
- 获取ServletContext对象;
ServletConfig类中的方法:
- getServletName():获取web.xml配置文件中servlet-name标签的值;
- getInitParameter(参数):获取init-param标签中的值;
- 参数:param-name标签
- 获取到param-value标签的值,这两个标签好比键值对
- getServletContext():返回ServletContext对象;
web.xml文件配置
<servlet>
<servlet-name>Servlet2</servlet-name>
<servlet-class>com.mlyr.Servlet2</servlet-class>
<!--init-param标签是初始化参数,这个只属于Servlet2程序中的,别的程序访问不到-->
<init-param>
<!--参数的名字-->
<param-name>username</param-name>
<!--参数的值-->
<param-value>root</param-value>
</init-param>
<init-param>
<!--参数的名字-->
<param-name>password</param-name>
<!--参数的值-->
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Servlet2</servlet-name>
<url-pattern>/servlet2</url-pattern>
</servlet-mapping>
Java代码
public class Servlet2 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//获取Servlet程序的别名,就是servlet-name标签的值
System.out.println(servletConfig.getServletName());
//获取初始化参数,init-param标签中的
System.out.println("username:"+servletConfig.getInitParameter("username"));
System.out.println("password:"+servletConfig.getInitParameter("password"));
//获取ServletContext对象
System.out.println(servletConfig.getServletContext());
}
}
上方的是实现了Servlet接口,init()方法自然会重写Servlet接口中的方法;
下方:如果继承了HttpServlet类,它的父抽象类GenericServlet中有两个init()方法,一个是从接口Servlet中实现的有参方法,还有一个无参init()方法是独有的,如果自定义的类要重写HttpServlet类中的init()有参方法,一定要调用super.init(config);不然会在使用ServletConfig对象的时候会报500错误(内部服务器错误),空指针异常;
ServletContext类
- ServletContext是一个接口,表示Servlet上下文对象;
- 一个web工程只有一个ServletContext对象;
- ServletContext对象是一个域对象;
- 域对象,是可以像Map一样存取数据的对象;
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
- ServletContext在web工程启动的时候创建,在web工程停止的时候销毁;
ServletContext类的作用
- 获取web.xml中配置的上下文参数context-param标签;
- context-param标签是不能在servlet标签中的,只能在最外面,属于整个web工程,不单单只属于哪一个Servlet程序;
- 只能被ServletContext对象获取;
- 获取当前工程路径
- 获取工程部署后在服务器硬盘上的绝对路径;
- 像Map一样存取数据;
ServletContext类中的方法
- getInitParameter(参数):获取context-param标签中的数据;
- getContextPath():获取当前工程的路径;
- getRealPath(参数):获取工程部署后在服务器硬盘上的绝对路径;
- 参数/: 斜杠在服务器上会被解析为http://ip:port/工程名/ 就是映射到IDEA代码的web目录
- sc.getRealPath("/img"):表示获取该工程下的img目录在工程部署后在服务器硬盘上的绝对路径;
- setAttribute(别名,对象):将一个对象存储到ServletContext对象中,起个别名;
- getAttribute(别名):通过别名获取存入其中的对象;
- removeAttribute(别名):删除该别名中的对象;
web.xml文件配置
<!--context-param是上下文参数,属于整个web工程,都能访问到-->
<context-param>
<!--param-name与param-value是存储数据的标签-->
<param-name>name</param-name>
<param-value>ROOT</param-value>
</context-param>
<context-param>
<param-name>PSW</param-name>
<param-value>123</param-value>
</context-param>
Java代码
public class Servlet4 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext 对象
ServletContext sc = getServletContext();
//获取web.xml中配置的上下文参数,context-param标签中的数据
System.out.println("name:"+sc.getInitParameter("name"));//name:ROOT
System.out.println("PSW:"+sc.getInitParameter("PSW"));//PSW:123
//获取当前的工程路径
System.out.println("当前工程路径"+sc.getContextPath());//当前工程路径/JavaWeb_4
//获取工程部署后在服务器硬盘上的绝对路径
// / 斜杠在服务器上会被解析为http://ip:port/工程名/ 就是映射到IDEA代码的web目录
System.out.println("工程部署的路径是:"+sc.getRealPath("/"));//工程部署的路径是:E:\IDEA\JavaWeb_4\out\artifacts\JavaWeb_4_war_exploded\
System.out.println("工程下img目录的绝对路径是:"+sc.getRealPath("/img"));//工程下img目录的绝对路径是:E:\IDEA\JavaWeb_4\out\artifacts\JavaWeb_4_war_exploded\img
System.out.println("工程下img目录下的1.jpg文件的绝对路径是:"+sc.getRealPath("/img/1.jpg"));//工程下img目录下的1.jpg文件的绝对路径是:E:\IDEA\JavaWeb_4\out\artifacts\JavaWeb_4_war_exploded\img\1.jpg
// 获取ServletContext 对象
ServletContext context = getServletContext();
System.out.println(context);
System.out.println("保存之前:获取key的值是:"+ context.getAttribute("key"));//保存之前:获取key的值是:null
//在key中存储一个对象
context.setAttribute("key", "value");
System.out.println("存储之后:获取域数据key的值是:"+ context.getAttribute("key"));//存储之后:获取域数据key的值是:value
//删除key里面存储的对象
context.removeAttribute("key");
//上面的删除了key里面的对象,下面将获取不到
System.out.println("存储之后:获取域数据key的值是:"+ context.getAttribute("key"));//存储之后:获取域数据key的值是:null
}
}
这个上面的工程路径是IDEA整合Tomcat之后,Tomcat被拷贝的一些副本内容,就是将IDEA实际存在的项目,映射进Tomcat服务器中;
setAttribute存储的对象,要先存进去,然后整个web工程中所有Servlet程序才能够访问到,没有存储到ServletContext对象中,是获取不到的;
HttpServletRequest类
- 每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中,然后传递到service方法(doGet、doPost方法)中供我们使用;
- 通过HTTPServletRequest对象,可以获取所有请求的信息;
HTTPServletRequest类的方法
- getRequestURI() 获取请求的资源路径
- getRequestURL() 获取请求的统一资源定位符(绝对路径)
- getRemoteHost() 获取客户端的ip 地址
- getHeader(参数) 获取请求头
- 参数:要获取的请求头名称
- getMethod() 获取请求的方式GET 或POST
- getParameter(参数) 获取请求的参数
- 参数:要请求哪一个参数的值
- getParameterValues(参数) 获取请求的多个参数
- 参数:要请求哪一个参数的值
- setAttribute(别名,对象) 将对象作为request对象的一个属性存放到request对象中;
- 别名:String类型,就相当于request对象中的一个属性,自己起名;
- 对象:Object类型
- getAttribute(别名) 获取request对象中该别名的值(这个值可以是任何类型)
- getRequestDispatcher(参数) 获取请求转发对象
- 参数:就是要转发给谁
- getRequestDispatcher(参数).forward(request,response) 转发
java代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的资源路径
System.out.println("URI:"+request.getRequestURI());//URI:/JavaWeb_4/servlet5
//获取请求的统一资源定位符(绝对路径)
System.out.println("URL:"+request.getRequestURL());//URL:http://localhost:8080/JavaWeb_4/servlet5
//获取客户端的ip 地址
//IP:0:0:0:0:0:0:0:1 客户端localhost:8080访问,这个是ipv6的表现形式,对应ipv4来说相当于127.0.0.1
//IP:192.168.137.1 使用真实IP地址访问
//IP:127.0.0.1 客户端127.0.0.1:8080访问
System.out.println("IP:"+request.getRemoteHost());
//获取请求头
System.out.println("User-Agent请求头"+request.getHeader("User-Agent"));//User-Agent请求头Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36
System.out.println("Accept-Language请求头"+request.getHeader("Accept-Language"));//Accept-Language请求头zh-CN,zh;q=0.9
//获取请求的方式GET 或POST
System.out.println(request.getMethod());//GET
////////////////////////////////////////////////////////////////
//获取请求参数,就是获取表单提交过来的参数值
System.out.println("用户名:"+request.getParameter("username"));//用户名:MLYR
System.out.println("密码:"+request.getParameter("password"));//密码:123
//获取请求的多个参数
String[] hobby = request.getParameterValues("hobby");
System.out.println("兴趣爱好:"+ Arrays.toString(hobby));//兴趣爱好:[java, js]
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的字符集编码为UTF-8,如果不设置,输入中文会乱码
req.setCharacterEncoding("UTF-8");
//获取当前请求的字符编码,需要提前设置,不然是null
System.out.println(req.getCharacterEncoding());//UTF-8
//获取请求参数,就是获取表单提交过来的参数值
System.out.println("用户名:"+req.getParameter("username"));//用户名:中
System.out.println("密码:"+req.getParameter("password"));//密码:1212
//获取多个请求的参数
String[] hobby = req.getParameterValues("hobby");
System.out.println("兴趣爱好:"+ Arrays.toString(hobby));//兴趣爱好:[cpp, java]
}
表单代码
<form action="servlet5" method="get">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
</form>
doGet()请求一般不会乱码,如果有,按照下面的方法解决:
String username = request.getParameter("username");
//先以iso-8859-1进行编码,再以utf-8进行解码
username = new String(username.getBytes("iso-8859-1"),"UTF-8");
//获取请求参数,就是获取表单提交过来的参数值
System.out.println("用户名:"+username);
HttpServletResponse类
- HttpServletResponse类和HttpServletRequest类一样,每一次请求进来,Tomcat服务器都会创建一个Response对象和Request对象;
- HttpServletResponse表示所有的响应信息,HttpServletRequest表示请求过来的信息;
- 要返回给客户端信息,都是通过Response对象进行设置;
两个输出流
- getOutputStream() 字节流,常用于下载,传递二进制;
- getWriter() 字符流,常用于回传字符串
- 两个流不能同时使用;
HttpServletResponse类的方法
- setContentType() 同时设置服务器和客户端的编码格式
- setCharacterEncoding() 设置服务器的编码格式
- setStatus(参数) 设置响应状态吗,表示重定向
- setHeader() 通过响应头设置浏览器的编码格式
- getWriter() 获取字符输出流对象PrintWriter
- writer(参数) 写数据,参数可以是Object、int、String、数组、double...
- getOutputStream() 获取字节输出流对象ServletOutputStream
- print(参数) 写数据,,参数可以是int、String、数组、double...不能写对象
- sendRedirect(参数) 重定向
- 参数:要重定向的路径
java代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//它会同时设置服务器和客户端都使用UTF-8 字符集,还设置了响应头
//此方法一定要在获取流对象之前调用才有效
response.setContentType("text/html; charset=UTF-8");
//设置服务器字符集为UTF-8
response.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器也使用UTF-8 字符集
response.setHeader("Content-Type", "text/html; charset=UTF-8");
//CharConversionException: 不是ISO 8859-1字符:[啦]
System.out.println("doGet方法");
//获取字符输出流对象
//PrintWriter writer = response.getWriter();
//写数据
//writer.println("啦啦啦lll");
//获取字节输出流对象
ServletOutputStream os = response.getOutputStream();
//写数据
os.print(121212121);
}
java.lang.IllegalStateException: 当前响应已经调用了方法getOutputStream()
两个流一起使用报错
请求转发与重定向
请求转发
- 服务器收到请求后,从一次资源跳转到另一个资源的操作,叫做请求转发;
表单
<form action="servlet6" method="post">
信息:<input type="text" name="xinxi"><br/>
<input type="submit">
</form>
Servlet6
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求的字符集编码
req.setCharacterEncoding("UTF-8");
//获取请求参数
String xinxi = req.getParameter("xinxi");
System.out.println(xinxi);//陌路邑人
//设置数据域,就是将一个对象放进数据域中,起个别名key
req.setAttribute("key","来自Servlet6");
//获取要转发给的地址对象(一般与下面执行转发是一步编写) /servlet7就是http://localhost:8080/JavaWeb_4/servlet7
RequestDispatcher rd = req.getRequestDispatcher("/servlet7");
//执行转发操作
rd.forward(req,resp);
}
Servlet7
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//doPost方法中,必须是POST请求,才能被获取
//获取请求参数
String xinxi = request.getParameter("xinxi");//陌路邑人
System.out.println(xinxi);
//获取Servlet6转发过来的对象
Object key = request.getAttribute("key");
System.out.println("Servlet7获取到Servlet6转发过来的对象:"+key);//Servlet7获取到Servlet6转发过来的对象:来自Servlet6
}
表单中的提交是post请求方式,所以在两个Servlet程序中,想要获取表单提交的数据,必须也是doPost方法进行获取;
a标签的转发
web工程下d.html
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<!--下方的可以与HTML下的e.html互相跳转-->
<a href="HTML/e.html">b.html</a>
<!--该标签跳转到servlet7程序配置的路径上-->
<a href="servlet7">请求转发</a>
</body>
HTML下e.html
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--base 标签设置页面相对路径工作时参照的地址href 属性就是参数的地址值-->
<base href="http://localhost:8080/JavaWeb_4/HTML/e.html">
</head>
<body>
<a href="../d.html">回到首页</a>
</body>
Servlet7
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("经过了Servlet7程序");
//如果有请求到这,进行转发到HTML下的e.html
request.getRequestDispatcher("/HTML/e.html").forward(request,response);
}
这种情况没有base标签给e.html进行参照路径的话,他就会报错,找不到文件;
下面解释:
- 当首先访问web工程下的d.html文件时,它的绝对路径是http://localhost:8080/JavaWeb_4/d.html;
- 当点击请求转发连接时,他就会跳到Servlet7程序所配置的路径上:http://localhost:8080/JavaWeb_4/servlet7;
- 然后当点击回到首页连接时,它相当于将a标签中的../d.html路径与他现在所在的路径进行拼接跳转,就会跳转到http://localhost:8080/JavaWeb_4/d.html(http://localhost:8080/JavaWeb_4/servlet7../d.html,../相当于与前面的目录相抵消)路径,当然找不到文件;
- 当base标签给e.html文件给定一个绝对路径http://localhost:8080/JavaWeb_4/HTML/e.html,就是该文件的绝对路径,不管怎么与a标签上的../d.html进行拼接,他就可以找到正确的路径
重定向
- 请求重定向,是指客户端给服务器发送请求后,返回服务器给客户端一个新地址,让客户端重新去访问新地址;
java代码
//Servlet9
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("来晚了");
/*request.setAttribute("kk","KKKKKK");
//第一种重定向方式
//设置响应状态吗,表市重定向
response.setStatus(302);
//设置响应头,说明新地址
response.setHeader("Location","servlet8");*/
//第二种重定向,参数不能加/斜杠,这里的/会被服务器解析为http://localhost:8080/
response.sendRedirect("servlet8");
}
//Servlet8
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet8doGet方法");
//重定向不共享Request对象中的数据域
System.out.println(req.getAttribute("kk"));
}
转发与重定向的区别
- 路径区别
- 相对路径没有区别;
- 绝对路径:
- 转发:中的/表示:http://ip:port/工程路径;
- 重定向:中的/表示:http://ip:port/;
- 地址栏的变化
- 转发:地址栏不会显示出转发后的地址;
- 重定向:则是完全跳转到新地址,地址栏也就是新地址;
- Request对象中的数据
- 转发:不会丢失数据;
- 重定向:会丢失数据;
- 请求次数
- 转发:客户端只向服务器发送一次请求;
- 重定向:客户端发送了两次请求给服务器;
- 跳转位置
- 转发:在服务器中跳转;
- 重定向:返回给客户端新地址,客户端跳转;
- 访问域
- 转发:只能在web工程中访问跳转;
- 重定向:可以跨域访问跳转;就是随便跳;
- 能否访问web工程的WEB-INF目录
- 转发:可以访问;
- 重定向:不可以访问;
监听器
什么是监听器?
- Listener监听器是JavaWeb的三大组件之一;
- 作用:监听某种事物的变化,然后通过回调函数,反馈给客户;
ServletContextListener监听器
- ServletContextListener 它可以监听ServletContext 对象的创建和销毁
- ServletContext 对象在web 工程启动的时候创建,在web 工程停止的时候销毁。
- 监听到创建和销毁之后都会分别调用ServletContextListener 监听器的方法反馈
public interface ServletContextListener extends EventListener {
//在ServletContext 对象创建之后马上调用,做初始化
public void contextInitialized(ServletContextEvent sce);
//在ServletContext 对象销毁之后调用
public void contextDestroyed(ServletContextEvent sce);
}
如何实现ServletContextListener监听器监听ServletContext对象
public class Listener1 implements ServletContextListener{
//ServletContext对象在创建的时候执行
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象创建了");
}
//ServletContext对象在销毁的时候被执行
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象销毁了");
}
}
<!--配置监听器-->
<listener>
<listener-class>com.mlyr.listener.Listener1</listener-class>
</listener>
ServletContextListener监听器的主要作用
- 初始化工作:初始化对象,初始化数据,比如加载数据库驱动,对连接池的初始化。
- 加载一些初始化的配置文件;
Cookie
什么是Cookie?
- Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息;
为什么需要Cookie?
- 因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是否来源于同一个浏览器;
- 所以,需要额外的数据用于维护会话;Cookie正是这样一段随HTTP请求一起被传递的额外数据;
Cookie的注意点
能不能一次发送多个Cookie?
- 可以,可以创建多个Cookie对象,使用response调用多次addCookie方法发送即可;
Cookie能不能存中文?
- 在Tomcat8之前不能存中文,要进行URL编码(%E3)或者BASE64编码将中文数据转码
- 在Tomcat8之后支持中文数据,但是特殊字符还是不支持;
Cookie大小限制
- 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)
Cookie的创建、获取、修改
html页面
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cookie</title>
<base href="http://localhost:8080/JavaWeb_4/">
<style type="text/css">
ul li {
list-style: none;
}
</style>
</head>
<body>
<iframe name="target" width="500" height="500" ></iframe>
<div >
<ul>
<li><a href="cookie1?action=createCookie" target="target">Cookie的创建</a></li>
<li><a href="cookie1?action=getCookie" target="target">Cookie的获取</a></li>
<li><a href="cookie1?action=updateCookie" target="target">Cookie值的修改</a></li>
<li>Cookie的存活周期</li>
<li>
<ul>
<li><a href="cookie1?action=defaultLife" target="target">Cookie的默认存活时间(会话)</a></li>
<li><a href="cookie1?action=deleteNow" target="target">Cookie立即删除</a></li>
<li><a href="cookie1?action=life3600" target="target">Cookie存活3600秒(1小时)</a></li>
</ul>
</li>
<li><a href="cookie1?action=testPath" target="target">Cookie的路径设置</a></li>
<li><a href="" target="target">Cookie的用户免登录练习</a></li>
</ul>
</div>
</body>
</html>
java代码
package com.mlyr.Cookie;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Cookie1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
String action = request.getParameter("action");
switch (action){
case "createCookie":
createCookie(request,response);
break;
case "getCookie":
getCookie(request,response);
break;
case "updateCookie":
updateCookie(request,response);
break;
}
}
// Cookie的创建
protected void createCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie1 = new Cookie("key1", "value1");
Cookie cookie2 = new Cookie("key2", "value2");
//保存到客户端
response.addCookie(cookie1);
response.addCookie(cookie2);
//返回信息给客户端页面
response.getWriter().write("Cookie创建成功{Cookie1:"+cookie1+"-->Cookie2:"+cookie2+"}");
}
// Cookie的获取
protected void getCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通过请求获取客户端中的Cookie数组
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
//getName():获取到Cookie的key值
//getValue():获取到Cookie的value值
response.getWriter().write("key=="+cookie.getName()+"-->value=="+cookie.getValue()+"\n");
}
Cookie key1 = CookieUtils.findCookie("key1", cookies);
String value = key1.getValue();
response.getWriter().write("key1=="+value);
}
// Cookie的修改
protected void updateCookie(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//第一种方式:直接创建一个新的Cookie对象,key值与要修改的一样,直接覆盖掉原来的
Cookie cookie = new Cookie("key1", "我改了");
response.addCookie(cookie);
//第二种方式:先找到要修改的Cookie对象,调用setValue()方法修改值
Cookie key2 = CookieUtils.findCookie("key2", request.getCookies());
if (key2!=null){
//修改
key2.setValue("人傻了");
//通知客户端
response.addCookie(key2);
}else {
System.out.println("没找到");
}
}
}
查找Cookie
import javax.servlet.http.Cookie;
// Cookie工具类
public class CookieUtils {
public static Cookie findCookie(String name,Cookie[] cookies ){
//判断当名字、Cookie数组任意一个为null时,就没有必要查询了
if (name == null || cookies == null || cookies.length ==0){
return null;
}
//循环遍历Cookie数组
for (Cookie cookie : cookies) {
//当name与cookie中的key值相同就返回它
if (name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
}
Cookie的生命周期
- setMaxAge(int seconds):这个方法就是设置Cookie的保存时间的方法;
- 正数:要保存的时间秒数,将Cookie数据写到硬盘中;
- 负数:默认值,当浏览器关闭,Cookie数据被销毁;
- 零:删除Cookie信息;
//Cookie的立即删除
private void deleteNow(HttpServletRequest request, HttpServletResponse response) throws IOException {
Cookie key3 = CookieUtils.findCookie("key3", request.getCookies());
if (key3!=null){
key3.setMaxAge(0);
response.addCookie(key3);
response.getWriter().write("Key3已经删除!!!");
}
}
//保存3600秒
private void life3600(HttpServletRequest request, HttpServletResponse response) throws IOException {
Cookie key4 = new Cookie("key4", "3600");
//设置保存key4的时间
key4.setMaxAge(60*60);
response.addCookie(key4);
response.getWriter().write("Key4已经设置保存时间1小时");
}
Cookie的共享设置
- 默认的Cookie只能在一个应用中共享,即一个Cookie只能由创建它的应用获得。
- setPath():设置cookie的共享范围;
- cookie.setPath("/"):可在同一应用服务器内共享方法
- cookie.setPath(request.getContextPath()+"/HTML");只在该工程的HTML下共享,别的目录下获取不到
private void testPath(HttpServletRequest request, HttpServletResponse response) throws IOException {
Cookie cookie = new Cookie("key5", "有效路径");
cookie.setPath(request.getContextPath()+"/HTML");
response.addCookie(cookie);
response.getWriter().write("创建了一个带有路径的cookie");
}
免输入用户名登录
java代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取到请求进来的用户名与密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//先给定一个死的值
if ("111111".equals(username) && "111111".equals(password)){
//将请求进来的用户名放入Cookie对象中
Cookie cookie = new Cookie("username",username);
//设置它的保存时间
cookie.setMaxAge(60*60*60);
//返回给客户端
response.addCookie(cookie);
System.out.println("登陆成功");
}else{
System.out.println("登录失败");
}
}
jsp页面
- jap页面中的用户名输入框中的value值就在cookie域中拿就行,第一次没有默认就为空,第二次访问时,Cookie域中就会保存有用户名,当访问时就有了用户名
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/JavaWeb_4/cookie2" method="get">
用户名:<input type="text" name="username" value="${cookie.username.value}"> <br>
密码:<input type="password" name="password"> <br>
<input type="submit" value="登录">
</form>
</body>
</html>
Session
什么是Session?
- Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术;
- Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
- 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了
创建Session对象、Session域中的存取
HTML页面
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Session</title>
<base href="http://localhost:8080/JavaWeb_4/">
<style type="text/css">
ul li {
list-style: none;
}
</style>
</head>
<body>
<iframe name="target" width="500" height="500" ></iframe>
<div >
<ul>
<li><a href="session1?action=createOrGetSession" target="target">Session的创建和获取(id号、是否为新创建)</a></li>
<li><a href="session1?action=setAttribute" target="target">Session域数据的存储</a></li>
<li><a href="session1?action=getAttribute" target="target">Session域数据的获取</a></li>
<li>Session的存活</li>
<li>
<ul>
<li><a href="session1?action=defaultLife" target="target">Session的默认超时及配置</a></li>
<li><a href="session1?action=life3" target="target">Session3秒超时销毁</a></li>
<li><a href="session1?action=deleteNow" target="target">Session马上销毁</a></li>
</ul>
</li>
<li><a href="" target="target">浏览器和Session绑定的原理</a></li>
</ul>
</div>
</body>
</html>
java代码
package com.mlyr;
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;
@WebServlet("/session1")
public class Session1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String action = request.getParameter("action");
switch (action){
case "createOrGetSession":
createOrGetSession(request,response);
break;
case "setAttribute":
setAttribute(request,response);
break;
case "getAttribute":
getAttribute(request,response);
break;
}
}
//Session的创建和获取(id号、是否为新创建)
protected void createOrGetSession(HttpServletRequest request, HttpServletResponse response) throws IOException {
//创建Session对象
HttpSession session = request.getSession();
//获取Session对象的ID值
String id = session.getId();
//判断Session是否刚刚创建的
boolean aNew = session.isNew();
//将结果响应给页面
response.getWriter().write("Session对象:"+session+"\n");
response.getWriter().write("Session对象的ID值:"+id+"\n");
response.getWriter().write("判断Session是否刚刚创建的:"+aNew+"\n");
}
//Session域数据的存储
protected void setAttribute(HttpServletRequest request, HttpServletResponse response) throws IOException {
//向Session域中存放数据
request.getSession().setAttribute("key1","value1");
response.getWriter().write("Session域数据的存储完成");
}
//Session域数据的获取
protected void getAttribute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
//获取Session域中的数据
Object key1 = request.getSession().getAttribute("key1");
response.getWriter().write("获取Session域中的数据:"+key1);
}
}
Session生命周期
- public void setMaxInactiveInterval(int interval) 设置Session 的超时时间(以秒为单位),超过指定的时长,Session就会被销毁。
- 值为正数的时候,设定Session 的超时时长。
- 负数表示永不超时(极少使用)
- public int getMaxInactiveInterval()获取Session 的超时时间
- public void invalidate() 让当前Session会话马上超时无效
Session的默认Session超时时长
- IDEA中Using CATALINA_BASE整合后的路径下,web.xml配置文件中默认配置了Session的超时时长为30分钟
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- 如果想修改整个Web工程的所有Session超时时长,可以在Web工程下的web.xml配置文件中添加配置,就是上面的
- 如果只想修改个别Session的超时时长,使用setMaxInactiveInterval()方法单独设置
//Session的默认超时及配置
protected void defaultLife(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
int maxInactiveInterval = request.getSession().getMaxInactiveInterval();
response.getWriter().write("Session的默认超时时长:"+maxInactiveInterval);
}
//Session3秒超时销毁
protected void life3(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
request.getSession().setMaxInactiveInterval(3);
response.getWriter().write("已经设置Session的超时时长为3秒");
}
//Session马上销毁
protected void deleteNow(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.getSession().invalidate();
response.getWriter().write("设置Session立即销毁");
}
Session的实现原理
- Session 技术,底层其实是基于Cookie 技术来实现的。
session和cookie的联系和区别
- session和cookie都可以保存跟特定会话关联的信息
- session的信息是存放在服务器端的,cookie的信息是存放在浏览器端
- session中可以存放Object,cookie只能存放字符串信息
过滤器
是什么过滤器?
- Filter过滤器是JavaWeb的三大组件之一;
- 过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理,通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理;
- 它的作用:拦截请求,过滤响应;
- 拦截请求的常见应用场景:权限检查、日记操作、事务管理...
- 拦截请求的常见应用场景:权限检查、日记操作、事务管理...
创建一个Filter过滤器
- 权限设定,没有登录的不能直接访问web工程下的HTML目录下的所有资源
首先一个登陆页面
- 提交到LoginServlet程序
<form action="http://localhost:8080/JavaWeb_4/loginservlet" method="get">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="password" name="password"/><br/>
<input type="submit"/>
</form>
LoginServlet程序
@WebServlet(name = "LoginServlet",urlPatterns = "/loginservlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//处理响应乱码
response.setContentType("text/jsp;charset=UTF-8");
//获取输入的用户名以及密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//先给定一个值
if ("abcdef".equals(username) && "123456".equals(password)){
//如果用户名密码正确,将用户名保存在Session域中
request.getSession().setAttribute("username",username);
response.getWriter().write("登陆成功!!!");
}else {
request.getRequestDispatcher("/index.jsp").forward(request,response);
}
}
}
登陆成功之后将用户名放入到Session域中
创建Filter过滤器
public class Filter1 implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//通过ServletRequest请转获取到HttpServletRequest请求
HttpServletRequest request = (HttpServletRequest) req;
//通过request请求再获取Session域
HttpSession session = request.getSession();
//查询Session与中是否有用户名信息,有说明已经登录,可访问HTML下的
Object username = session.getAttribute("username");
//为null,就说明没有登录
if (username == null) {
//没有登录就重定向到登录页面
req.getRequestDispatcher("/index.jsp").forward(req, resp);
} else {
//登录的话,就放行,该请求哪里就让他到哪里
chain.doFilter(req, resp);
}
}
}
当Session域中没有用户名的时候(用户没有登录),放强行访问HTML下的资源时,就会被过滤器重定向到登录页面,只有当Session域中存在用户名时,才会被过滤器放行允许其访问HTML下的资源
Filter过滤器的web配置
<!--filter 标签用于配置一个Filter 过滤器-->
<filter>
<!--给filter起一个别名-->
<filter-name>Filter1</filter-name>
<!--配置filter的全类名-->
<filter-class>com.mlyr.filter.Filter1</filter-class>
</filter>
<!--filter过滤器拦截的路径-->
<filter-mapping>
<!--给那个filter过滤器使用-->
<filter-name>Filter1</filter-name>
<!--url-pattern:配置filter的拦截路径
/ 表示http://ip:port/工程路径/ 映射到web目录
/HTML/*</ 表示拦截http://ip:port/工程路径/HTML/目录下的所有文件及目录
-->
<url-pattern>/HTML/*</url-pattern>
</filter-mapping>
Filter的生命周期
public class Filter2 implements Filter {
//构造方法
public Filter2() {}
@Override//init()初始化方法
public void init(FilterConfig filterConfig) throws ServletException {}
@Override//doFilter()过滤方法
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}
@Override//destroy()销毁方法
public void destroy() {}
}
构造方法与init()初始化方法在web工程启动的时候执行
doFilter()过滤方法在每次拦截到请求时执行
destroy()销毁方法在停止web工程的时候执行
FilterConfig类
- 它是Filter过滤器的配置文件类
- 当web工程创建Filter过滤器时,同时会创建一个FilterConfig类
- 它的作用:获取Filter过滤器的配置内容
- 获取Filter的名称,也就是filter-name标签中的内容
- 获取Filter中配置的init-param初始化的内容
- 获取ServletContext对象
public void init(FilterConfig config) throws ServletException {
//获取Filter过滤器名字
System.out.println(config.getFilterName());//Filter3
//获取init初始化内容
System.out.println(config.getInitParameter("name"));//张三
//获取ServletContext对象
ServletContext servletContext = config.getServletContext();
}
<filter>
<filter-name>Filter3</filter-name>
<filter-class>com.mlyr.filter.Filter3</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Filter3</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
FilterChain过滤链
- 如果有多个过滤器,它就形成了一个FilterChain过滤器链
- 那个Filter先执行与Filter的配置相关,在web.xml配置文件中,那个配置在最前方,那个就先执行
- 第一个执行到doFilter时,会进行判断,如果有下一个Filter,就去执行下个Filter;没有的话,就直接执行资源文件,然后返回Filter执行doFilter后面的代码
- 所有的Filter和目标资源默认在同一个线程中;多个Filter执行的时候,他们使用同一个Request对象
Filter的拦截路径分类
精确匹配
- 只会拦截HTML下的a.html的请求
<url-pattern>/HTML/a.html</url-pattern>
目录匹配
- 只会拦截HTML下的所有请求
<url-pattern>/HTML/*</url-pattern>
后缀名匹配
- 只会拦截以.html结尾的请求
<url-pattern>*.html</url-pattern>
不经风雨,怎见彩虹?Filter过滤器只关心请求的地址是否匹配,不关心请求的资源是否存在
相关文章
- 暂无相关文章
用户点评