zoukankan      html  css  js  c++  java
  • Spring Boot 2.X(十):自定义注册 Servlet、Filter、Listener

    前言

    在 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 匹配模式。等价于标签
    loadOnStartup int 指定 Servlet 的加载顺序,等价于 标签
    initParams WebInitParam[] 指定一组 Servlet 初始化参数,等价于标签
    asyncSupported boolean 声明 Servlet 是否支持异步操作模式,等价于 标签
    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 匹配模式。等价于标签
    servletNames String[] 指定过滤器将应用于哪些 Servlet。取值于 @WebServlet 中的 name 属性,或者是 web.xml 中 的值
    initParams WebInitParam[] 指定一组 Filter 初始化参数,等价于标签
    dispatcherTypes DispatcherType[] 指定 Filter 的转发模式,包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST
    asyncSupported boolean 声明 Filter 是否支持异步操作模式,等价于 标签
    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 方法执行后执行。

    示例代码

    github

    码云

    非特殊说明,本文版权归 朝雾轻寒 所有,转载请注明出处.

    原文标题:Spring Boot 2.X(十):自定义注册 Servlet、Filter、Listener

    原文地址: https://www.zwqh.top/article/info/17

    如果文章对您有帮助,请扫码关注下我的公众号,文章持续更新中...

  • 相关阅读:
    锁表
    vs2010宏的应用
    Oracle:sqlplus查询出的中文是乱码问题的解决(转)
    linux下查看端口和服务的一些命令
    netsh
    xpshutdown关机命令详解
    linux系统如何察看、修改系统时间
    delphi编程中调用其他执行程序?(转)
    如何修改Oracle用户密码的诀窍(转)
    转:用Delphi实现从Excel数据Update(Insert类似)到Oracle数据库表中
  • 原文地址:https://www.cnblogs.com/zwqh/p/11735755.html
Copyright © 2011-2022 走看看