Servlet3.0——注册web组件

一、Servlet容器启动时会扫描当前应用中每一个jar包中的在META-INF/services/javax.servlet.ServletContainerInitializer文件(该文件没有后缀名)中配置的ServletContainerInitializer的实现类,javax.servlet.ServletContainerInitializer文件的内容就是ServletContainerInitializer实现类的全类名,启动时会运行这些实现类的onStartUp方法,可以通过@HandlesTypes传入一些感兴趣的类型,在onStartUp方法中做一些操作。一个jar包中只能有一个javax.servlet.ServletContainerInitializer配置文件,一个javax.servlet.ServletContainerInitializer配置文件中只能配置一个ServletContainerInitializer实现类。

ServletContainerInitializer实现类:

@HandlesTypes({HelloServiceInterface.class})
public class MyServletContainerInitializer implements ServletContainerInitializer{

	@Override
	public void onStartup(Set> set, ServletContext context) throws ServletException {
		System.out.println("感兴趣的类:");
		for (Class clazz : set) {
			System.out.println(">>>>>>" + clazz);
		}
	}

}

onStartUp方法的入参:

    set是@HandlesTypes中传入的接口或者类的所有子接口或者子类(不包含该接口或该类本身);context是web项目的servlet上下文,一个web项目对应一个ServletContext,通过ServletContext可以来注册web组件,比如第三方的filter组件(由于第三方的组件并不是我们写的,我们无法通过@WebServlet、@WebFilter、@WebListener来标注使其拦截相应的请求,这个时候就需要在ServletContainerInitializer中通过ServletContext来注册了)

javax.servlet.ServletContainerInitializer配置文件内容:

com.bdm.servlet.MyServletContainerInitializer

javax.servlet.ServletContainerInitializer配置文件的目录:

Servlet3.0——注册web组件_第1张图片

此时在项目启动时可以看到后台日志中打印出:

二、使用ServletContext注册web组件

UserServlet.java:

public class UserServlet extends HttpServlet{

	private static final long serialVersionUID = -5343785314009218808L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().write("tomcat...");
	}
}

UserFilter.java:

public class UserFilter implements Filter{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("UserFilter...doFilter...");
		chain.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}

}

UserListener.java:只要实现了ServletContextListener接口就可以监听到ServletContext(Servlet容器)的创建和销毁

public class UserListener implements ServletContextListener {

	@Override
	public void contextDestroyed(ServletContextEvent event) {
		System.out.println("UserListener...contextDestroyed...");
	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		System.out.println("UserListener...contextInitialized...");
	}

}

注册web组件:

@HandlesTypes({HelloServiceInterface.class})
public class MyServletContainerInitializer implements ServletContainerInitializer{

	@Override
	public void onStartup(Set> set, ServletContext context) throws ServletException {
		
		ServletRegistration.Dynamic userServlet = context.addServlet("userServlet", new UserServlet());
		userServlet.addMapping("/user");
		
		FilterRegistration.Dynamic filter = context.addFilter("userFilter", UserFilter.class);
		filter.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true, "userServlet");
		filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
		
		context.addListener(UserListener.class);
	}

}

context.addServlet()注册servlet组件,context.addFilter()注册filter组件,这两个组件都需要配置映射路径,其中filter还可以配置拦截哪些servlet;context.addListener()注册listener,listener在tomcat启动时就会调用其中的逻辑;

servlet、filter、listener这些组件的注册必须在tomcat容器启动的时候,有两处可以进行这些组件的注册,一个就是上面的例子(通过ServletContainerInitializer中的ServletContext来注册),还有一个地方可以注册,就是在ServletContextListener的实现类中获取到ServletContext,然后通过ServletContext注册其他的listener、filter、servlet:

@WebListener
public class UserListener implements ServletContextListener {

	@Override
	public void contextDestroyed(ServletContextEvent event) {
		System.out.println("UserListener...contextDestroyed...");
	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		ServletContext servletContext = event.getServletContext();
		Dynamic addServlet = servletContext.addServlet("userServlet", UserServlet.class);
		addServlet.addMapping("/user");
		javax.servlet.FilterRegistration.Dynamic addFilter = servletContext.addFilter("userFilter", UserFilter.class);
		addFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
	}

}

此处的UserLisener需要使用@WebListener注解的方式注册,而不可以在ServletContainerInitializer中注册,不知道什么原因?

你可能感兴趣的:(Servlet3.0)