1.引入pom依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-json</artifactId>
<version>4.1.21</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
2.配置启动类
- @ServletComponentScan():
???????????????Servlet可以直接通过@WebServlet注解自动注册 ???????????????Filter可以直接通过@WebFilter注解自动注册 ???????????????Listener可以直接通过@WebListener 注解自动注册
import com.it.mhh.filter.MyFilter;
import com.it.mhh.listener.MyHttpSessionListener;
import com.it.mhh.listener.MyServletContextListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class FilterAndListenerApplication {
public static void main(String[] args) {
SpringApplication.run(FilterAndListenerApplication.class,args);
}
}
3.Filter 的使用
3.1过滤器创建
- @WebFilter():
????????????value[] 与urlPatterns[]属性一致: 表示过滤的路径 ??????????????? ??????? /* :表示过滤所有 ??????????????? ??????? *.html :表示只过滤html的文件 ??????????????? ??????? /app/* :表示过滤有app路径的所有文件 ??????????????? ??????? ... - dispatcherTypes[] : 资源被访问的方式(意思是什么时候过滤器奏效)
????????FORWARD : 转发访问资源(配置此方法 只有转发的资源才会被拦截) ????????INCLUDE : 包含访问资源截) ????????REQUEST : 默认值。浏览器直接请求资源截) ????????ASYNC : 异步访问资源 ????????ERROR : 错误跳转资源 - init方法:在服务器启动后,会创建Filter对象,然后调用init方法(只执行一次)
- doFilter方法:每一次请求被拦截资源时会执行
??????????????????????首先执行过滤器——>执行放行后的资源——>回来执行放行代码下的代码 ??????????????????????如果没有放行 就不再执行后面代码. - destroy方法: 在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法(只执行一次)
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.err.println(filterConfig.getFilterName());
System.err.println(filterConfig.getInitParameterNames());
System.err.println(filterConfig.getServletContext().getClassLoader());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
Map<String, String[]> parameterMap = request.getParameterMap();
System.err.println(parameterMap);
ServletRequest servletRequestPoxy = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(), servletRequest.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("getParameter" == method.getName().intern()) {
Object o = method.invoke(servletRequest, args);
if (o instanceof String) {
String invoke = (String) o;
if (invoke.intern() == "mhh") {
return "proxy_new_mhh";
}
}
}
return method.invoke(servletRequest, args);
}
});
System.err.println("请求资源执行前代码操作");
filterChain.doFilter(servletRequestPoxy, servletResponse);
System.err.println("请求资源执行完后代码操作");
}
@Override
public void destroy() {
System.err.println("过滤器销毁");
}
}
3.2Filter 过滤器测试
- 过滤器中doFilter方法中才是真正自己要做的操作
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("filter")
public class FilterController {
@RequestMapping("get")
public String get(HttpServletRequest httpServletRequest) {
System.err.println("进入->: " + httpServletRequest.getRequestURI());
return httpServletRequest.getParameter("name");
}
}
4.Listener 的使用
4.1.1 监听 ServletContext对象
- @WebListener : 启动监听(必须在启动类上加@ServletComponentScan)
- ServletContextListener : 接口用于监听 ServletContext 对象的创建和销毁事件。
- ServletContextAttributeListener : 接口用于监听ServletContext 新增 删除 替换属性
- contextInitialized方法 : 当 ServletContext 对象被创建时,调用接口中的方法:
- contextDestroyed方法 : 当 ServletContext 对象被销毁时,调用接口中的方法:
- attributeAdded方法 : 当新增被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
- attributeRemoved方法 : 当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
- attributeReplaced方法 : 当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@WebListener
public class MyServletContextListener implements ServletContextListener, ServletContextAttributeListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.err.println("监听ServletContext对象创建了...");
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("age",12);
final int[] i = {0};
TimerTask task = new TimerTask() {
@Override
public void run() {
System.err.println(i[0]++);
}
};
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(2,
new BasicThreadFactory.Builder().daemon(true).build());
executorService.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.shutdown();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.err.println("监听ServletContext对象销毁了...");
}
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.err.println("ServletContext新增属性--> "+scae.getName()+": "+scae.getValue());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.err.println("ServletContext删除属性--> "+scae.getName()+": "+scae.getValue());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.err.println("ServletContext替换属性--> "+scae.getName()+": "+scae.getValue());
}
}
4.1.2 监听 ServletContext对象测试
- ServletContext对象的生成和销毁 以及属性的变化 都会执行相应的方法
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("servletContext")
public class MyServletContextListenerController {
@RequestMapping("/get")
public String get(HttpServletRequest httpServletRequest) {
ServletContext servletContext = httpServletRequest.getServletContext();
System.err.println("获取在监听器初始化赋的value--> " + servletContext.getAttribute("age"));
servletContext.setAttribute("name", "mhh");
servletContext.setAttribute("name", "孟浩浩");
servletContext.removeAttribute("name");
return "ServletContext测试";
}
}
4.2.1 监听 HttpSession对象
- @WebListener : 启动监听(必须在启动类上加@ServletComponentScan)
- HttpSessionListener接口 : 用于监听HttpSession的创建和销毁
- HttpSessionAttributeListener接口 : 用于监听HttpSession 新增 删除 替换属性
- sessionCreated方法 : 创建一个Session时,接口中的该方法将会被调用
- sessionDestroyed方法 : 销毁一个Session时,接口中的该方法将会被调用
- attributeAdded方法 : 当Session中添加属性时 调用该方法
- attributeRemoved方法 : 当Session中删除属性时 调用该方法
- attributeReplaced方法 : 当Session中替换属性时 调用该方法
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
@WebListener
public class MyHttpSessionListener implements HttpSessionListener, HttpSessionAttributeListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session被创建了");
HttpSession session = se.getSession();
System.out.println("id:" + session.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session被销毁了");
HttpSession session = se.getSession();
System.out.println("id:" + session.getId());
}
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.err.println("Session是->:"+se.getSession()+" Session新增属性--> "+se.getName()+": "+se.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.err.println("Session是->:"+se.getSession()+" Session删除属性--> "+se.getName()+": "+se.getValue());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.err.println("Session是->:"+se.getSession()+" Session替换属性--> "+se.getName()+": "+se.getValue());
}
}
4.2.2 监听 HttpSession对象测试
- HttpSession对象的生成和销毁 以及属性的变化 都会执行相应的方法
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RestController
@RequestMapping("session")
public class MySessionListenerController {
@RequestMapping("/get")
public String get(HttpServletRequest httpServletRequest) {
HttpSession session = httpServletRequest.getSession();
session.setAttribute("name", "mhh");
session.setAttribute("name", "孟浩浩");
session.removeAttribute("name");
return "Session测试";
}
}
4.3.1 监听 ServletRequest对象
- @WebListener : 启动监听(必须在启动类上加@ServletComponentScan)
- ServletRequestListener : 接口用于监听ServletRequest 对象的创建和销毁
- ServletRequestAttributeListener : 接口用于监听ServletRequest 新增 删除 替换属性
- requestDestroyed方法 : ServletRequest对象被创建时,监听器的requestInitialized方法将会被调用。
- requestInitialized方法 : ServletRequest对象被销毁时,监听器的requestDestroyed方法将会被调用。
- attributeAdded方法 : 当新增被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
- attributeRemoved方法 : 当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
- attributeReplaced方法 : 当替换被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyServletRequestListener implements ServletRequestListener, ServletRequestAttributeListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("ServletRequest对象被创建");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("ServletRequest对象被销毁");
}
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.err.println("ServletRequest新增属性--> "+srae.getName()+": "+srae.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.err.println("ServletRequest删除属性--> "+srae.getName()+": "+srae.getValue());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.err.println("ServletRequest替换属性--> "+srae.getName()+": "+srae.getValue());
}
}
4.3.2 监听 ServletRequest对象测试
- servletRequest对象的生成和销毁 以及属性的变化 都会执行相应的方法
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("servletRequest")
public class MyServletRequestListenerController {
@RequestMapping("/get")
public String get(HttpServletRequest httpServletRequest) {
httpServletRequest.setAttribute("name", "mhh");
httpServletRequest.setAttribute("name","孟浩浩");
httpServletRequest.removeAttribute("name");
return "ServletRequest 测试";
}
}
|