Web原生组件——Servlet,Filter和Listener
统一配置
需要再主配置类上添加注解**@ServletComponentScan(basePackages = “com.xxx.xxx”)**,默认是主配置类所在的包下都会扫描
初始化问题:
原生组件中,最先初始化的是Listener,之后是Filter,这两者是随着容器的创建而初始化的,最后是Servlet的初始化,但Servlet默认是在第一次访问时初始化
Servlet的配置
- 在主配置类添加@ServletComponentScan(basePackages = “com.xxx.xxx”)注解,确保自定义的Servlet会被扫描进来
- 自定义一个Servlet
- 定义一个类继承自HttpServlet
- 添加@WebServlet(urlPatterns = “/my”)注解,在其中添加访问路径
- 重写doGet或doPost方法
@ServletComponentScan//**默认扫描主配置类所在包
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("6666666");
}
}
特别注意:
因为Servlet的拼配匹配原则是精确匹配,因此当设置路径后(例如/my),一旦访问/my会优先精确匹配自定义的Servlet(精确优先原则),就不会被DispatchServlet捕获,而拦截器机制是在DispatchServlet内部实现的,因此自定义的Servlet拦截器不会生效
Filter的配置
-
在主配置类添加@ServletComponentScan(basePackages = “com.xxx.xxx”)注解,确保自定义的Filter会被扫描进来
-
自定义一个Filter
- 定义一个类实现Filter接口
- 添加@WebFilter(urlPatterns = “/my”)注解,在其中添加访问路径
- 重写init,doFilter, destroy方法
@Slf4j
@WebFilter(urlPatterns = {"/css/*","/images/*","/my"})
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("MyFilter初始化完成");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
Object user = httpServletRequest.getSession().getAttribute("user");
if (user == null) {
httpServletRequest.getRequestDispatcher("/pages/user/login.jsp").forward(servletRequest,servletResponse);
} else {
filterChain.doFilter(servletRequest,servletResponse);//要执行这行代码保证执行
}
@Override
public void destroy() {
log.info("MyFilter已被销毁");
}
}
Listener的配置
-
在主配置类添加@ServletComponentScan(basePackages = “com.xxx.xxx”)注解,确保自定义的Listener会被扫描进来
-
自定义一个Listener(Listener有很多种类,选一个实现)
- 定义一个类实现ServletContextListener接口
- 添加@WebListener
- 重写contextInitialized,contextDestroyed方法
@Slf4j
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
log.info("MyListener监听到项目初始化完成");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log.info("MyListener监听到项目销毁");
}
}
其他方式
除了使用注解外,还可以通过设置配置类的方式将三者进行注册,但也需要自定义原生组件
@Configuration
public class MyRegistConfig {
@Bean
public ServletRegistrationBean myServlet(){
MyServlet myServlet = new MyServlet();
return new ServletRegistrationBean(myServlet,"/my","/my01");
}
@Bean
public FilterRegistrationBean myFilter(){
MyFilter myFilter = new MyFilter();
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter;
filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
return filterRegistrationBean;
}
@Bean
public ServletListenerRegistrationBean myListener(){
MyListener myListener = new MyListener();
return new ServletListenerRegistrationBean(myListener);
}
}
2022-04-03 10:11:35 星期日