在普通的java web项目中,Servlet、Filter、Listener都可以通过在 web.xml
文件中配置的方式添加,但是在springboot项目中,没有web.xml
文件,可以使用以下的方式添加:
添加servlet
- 继承父类
HttpServlet
,或者GenericServlet
; - 在实现的servlet类上使用
@WebServlet
注解; - 在配置类使用
@ServletComponentScan
注解扫描servlet组件即可。
package com.jvm123.servlet
import javax.servlet.AsyncContext
import javax.servlet.ServletException
import javax.servlet.annotation.WebServlet
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
/**
*
* @author yawn http://jvm123.com
* 2019/11/4 11:20
*/
@WebServlet(
name = "testServlet",
urlPatterns = "/servlet/test",
asyncSupported = true
)
class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext asyncContext = req.startAsync()
asyncContext.start(new Runnable() {
@Override
void run() {
doRequest(req, resp)
asyncContext.complete()
}
})
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doRequest(req, resp)
}
private void doRequest(HttpServletRequest req, HttpServletResponse resp) {
resp.getOutputStream().print("这是一个原生的 HttpServlet!")
}
}
如果使用异步servlet,需要加上asyncSupported = true
,再使用AsyncContext
来执行处理,执行完处理之后,要使用asyncContext.complete()
来完成异步处理,否则会一直等待,直至超时。
上面代码中的doGet方法使用了异步的处理,doPost方法使用了同步处理。
Servlet的实现继承关系
servlet的实现继承关系如下,实现时,可以继承 HttpServlet
,重写其中的 doXXX()
方法,或者继承GenericServlet
,实现其中的抽象方法service(ServletRequest req, ServletResponse res)
。

添加filter
添加filter过滤器时,可以经过以下几个步骤:
- 实现接口
javax.servlet.Filter
; - 在实现的servlet类上使用
@WebFilter
注解; - 在配置类使用
@ServletComponentScan
注解扫描组件。
package com.jvm123.servlet
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.servlet.Filter
import javax.servlet.FilterChain
import javax.servlet.FilterConfig
import javax.servlet.ServletException
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.annotation.WebFilter
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
/**
* @author yawn http://jvm123.com
* 2019/11/3 14:36
*/
@WebFilter(urlPatterns = "/*")
class AuditFilter implements Filter {
Logger logger = LoggerFactory.getLogger(AuditFilter.class)
@Override
void init(FilterConfig filterConfig) throws ServletException {
}
@Override
void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest
HttpServletResponse response = (HttpServletResponse) servletResponse
String uri = request.getRequestURI()
String referer = request.getHeader("Referer")
String host = request.getHeader("Host")
int statusCode = response.getStatus()
filterChain.doFilter(servletRequest, servletResponse)
logger.info("{} {}, host={}, referer={}", statusCode, uri, host, referer)
}
@Override
void destroy() {
}
}
添加listener
Listener的添加与上面类似,可以添加对不同servlet组件的监听,例如request、session、application,也可以监听其中属性的变化,分别实现不同的接口就可以实现这一目的。示例如下:
package com.jvm123.servlet
import javax.servlet.ServletRequestEvent
import javax.servlet.ServletRequestListener
import javax.servlet.annotation.WebListener
import javax.servlet.http.HttpServletRequest
/**
*
* @author yawn http://jvm123.com
* 2019/11/4 11:42
*/
@WebListener
class RequestListener implements ServletRequestListener {
@Override
void requestDestroyed(ServletRequestEvent event) {
HttpServletRequest request = (HttpServletRequest) event.getServletRequest()
println "request被销毁:" + request.getRequestURL()
}
@Override
void requestInitialized(ServletRequestEvent event) {
HttpServletRequest request = (HttpServletRequest) event.getServletRequest()
println "request初始化:" + request.getRequestURL()
}
}
spring boot 加载servlet组件验证
在添加了以上servlet组件之后,我们可以通过检查springboot启动时的日志进行验证,每个组件如果在启动时被加载,就会有如下的日志输出:
DEBUG [main] o.s.b.web.servlet.ServletContextInitializerBeans 128 : Added existing Servlet initializer bean 'dispatcherServletRegistration'; order=2147483647, resource=class path resource [org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration.class] DEBUG [main] o.s.b.web.servlet.ServletContextInitializerBeans 128 : Added existing Filter initializer bean 'com.jvm123.servlet.AuditFilter'; order=2147483647, resource=null DEBUG [main] o.s.b.web.servlet.ServletContextInitializerBeans 128 : Added existing EventListener initializer bean 'com.jvm123.servlet.RequestListener'; order=2147483647, resource=null DEBUG [main] o.s.b.web.servlet.ServletContextInitializerBeans 128 : Added existing EventListener initializer bean 'com.jvm123.servlet.SessionListener'; order=2147483647, resource=null DEBUG [main] o.s.b.web.servlet.ServletContextInitializerBeans 128 : Added existing Servlet initializer bean 'testServlet'; order=2147483647, resource=null DEBUG [main] o.s.b.web.servlet.ServletContextInitializerBeans 176 : Created Filter initializer for bean 'characterEncodingFilter'; order=-2147483648, resource=class path resource [org/springframework/boot/autoconfigure/web/HttpEncodingAutoConfiguration.class] INFO [main] o.s.boot.web.servlet.ServletRegistrationBean 190 : Mapping servlet: 'dispatcherServlet' to [/] INFO [main] o.s.boot.web.servlet.ServletRegistrationBean 190 : Mapping servlet: 'testServlet' to [/servlet/test] INFO [main] o.s.boot.web.servlet.FilterRegistrationBean 251 : Mapping filter: 'characterEncodingFilter' to: [/*] INFO [main] o.s.boot.web.servlet.FilterRegistrationBean 262 : Mapping filter: 'com.jvm123.servlet.AuditFilter' to urls: [/*]
由日志可以看出,除了dispatcherServlet和characterEncodingFilter之外,其他的servlet组件都是我们自定义的。