SpringBoot中Servlet&Listener&Filter的应用
2017-01-06 13:28
671 查看
在spring boot中添加自己的Servlet有两种方法,代码注册Servlet和注解自动注册:
一、代码注册通过ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制。
二、在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
下面首先通过第一种方式验证:
1、添加一个servlet类:
package com.shf.springboot.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet1 extends HttpServlet {
private static final long serialVersionUID = -4186518845701003231L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet1");
resp.setContentType("text/html");
resp.getWriter().write("Servlet1");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet1 loadOnStart");
}
}
2、添加一个Java配置类,主要进行servlet配置:
package com.shf.springboot.config;
import javax.servlet.Servlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.shf.springboot.servlet.Servlet1;
import com.shf.springboot.servlet.Servlet3;
@Configuration
public class ServletConfigure {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean
servletRegistrationBean=new ServletRegistrationBean(new Servlet1(), "/servlet1");
return servletRegistrationBean;
}
}
3、启动服务验证,发出请求:
同时控制台
4、如果需要此servlet能够在启动应用时直接加载启动,则修改如下:
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new Servlet1(), "/servlet1");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
5、启动服务查看控制台:
再次请求仅打印servlet1
第一种方式配置直接通过ServletRegistrationBean的方式注册bean对象完成注册,springboot中ServletRegistrationBean提供相对比较灵活的配置,不仅仅是loadOnStartup的设置。那么第二种方式是否更加习惯呢,在之前的springmvc中正式通过注解配置,这也是servlet3版本以后的特性。下面就开始验证:
1、首先再次添加2个servlet:
package com.shf.springboot.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns="/servlet2",loadOnStartup=1)
public class Servlet2 extends HttpServlet {
private static final long serialVersionUID = -4186518845701003231L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet2");
resp.setContentType("text/html");
resp.getWriter().write("Servlet2");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet2 loadOnStart");
}
}
package com.shf.springboot.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
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 org.springframework.boot.web.servlet.ServletContextInitializer;
@WebServlet(urlPatterns="/servlet3")
public class Servlet3 extends HttpServlet {//implements ServletContextInitializer
private static final long serialVersionUID = -4186518845701003231L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet3");
resp.setContentType("text/html");
resp.getWriter().write("Servlet3");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet3 loadOnStart");
}
}
两个servlet仅servlet2启动加载,另一个非启动加载。
2、此时还需要在启动类添加servlet扫描注解@ServletComponentScan:
package com.shf.SpringBoot1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.shf.springboot.controller.ServerConfig2;
@SpringBootApplication
@EnableConfigurationProperties({ServerConfig.class,ServerConfig2.class})
@ComponentScan(basePackages={"com.shf.SpringBoot1","com.shf.springboot.*"})
@ServletComponentScan(basePackages={"com.shf.springboot.*"})
public class App
extends SpringBootServletInitializer //这个类的作用与在web.xml中配置负责初始化Spring应用上下文的监听器作用类似,如果需要打成war部署在tomcat下则需要
{
@Autowired
ServerConfig serverConfig;
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(App.class);
}
}
3、此时即可启动服务,先查看控制台:
说明两种方式不同的配置模式,同样的效果,下面对3个servlet分别请求,观察控制台:
4、以上能够看出servlet的配置已经如期望生效,那么对应的filter以及listener呢,下面添加一个listener统计每个请求的请求时长、一个过滤器过滤所有的请求地址:
监听:
package com.shf.springboot.servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
/**
* 监听每个请求的运行时长
* @description TODO
* @author song
*/
@WebListener
public class PerforationStatListener implements ServletRequestListener {
private static final String START = "Start";
/**
* 请求建立
*/
@Override
public void requestInitialized(ServletRequestEvent servletrequestevent) {
HttpServletRequest request = (HttpServletRequest) servletrequestevent.getServletRequest();
request.setAttribute(START, System.nanoTime());
System.out.println(request.getRequestURI()+"进入监听");
}
/**
* 请求销毁
*/
@Override
public void requestDestroyed(ServletRequestEvent servletrequestevent) {
HttpServletRequest request = (HttpServletRequest) servletrequestevent.getServletRequest();
long start = (Long)request.getAttribute(START);
long ms = (System.nanoTime() - start)/1000;
String uri = request.getRequestURI();
//1秒=1000豪秒 、1毫秒=1000微秒、 1微秒=1000毫微秒
System.out.println("请求"+uri+"耗时:"+ms+"微秒");
}
}
过滤器:
package com.shf.springboot.servlet;
import java.io.IOException;
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;
@WebFilter(filterName="myFilter",urlPatterns="/*")
public class MyFilter implements Filter {
@Override
public void destroy() {
System.out.println("过滤器销毁");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("执行过滤操作");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("过滤器初始化");
}
}
5、启动服务验证:
此时请求servlet3
通过此图也不难发现servlet、filter、listener的执行顺序:
listener的requestInitialized()-->servlet的init()-->filter的doFilter()-->servlet的doGet()-->listener的requestDestroyed()
注:以上不仅在开发环境下通过main函数启动服务验证通过,同时通过jar方式采用内置tomcat、以及自定义tomcat容器下war包部署均正常访问、过滤、监听。
一、代码注册通过ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制。
二、在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
下面首先通过第一种方式验证:
1、添加一个servlet类:
package com.shf.springboot.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet1 extends HttpServlet {
private static final long serialVersionUID = -4186518845701003231L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet1");
resp.setContentType("text/html");
resp.getWriter().write("Servlet1");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet1 loadOnStart");
}
}
2、添加一个Java配置类,主要进行servlet配置:
package com.shf.springboot.config;
import javax.servlet.Servlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.shf.springboot.servlet.Servlet1;
import com.shf.springboot.servlet.Servlet3;
@Configuration
public class ServletConfigure {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean
servletRegistrationBean=new ServletRegistrationBean(new Servlet1(), "/servlet1");
return servletRegistrationBean;
}
}
3、启动服务验证,发出请求:
同时控制台
4、如果需要此servlet能够在启动应用时直接加载启动,则修改如下:
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean servletRegistrationBean=new ServletRegistrationBean(new Servlet1(), "/servlet1");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
5、启动服务查看控制台:
再次请求仅打印servlet1
第一种方式配置直接通过ServletRegistrationBean的方式注册bean对象完成注册,springboot中ServletRegistrationBean提供相对比较灵活的配置,不仅仅是loadOnStartup的设置。那么第二种方式是否更加习惯呢,在之前的springmvc中正式通过注解配置,这也是servlet3版本以后的特性。下面就开始验证:
1、首先再次添加2个servlet:
package com.shf.springboot.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns="/servlet2",loadOnStartup=1)
public class Servlet2 extends HttpServlet {
private static final long serialVersionUID = -4186518845701003231L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet2");
resp.setContentType("text/html");
resp.getWriter().write("Servlet2");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet2 loadOnStart");
}
}
package com.shf.springboot.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
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 org.springframework.boot.web.servlet.ServletContextInitializer;
@WebServlet(urlPatterns="/servlet3")
public class Servlet3 extends HttpServlet {//implements ServletContextInitializer
private static final long serialVersionUID = -4186518845701003231L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet3");
resp.setContentType("text/html");
resp.getWriter().write("Servlet3");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet3 loadOnStart");
}
}
两个servlet仅servlet2启动加载,另一个非启动加载。
2、此时还需要在启动类添加servlet扫描注解@ServletComponentScan:
package com.shf.SpringBoot1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.shf.springboot.controller.ServerConfig2;
@SpringBootApplication
@EnableConfigurationProperties({ServerConfig.class,ServerConfig2.class})
@ComponentScan(basePackages={"com.shf.SpringBoot1","com.shf.springboot.*"})
@ServletComponentScan(basePackages={"com.shf.springboot.*"})
public class App
extends SpringBootServletInitializer //这个类的作用与在web.xml中配置负责初始化Spring应用上下文的监听器作用类似,如果需要打成war部署在tomcat下则需要
{
@Autowired
ServerConfig serverConfig;
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(App.class);
}
}
3、此时即可启动服务,先查看控制台:
说明两种方式不同的配置模式,同样的效果,下面对3个servlet分别请求,观察控制台:
4、以上能够看出servlet的配置已经如期望生效,那么对应的filter以及listener呢,下面添加一个listener统计每个请求的请求时长、一个过滤器过滤所有的请求地址:
监听:
package com.shf.springboot.servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
/**
* 监听每个请求的运行时长
* @description TODO
* @author song
*/
@WebListener
public class PerforationStatListener implements ServletRequestListener {
private static final String START = "Start";
/**
* 请求建立
*/
@Override
public void requestInitialized(ServletRequestEvent servletrequestevent) {
HttpServletRequest request = (HttpServletRequest) servletrequestevent.getServletRequest();
request.setAttribute(START, System.nanoTime());
System.out.println(request.getRequestURI()+"进入监听");
}
/**
* 请求销毁
*/
@Override
public void requestDestroyed(ServletRequestEvent servletrequestevent) {
HttpServletRequest request = (HttpServletRequest) servletrequestevent.getServletRequest();
long start = (Long)request.getAttribute(START);
long ms = (System.nanoTime() - start)/1000;
String uri = request.getRequestURI();
//1秒=1000豪秒 、1毫秒=1000微秒、 1微秒=1000毫微秒
System.out.println("请求"+uri+"耗时:"+ms+"微秒");
}
}
过滤器:
package com.shf.springboot.servlet;
import java.io.IOException;
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;
@WebFilter(filterName="myFilter",urlPatterns="/*")
public class MyFilter implements Filter {
@Override
public void destroy() {
System.out.println("过滤器销毁");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("执行过滤操作");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("过滤器初始化");
}
}
5、启动服务验证:
此时请求servlet3
通过此图也不难发现servlet、filter、listener的执行顺序:
listener的requestInitialized()-->servlet的init()-->filter的doFilter()-->servlet的doGet()-->listener的requestDestroyed()
注:以上不仅在开发环境下通过main函数启动服务验证通过,同时通过jar方式采用内置tomcat、以及自定义tomcat容器下war包部署均正常访问、过滤、监听。
相关文章推荐
- Spring Boot - Web 应用开发 - Servlet, Filter, Listener
- Spring Boot中Servlet&Filter&Listener&Interceptor的使用
- spring boot(18)-servlet、filter、listener
- SpringBoot初始教程之Servlet、Filter、Listener配置
- SpringBoot初始教程之Servlet、Filter、Listener配置(七)
- spring-boot如何定义一个servlet,filter,listener
- Spring Boot 之Servlet、Listener、Filter
- SpringBoot初始教程之Servlet、Filter、Listener配置详解
- 在SpringBoot中使用 Servlet Filter Listener
- SpringBoot之Servlet、Filter、Listener配置
- springboot(4)添加Servlet、Listener、Filter
- Spring Boot参考教程(六)Spring Boot配置Servlet,Filter,Listener,Interceptor
- SpringBoot初始教程之Servlet、Filter、Listener配置
- servlet3.0 新特性和springboot Listener和filter案例
- Spring Boot 编写Servlet、Filter、Listener、Interceptor的方法
- spring boot (二) servlet listener filter interceptor
- Spring Boot使用Servlet、Filter或Listener的方式
- 【spring】SpringBoot之Servlet、Filter、Listener配置
- Spring Boot Servlet Filter Listener
- springboot 2.0.0.M7 之 Servlet Listener Filter