Spring Boot 自定义注册 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 方法执行后执行。
Spring Boot 自定义注册 Servlet、Filter、Listener的更多相关文章
- Spring boot中使用servlet filter
Spring boot中使用servlet filter liuyuhang原创,未经允许请勿转载! 在web项目中经常需要一些场景,如参数过滤防止sql注入,防止页面攻击,空参数矫正等, 也可以做成 ...
- Spring boot中注册Servlet
Spring boot中注册Servlet 如何在spring boot项目中注册Servlet呢? 如何在spring boot项目中注册Servlet呢? 由于没有web.xml,无法直接在xml ...
- 18. Spring Boot 、注册Servlet三大组件Servlet、Filter、Listener
由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件 public class MyServlet extends ...
- spring boot中使用servlet、listener和filter
spring boot中支持使用java Web三大组件(servlet.listener和filter),但是坑比较多,主要是spring boot内嵌tomcat和独立tomcat服务器有一些细节 ...
- Spring Boot 2 使用Servlet、Listener和Filter配置
开发环境:IntelliJ IDEA 2019.2.2Spring Boot版本:2.1.8 新建一个名称为demo的Spring Boot项目. 一.使用Servlet配置 1.修改启动类 Demo ...
- Spring Boot之注册servlet三大组件
由于Spring Boot默认是以jar包的形式启动嵌入式的Servlet容器来启动Spring Boot的web应用是,没有web.xml配置文件 注册三大组件用以下方式 ServletRegist ...
- SpringBoot注册Servlet/Filter/Listener
由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,那么没有web.xml文件,如何配置我们的三大Web基础组件呢? 通过使用XXXRe ...
- Spring boot 梳理 - Spring boot自动注册DispatcherServlet
spring boot提供的DispatcherServlet的name就是“dispatcherServlet”. 源码 public ServletRegistrationBean dispatc ...
- Spring Boot 2.X(十):自定义注册 Servlet、Filter、Listener
前言 在 Spring Boot 中已经移除了 web.xml 文件,如果需要注册添加 Servlet.Filter.Listener 为 Spring Bean,在 Spring Boot 中有两种 ...
随机推荐
- redis 和 memache 缓存的区别
总结一: 1.数据类型 Redis数据类型丰富,支持set list等类型 memcache支持简单数据类型,需要客户端自己处理复杂对象 2.持久性 redis支持数据落地持久化存储 memcache ...
- OCP协议_电信特殊协议
OCP(Online Charging Protocol)协议——在线计费协议(也称为AAA协议),是中国电信(文中以中国电信为主)充分研究国内外在线计费协议,基于中国电信自己在线计费的需求,参考3G ...
- java poi
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.a ...
- javaweb 一个坑—— writer必须放在response相关设置后面
https://blog.csdn.net/weixin_33962621/article/details/86454414
- webpack打包,同时将ES6转为ES5,初探
webpack打包,同时将ES6转为ES5,第一次尝试搞了一下午才弄好,所有的问题均来自ES6转es5上面,可能天分不够把,但愿各大浏览器快点支持ES6吧!忽略nodejs安装. 第一,新建一个项目文 ...
- 直通BAT必考题系列:JVM的4种垃圾回收算法、垃圾回收机制与总结
垃圾回收算法 1.标记清除 标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段. 在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象. ...
- javascript中的原型和原型链(一)
原型和原型链是 JS 中不可避免需要碰到的知识点,本文使用图片思维导图的形式缕一缕原型.原型链.实例.构造函数等等概念之间的关系. Constructor 构造函数 首先我们先写一个构造函数 Pers ...
- [VIJOS2055][SDOI2019]移动金币:DP+组合数学
分析 显然可以转化为阶梯nim. 于是问题转化为了对于所有\(i \in [0,n-m]\),求长度为\(\lfloor\frac{m+1}{2}\rfloor\),和为\(i\),异或和非\(0\) ...
- 原生Js_制作简易日历
javascript制作简易日历,月份信息已经放在一个数组中,在<script>...</script>中编写代码实现其功能 实现步骤 a) 获取需要操作的dom对象 b) 在 ...
- WebSocket 结合 Nginx 实现域名及 WSS 协议访问-Nginx配置
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...