JavaWeb day06 过滤器监听器Web项目路径
Posted halulu.me
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb day06 过滤器监听器Web项目路径相关的知识,希望对你有一定的参考价值。
Java Web三大组件
过滤器
介绍
javaee体系提供一个Filter接口,实现这个接口后可以对所有资源进行拦截,拦截通过后才会达到目标资源执行
1、开发方式–手动配置xml文件
<filter>、 <filter-name>、<filter-class>、<url-pattern>
<?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">
<!--
web.xml配置过滤器要拦截的资源
1.定义过滤器类全名 <filter>
2.配置拦截的目标资源路径 <filter-mapping>
应用场景:以后配置别人开发的jar中过滤器类的时候使用
-->
<filter>
<filter-name>Demo1Filter</filter-name>
<filter-class>com.itheima._01filter开发方式1_手动XML.Demo1Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Demo1Filter</filter-name>
<url-pattern>/DemoServlet1</url-pattern>
</filter-mapping>
</web-app>
2、开发方式2–注解实现
跟@WebServlet(" ")一样
/**
* @WebFilter("/Demo2Servlet")
* 含义: 拦截/Demo2Servlet资源的过滤器注解配置
* 注解属性1: filterName, 功能与xml中<filter-name>标签功能一致,起别名,可有可无的属性
* 注解属性2: urlPatterns,这是默认注解值属性,配置拦截路径,支持如下格式:
* @WebFilter("/拦截路径")
* @WebFilter(urlPatterns={"/拦截路径1","/拦截路径2",...})
*/
@WebFilter("/Demo2Servlet")
public class Demo2Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//拦截请求与响应的方法
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
//1.拦截请求
System.out.println("==执行了Demo2Filter拦截请求的代码==");
//2.放行
filterChain.doFilter(request,response);
//3.拦截响应‘
System.out.println("==执行了Demo2Filter拦截响应的代码==");
}
@Override
public void destroy() {
}
}
注意:
没有 filterChain.doFilter(request,response) 默认拦截。
3、执行流程
4、过滤器生命周期
过滤器的3个方法:
1、初始化方法,init()
2、拦截请求和响应方法 ,doFilter()
3、销毁方法,destroy()
过滤器对象什么时候被创建?
服务器启动时创建,比servlet的创建早,servlet的创建在访问网站的时候创建的。
服务创建过滤器对象创建了几次?
由于init方法只调用1次,所以过滤器对象创建1次,全局唯一,节省内存
什么时候销毁过滤器?
服务器关闭之前
5、过滤器拦截路径的配置
拦截路径配置方式有2种(精确匹配和模糊匹配):
第一种:精确匹配,配置的路径与资源访问的路径要一模一样就可以拦截
urlPatterns = “/img/3.jpg”,
urlPatterns = “/index.jsp”
第二种:模糊匹配,只能使用一个“*”号通配符操作,代表0~多个字符
1.前缀匹配,匹配开头一致的
要求:以“/”开头,以"/*"结尾
例子:
/abc/*,拦截资源访问路径以/abc开头的所有资源
/*,拦截所有资源
2.后缀匹配,匹配结尾一致的
要求:以“*”开头,以“ . 扩展名”方式结尾
例子:
*. action,拦截资源访问路径
以 . action为结尾的所有资源
*. do,拦截资源访问路径
以 . do为结尾的所有资源
6、过滤器默认不拦截转发跳转
过滤器默认类型是REQUEST,默认不拦截转发跳转。
注解方式修改拦截方式的语法
@WebFilter(urlPatterns = "/Two2Servlet",
//配置拦截方式: 拦截浏览器直接访问和转发跳转的目标资源
dispatcherTypes ={DispatcherType.FORWARD,DispatcherType.REQUEST} )
public class Demo4Filter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//1.拦截请求
System.out.println("==执行了Demo4Filter的请求拦截代码==");
//2.放行:允许访问目标资源了
filterChain.doFilter(request,response);
//3.拦截响应
System.out.println("==执行了Demo4Filter的响应拦截代码==");
}
public void init(FilterConfig config) throws ServletException {
}
}
xml修改拦截方式
7、过滤器链
同一个资源同时被多个过滤器拦截形成过滤器链,一个过滤器一个过滤器进行串行拦截
过滤器链执行顺序
1、 使用web.xml的配置方式:哪个配置在前面就先执行哪个
2、使用注解的配置方式:按过滤器类名的字母顺序进行排序,哪个在前面就先执行。
<!--配置过滤器链:先执行Chain2Filter2, 再执行Chain1Filter2
注意:xml配置过滤器,执行顺序就是配置的顺序
-->
<filter>
<filter-name>Chain2Filter2</filter-name>
<filter-class>com.itheima._09过滤器链使用xml方式修改执行顺序.Chain2Filter2</filter-class>
</filter>
<filter-mapping>
<filter-name>Chain2Filter2</filter-name>
<url-pattern>/Demo4Servlet2</url-pattern>
</filter-mapping>
<filter>
<filter-name>Chain1Filter2</filter-name>
<filter-class>com.itheima._09过滤器链使用xml方式修改执行顺序.Chain1Filter2</filter-class>
</filter>
<filter-mapping>
<filter-name>Chain1Filter2</filter-name>
<url-pattern>/Demo4Servlet2</url-pattern>
</filter-mapping>
先执行Chain2Filter2,再执行Chain1Filter2
解决全站post提交中文乱码
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.获取请求数据的类型
//req.getMethod() ServletRequest接口中没有getMethod()方法,子接口HttpServletRequest才有
//将父接口转换为子接口
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
String method = request.getMethod(); //返回get或post
//2.如果类型为post处理乱码
if("post".equalsIgnoreCase(method)){
request.setCharacterEncoding("utf-8");
}
//3.放行
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
注意:
请求乱码过滤器解决,响应乱码JSP解决。
码表过滤器一定要放在最前面运行
推荐使用xml配置过滤器,因为注解的监听器会自动进行排序,浪费内存
监听器
web开发三大组件
servlet: 用于处理请求与响应, 响应资源给浏览器
filter: 用于拦截请求与响应, 重复操作代码抽取优化
listener: 监听器, 监听三大域的变化, 在变化的时候的时间点允许开发人员调用自己业务逻辑
监听器分类
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">
<listener>
<listener-class>com.halulu.listener.ListenerDemo1</listener-class>
</listener>
</web-app>
注解方式配置监听器
@WebListener
public class ListenerDemo1 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("监听器创建:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date()));
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("监听器销毁:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date()));
}
}
监听器应用场景
1.加载自定义配置文件数据,spring框架的配置文件就是使用这个监听器进行加载的
2.开启定时器任务运行
java定时器
@WebListener
public class MyServletContextListener2 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
/*
* 获取到servletContext创建的时间点有什么用?ServletContextListener的作用?
* 答:我们认为上下文域对象的创建是服务器启动时候最早的时间点,通常可以做如下2个操作:
* 1.加载自定义配置文件数据,spring框架的配置文件就是使用这个监听器进行加载的
* 2.开启定时器任务运行
* 定时器任务:按照指定的时间执行任务
* js的定时器语法:setInterval()或setTimeout(),这里我们要学习java的定时器
* */
/*
* java定时器类:Timer
* 创建语法:new Timer()
* 设置定时任务语法:
* 语法1:timer.schedule(TimerTask,long,long);
* 参数1:TimerTask接口,用于编写任务代码
* 参数2:long,毫秒数,设置距离第一次任务执行的毫秒数
* 参数3:long,毫秒数,间隔执行任务的毫秒数
* 语法2:timer.schedule(TimerTask,Date,long);
* 参数1:TimerTask接口,用于编写任务代码
* 参数2:Date,设置距离第一次任务执行的时间
* 参数3:long,毫秒数,间隔执行任务的毫秒数
* */
//1、创建定时器类
Timer timer = new Timer();
//2、设置定时器任务(每3秒输出一次hello world)
timer.schedule(new TimerTask() {
@Override
public void run() {
//任务代码
System.out.println("hello world");
}
},0,3000);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
ServletContextAttributeListener 介绍
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
//写入数据的监听
@Override
public void attributeAdded(ServletContextAttributeEvent sc) {
//新增属性名获取
String name = sc.getName();
//新增属性值获取
String value = (String) sc.getValue();
System.out.println("新增属性名:"+name+",属性值:"+value);
}
//修改数据的监听
@Override
public void attributeReplaced(ServletContextAttributeEvent sc) {
//修改属性名获取
String name = sc.getName();
//修改前属性值获取
String oldValue = (String) sc.getValue();
//修改后的属性值获取
String newValue = (String) sc.getServletContext().getAttribute(name);
System.out.println("修改属性名:"+name+",修改前属性值:"+oldValue+",修改后属性值:"+newValue);
}
//删除数据的监听
@Override
public void attributeRemoved(ServletContextAttributeEvent sc) {
//删除属性名获取
String name = sc.getName();
//删除前属性值获取
String oldValue = (String) sc.getValue();
System.out.println("删除属性名:"+name+",修改前属性值:"+oldValue);
}
}
Web项目路径
路径方式1:
相对路径,使用相对路径访问资源
比如请求转发跳转,由于转发跳转是在服务器内部进行的,所以使用相对路径。
相对路径不安全,除了请求转发跳转使用相对路径外,其余使用全路径
路径方式2:
全路径,使用完整资源路径访问资源
浏览器之间的跳转需要使用全路径,使用相对路径不安全
比较重定向跳转
response.sendRedirect(request.getContextPath()+"/DemoServlet");
jsp页面的跳转:
<a href="${pageContext.request.contextPath}/DemoServlet">demo</a>
以上是关于JavaWeb day06 过滤器监听器Web项目路径的主要内容,如果未能解决你的问题,请参考以下文章
java_day30_javaWeb三大组件之过滤器Filter