前言
在 Spring Boot 中已经移除了 web.xml 文件, 如果需要注册添加 Servlet,Filter,Listener 为 Spring Bean, 在 Spring Boot 中有两种方式:
使用 Servlet 3.0 API 的注解 @WebServlet,@WebFilter,@Listener 用来配置.
Spring Boot JavaConfig 注解配置 Bean 的方式来进行配置.
注册之前
在使用 Servlet 时, 需要在 Spring Boot 入口类添加 @ServletComponentScan 注解, 告诉 Spring Boot 去扫描使用下面注册的 Servlet,Filter,Listener.
- @SpringBootApplication
- @ServletComponentScan
- public class SpringBootServletApplication {
- public static void main(String[] args) {
- SpringApplication.run(SpringBootServletApplication.class, args);
- }
- }
注册 Servlet
1.@WebServlet 属性
属性 | 类型 | 描述 |
---|---|---|
name | String | 指定 Servlet 名称,等价于 |
value | String[] | 等同于 urlPatterns 属性,两者不应该同时使用 |
urlPatterns | String[] | 指定一组 Servlet 的 URL 匹配模式。等价于 < url-pattern ztid="68" ow="28" oh="17"> 标签 |
loadOnStartup | int | 指定 Servlet 的加载顺序,等价于 |
initParams | WebInitParam[] | 指定一组 Servlet 初始化参数,等价于 < init-param ztid="78" ow="28" oh="17"> 标签 |
asyncSupported | boolean | 声明 Servlet 是否支持异步操作模式,等价于 < async-supported ztid="83" ow="32" oh="17"> 标签 |
smallIcon | String | 此 Servlet 的小图标 |
largeIcon | String | 此 Servlet 的大图标 |
description | String | 该 Servlet 的描述信息,等价于 |
displayName | String | 该 Servlet 的显示名,通常配合工具使用,等价于 |
2. 示例
- @WebServlet(urlPatterns = "/TestServlet")
- public class TestServlet extends HttpServlet {
- /**
- *
- */
- private static final long serialVersionUID = -3325041776508043481L;
- @Override
- public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- doPost(req, resp);
- }
- /*
- * 实现请求 uri 和 header 打印, 另外返回一个 JSON
- */
- @Override
- public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- System.out.println("RequestURI:" + req.getRequestURI());
- System.out.println("Request Headers:");
- StringBuilder sb = new StringBuilder();
- Enumeration<?> names = req.getHeaderNames();
- while (names.hasMoreElements()) {
- String name = names.nextElement().toString();
- Enumeration<?> hs = req.getHeaders(name);
- sb.append(name).append(":");
- while (hs.hasMoreElements()) {
- sb.append(hs.nextElement()).append(";");
- }
- }
- System.out.println(sb);
- ObjectMapper om=new ObjectMapper();
- UserEntity user=new UserEntity();
- user.setId(1L);
- user.setUserName("zwqh");
- user.setUserSex("男");
- user.setHeaders(sb.toString());
- String resultJson=om.writeValueAsString(user);
- resp.setContentType("application/json;charset=UTF-8");
- resp.getWriter().print(resultJson);
- }
- }
其中 @WebServlet(urlPatterns = "/TestServlet") 等价于以下代码:
- <servlet>
- <!-- 类名 -->
- <servlet-name> TestServlet </servlet-name>
- <!-- 所在的包 -->
- <servlet-class> cn.zwqh.springbboot.servlet.TestServlet </servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name> TestServlet </servlet-name>
- <!-- 访问的 url 路径地址 -->
- <url-pattern> /TestServlet </url-pattern>
- </servlet-mapping>
3. 测试
浏览器访问 http://127.0.0.1:8080/TestServlet
日志输出:
注册 Filter
1.@WebFilter 属性
属性 | 类型 | 描述 |
---|---|---|
filterName | String | 指定 Filter 名称,等价于 |
value | String[] | 等同于 urlPatterns 属性,两者不应该同时使用 |
urlPatterns | String[] | 指定一组 Filter 的 URL 匹配模式。等价于 < url-pattern ztid="135" ow="28" oh="17"> 标签 |
servletNames | String[] | 指定过滤器将应用于哪些 Servlet。取值于 @WebServlet 中的 name 属性,或者是 web.xml 中 |
initParams | WebInitParam[] | 指定一组 Filter 初始化参数,等价于 < init-param ztid="145" ow="28" oh="17"> 标签 |
dispatcherTypes | DispatcherType[] | 指定 Filter 的转发模式,包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST |
asyncSupported | boolean | 声明 Filter 是否支持异步操作模式,等价于 < async-supported ztid="154" ow="32" oh="17"> 标签 |
smallIcon | String | 此 Filter 的小图标 |
largeIcon | String | 此 Filter 的大图标 |
description | String | 该 Filter 的描述信息,等价于 |
displayName | String | 该 Filter 的显示名,通常配合工具使用,等价于 |
2. 示例
- @WebFilter(urlPatterns = { "/TestServlet" }) // 注册拦截器, 并添加拦截路径'/TestServlet'
- public class TestFilter implements Filter {
- /**
- * 初始化, 只在项目启动的时候执行一次
- */
- @Override
- public void init(FilterConfig filterConfig) {
- System.out.println("===> TestFilter init");
- }
- /**
- * 用于存放过滤器的业务逻辑实现代码
- */
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- chain.doFilter(request, response);// 处理请求和响应的分界线
- System.out.println("===> chain.doFilter 后执行处理 response 的相关方法");
- // 在 response header 里设置一个 token
- setToken(response);
- }
- private void setToken(ServletResponse response) {
- HttpServletResponse res = (HttpServletResponse) response;
- String token = UUID.randomUUID().toString();
- res.setHeader("Token", token);
- System.out.println("===> 设置了 token:" + token);
- }
- /**
- * 销毁, 在项目关闭, Servlet 容器销毁前调用
- */
- @Override
- public void destroy() {
- System.out.println("===> TestFilter destroy");
- }
- }
3. 测试
浏览器访问 http://127.0.0.1:8080/TestServlet :
日志打印:
4.Filter 主要使用场景
禁用浏览器的缓存 (缓存的处理)
解决中文乱码问题
登录鉴权及权限管理
用户授权, 负责检查用户的请求, 根据请求过滤用户非法请求
日志记录, 详细记录某些特殊的用户请求
其他场景
注册 Listener
1.@Listener 属性
属性 | 类型 | 描述 |
---|---|---|
value | String | 侦听器 Listener 的描述 |
2. 示例
与 ServletContext 相关的监听
Servlet 的监听器 Listener 是实现了 javax.servlet.ServletContextListener 接口的服务器端程序, 随着 Web 应用启动而启动, 只初始化一次, 也随着 Web 应用停止而销毁. 其主要作用是做一些初始化的内容添加工作, 如参数和对象等.
- @WebListener
- public class ContextListener implements ServletContextListener, ServletContextAttributeListener{
- public static final String INITIAL_CONTENT = "Content created in servlet Context";
- /**
- * ServletContext 创建
- */
- @Override
- public void contextInitialized(ServletContextEvent sce) {
- System.out.println("===> context initialized");
- ServletContext servletContext = sce.getServletContext();
- servletContext.setAttribute("content", INITIAL_CONTENT);
- }
- /**
- * ServletContext 销毁
- */
- @Override
- public void contextDestroyed(ServletContextEvent sce) {
- System.out.println("===> context destroyed");
- }
- /**
- * context 属性新增
- */
- @Override
- public void attributeAdded(ServletContextAttributeEvent scae) {
- System.out.println("===> context attribute added");
- }
- /**
- * context 属性移除
- */
- @Override
- public void attributeRemoved(ServletContextAttributeEvent scae) {
- System.out.println("===> context attribute removed");
- }
- /**
- * context 属性替换
- */
- @Override
- public void attributeReplaced(ServletContextAttributeEvent scae) {
- System.out.println("===> context attribute replaced");
- }
- }
与 HttpSession 相关的监听
- @WebListener
- public class SessionListener implements HttpSessionListener, HttpSessionIdListener, HttpSessionAttributeListener,
- HttpSessionActivationListener {
- /**
- * session 被创建时
- */
- @Override
- public void sessionCreated(HttpSessionEvent se) {
- System.out.println("===> session created");
- }
- /**
- * session 被销毁时
- */
- @Override
- public void sessionDestroyed(HttpSessionEvent se) {
- System.out.println("===> session destroyed");
- }
- /**
- * sessionId 改变
- */
- @Override
- public void sessionIdChanged(HttpSessionEvent se, String oldSessionId) {
- System.out.println("===> session id changed");
- }
- /**
- * session 属性新增
- */
- @Override
- public void attributeAdded(HttpSessionBindingEvent se) {
- System.out.println("===> session attribute added");
- }
- /**
- * session 属性移除
- */
- @Override
- public void attributeRemoved(HttpSessionBindingEvent se) {
- System.out.println("===> session attribute removed");
- }
- /**
- * session 属性替换
- */
- @Override
- public void attributeReplaced(HttpSessionBindingEvent se) {
- System.out.println("===> session attribute replaced");
- }
- /**
- * session 的钝化, 内存的数据写入到硬盘上的过程.
- */
- @Override
- public void sessionWillPassivate(HttpSessionEvent se) {
- System.out.println("===> session will passivate");
- }
- /**
- * session 的活化, 将硬盘的数据恢复到内存中.
- */
- @Override
- public void sessionDidActivate(HttpSessionEvent se) {
- System.out.println("===> session did activate");
- }
- }
与 ServletRequest 相关的监听
- @WebListener
- public class RequestListener implements ServletRequestListener,ServletRequestAttributeListener {
- /**
- * 请求即将进入 Web 应用程序的范围 / 请求初始化时
- */
- @Override
- public void requestInitialized(ServletRequestEvent sre) {
- System.out.println("===> request initialized");
- }
- /**
- * 请求即将进入 Web 应用程序的范围 / 请求销毁时
- */
- @Override
- public void requestDestroyed(ServletRequestEvent sre) {
- System.out.println("===> request destroyed");
- }
- /**
- * request 属性新增
- */
- @Override
- public void attributeAdded(ServletRequestAttributeEvent srae) {
- System.out.println("===> request attribute added");
- }
- /**
- * request 属性移除
- */
- @Override
- public void attributeRemoved(ServletRequestAttributeEvent srae) {
- System.out.println("===> request attribute removed");
- }
- /**
- * request 属性替换
- */
- @Override
- public void attributeReplaced(ServletRequestAttributeEvent srae) {
- System.out.println("===> request attribute replaced");
- }
- }
3. 项目相关日志输入 (启动和停止)
先执行 contextInitialzed 方法在执行 TestFilter 类的 init 方法,
contextDestroyed 方法在 TestFilter 类 destroy 方法执行后执行.
示例代码
码云
来源: https://www.cnblogs.com/zwqh/p/11735755.html