-
- 四、Servlet3.0
- 1. 创建一个Servlet工程,勾选Web Application,取名servlet-annotation
- 2. 创建基于注解的Servlet,对于Servlet提供直接的注解支持WebServlet
- 3. 编写待注册的Servlet组件,不使用WebServlet注解
- 4. 编写Filter
- 5. 编写Listener
- 6. 编写注册三大组件的配置类,实现ServletContainerInitializer接口
- 7. 识别ServletContainerInitializer实现类
- 8. 启动容器,访问ip:port/servlet-annotation/custom,然后销毁容器,日志如下,正确识别
- 四、Servlet3.0
四、Servlet3.0
本章节不详细介绍相关servlet的只是,只大概讲解如果抛弃传统的web.xml
配置文件来注册servlet三大组件
Servlet3.0以后,引入一个接口,
javax.servlet.ServletContainerInitializer
,该接口的onStartup
方法可以在ServletContext
启动完成之前,创建组件,并且实现了该接口的类通过特定格式的配置,能够在Servlet容器启动的时候自动被识别到然后被加载,最终完成组件的创建工作,包含每一个jar包里的ServletContainerInitializer的实现。格式规则必须绑定在classpath下,META-INF/services/javax.servlet.ServletContainerInitializer
文件下META-INF/services/这一块为文件路径,javax.servlet.ServletContainerInitializer
这个是文件的名称,而不是类名,然后将实现了ServletContainerInitializer
接口的全类名粘贴到这个文件内容里即可。使用IDEA
直接新建package
META-INF会不能直接创建,但是可以直接创建META-INF/services
,然后再在这个路径下新建文件即可
1. 创建一个Servlet
工程,勾选Web Application
,取名servlet-annotation
2. 创建基于注解的Servlet
,对于Servlet
提供直接的注解支持WebServlet
package com.ddf.annotation.servlet;
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 java.io.IOException;
/**
* @author DDf on 2018/8/14
* 使用注解代替web.xml配置文件来识别Servlet
*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello!");
}
}
3. 编写待注册的Servlet
组件,不使用WebServlet
注解
package com.ddf.annotation.servlet;
import com.ddf.annotation.servlet.configuration.CustomsContainerInit;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author DDf on 2018/8/14
* 使用编码方式映射servlet {@link CustomsContainerInit}
*/
public class CustomServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("使用编码方式映射Servlet..........");
}
}
4. 编写Filter
package com.ddf.annotation.servlet.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* @author DDf on 2018/8/14
*/
public class CustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器初始化。。。。。。。。");
System.out.println("servlet容器: " + filterConfig.getServletContext());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("目标方法被拦截.............");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("销毁方法。。。。。。。。。。。");
}
}
5. 编写Listener
package com.ddf.annotation.servlet.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @author DDf on 2018/8/14
* 监听servlet容器的创建和销毁
*/
public class CustomListeners implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("监听容器初始化。。。。。。。。。");
System.out.println(servletContextEvent);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("监听容器销毁..........");
System.out.println(servletContextEvent);
}
}
6. 编写注册三大组件的配置类,实现ServletContainerInitializer
接口
package com.ddf.annotation.servlet.configuration;
import com.ddf.annotation.servlet.CustomServlet;
import com.ddf.annotation.servlet.filter.CustomFilter;
import com.ddf.annotation.servlet.listener.CustomListeners;
import javax.servlet.*;
import javax.servlet.annotation.HandlesTypes;
import java.util.EnumSet;
import java.util.Set;
/**
* @author DDf on 2018/8/14
* @HandlesTypes 容器启动的时候会将@HandlesTypes指定的这个类型下面的子类(实现类,子接口等)传递过来作为onStartup的第一个参数
*
* 1、Servlet容器启动会扫描,当前应用里面每一个jar包的
* ServletContainerInitializer的实现
* 2、提供ServletContainerInitializer的实现类;
* 必须绑定在classpath下,META-INF/services/javax.servlet.ServletContainerInitializer
* 文件的内容就是ServletContainerInitializer实现类的全类名;
*/
@HandlesTypes(value={Filter.class})
public class CustomsContainerInit implements ServletContainerInitializer {
/**
* 在容器启动的时候创建servlet组件,不需要使用配置文件
* @param set
* @param servletContext
* @throws ServletException
*/
@Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
System.out.println("@HandlesTypes传入的类型有: ");
for (Class clazz : set) {
System.out.println(clazz);
}
// 注册Servlet
ServletRegistration.Dynamic customServlet = servletContext.addServlet("customServlet", new CustomServlet());
customServlet.addMapping("/custom");
// 注册Listener
servletContext.addListener(CustomListeners.class);
// 注册Filter
FilterRegistration.Dynamic customFilter = servletContext.addFilter("customFilter", new CustomFilter());
customFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
}
}
7. 识别ServletContainerInitializer
实现类
在src
下新建META-INF\services\javax.servlet.ServletContainerInitializer
文件,粘贴自定义实现类的全类名
com.ddf.annotation.servlet.configuration.CustomsContainerInit
8. 启动容器,访问ip:port/servlet-annotation/custom
,然后销毁容器,日志如下,正确识别
@HandlesTypes传入的类型有:
class com.ddf.annotation.servlet.filter.CustomFilter
监听容器初始化。。。。。。。。。
javax.servlet.ServletContextEvent[source=org.apache.catalina.core.StandardContext$NoPluggabilityServletContext@1e99db28]
过滤器初始化。。。。。。。。
servlet容器: org.apache.catalina.core.ApplicationContextFacade@1af646c8
目标方法被拦截.............
目标方法被拦截.............
14-Aug-2018 16:29:26.003 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory D:\tomcat8\webapps\manager
14-Aug-2018 16:29:26.039 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory D:\tomcat8\webapps\manager has finished in 36 ms
目标方法被拦截.............
销毁方法。。。。。。。。。。。
监听容器销毁..........
javax.servlet.ServletContextEvent[source=org.apache.catalina.core.StandardContext$NoPluggabilityServletContext@1e99db28]