servlet3.0之前都是在web.xml中设置Servlet、Filter、Listener,springboot里面没有web.xml这个文件了,因为功能被其他替代了
springboot整合Servlet、Filter、Listener有两种方法
一、servlet3.0注解
1、使用@WebServlet,@WebFilter,@WebListener,@ServletComponentScan注册
@Web*开头的注解是Servlet3.0 api中提供的注解,通过注解可以完全代替web.xml中的配置
2、添加MyServlet1.java
package com.example.config;
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(name = "MyServlet1", urlPatterns = "/servlet1")
public class MyServlet1 extends HttpServlet {
private static final long serialVersionUID = -2449675904917739591L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("MyServlet1 in");
resp.getWriter().print("hello servlet1");
resp.getWriter().flush();
resp.getWriter().close();
System.out.println("MyServlet1 out");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
3、添加MyFilter1.java
package com.example.config;
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 = "MyFilter1", urlPatterns = "/*")
public class MyFilter1 implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("filter1 in");
chain.doFilter(request, response);// 放行
System.out.println("filter1 out");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter1 init");
}
@Override
public void destroy() {
System.out.println("MyFilter1 destroy");
}
}
4、添加MyListener1.java
package com.example.config;
import java.time.LocalDateTime;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyListener1 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("MyListener1 init");
System.out.println("app startup at " + LocalDateTime.now().toString());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("MyListener1 destroy");
System.out.println("app stop at " + LocalDateTime.now().toString());
}
}
5、启动类添加扫描注解
注意需要添加扫描路径,否则就在启动类的包下找,会找不到
package com.example.myboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
@ServletComponentScan(basePackages = {"com.example"}) // 指定扫描路径
@ComponentScan(basePackages = {"com.example"}) // 指定扫描路径
@SpringBootApplication
public class MybootApplication {
public static void main(String[] args) {
SpringApplication.run(MybootApplication.class, args);
}
}
6、测试
可以看到javax.servlet下的类都来自于tomcat的包
启动springboot,浏览器访问:http://127.0.0.1:8088/servlet1
...
2020-03-23 11:35:04.796 [] INFO [main] com.example.myboot.MybootApplication :The following profiles are active: model1,model2,dev
2020-03-23 11:35:05.704 [] INFO [main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer :Tomcat initialized with port(s): 8088 (http)
2020-03-23 11:35:05.821 [] INFO [main] org.springframework.web.context.ContextLoader :Root WebApplicationContext: initialization completed in 1010 ms
MyListener1 init
app startup at 2020-03-23T11:35:05.884
MyFilter1 init
2020-03-23 11:35:06.024 [] INFO [main] org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor :Initializing ExecutorService 'applicationTaskExecutor'
2020-03-23 11:35:06.147 [] WARN [main] o.s.b.a.t.ThymeleafAutoConfiguration$DefaultTemplateResolverConfiguration :Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
2020-03-23 11:35:06.233 [] INFO [main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer :Tomcat started on port(s): 8088 (http) with context path ''
2020-03-23 11:35:06.233 [] INFO [main] com.example.myboot.MybootApplication :Started MybootApplication in 1.797 seconds (JVM running for 2.193)
filter1 in
MyServlet1 in
MyServlet1 out
filter1 out
...
二、通过springboot提供的配置类
1、使用ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean类注册
2、添加MyServlet2.java、MyFilter2.java、MyListener2.java没有@Web*开头的注解
原来filter调用顺序是按照web.xml中,filter-mapping哪个配置在前,哪个就先执行
FilterRegistrationBean可以按照启动顺序order值越小,越先注册,Filter越早经过
MyFilter2.java
package com.example.config;
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;
public class MyFilter2 implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("filter2 in");
chain.doFilter(request, response);// 放行
System.out.println("filter2 out");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter2 init");
}
@Override
public void destroy() {
System.out.println("MyFilter2 destroy");
}
}
MyServlet2.java
package com.example.config;
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 MyServlet2 extends HttpServlet {
private static final long serialVersionUID = -5058369010982472940L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("MyServlet2 in");
resp.getWriter().print("hello servlet2");
resp.getWriter().flush();
resp.getWriter().close();
System.out.println("MyServlet2 out");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
MyListener2.java
package com.example.config;
import java.time.LocalDateTime;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener2 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("MyListener2 init");
System.out.println("app startup at " + LocalDateTime.now().toString());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("MyListener2 destroy");
System.out.println("app stop at " + LocalDateTime.now().toString());
}
}
3、添加WebConfig.java
package com.example.config;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContextListener;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
@Bean
public ServletRegistrationBean<Servlet> myServlet() {
ServletRegistrationBean<Servlet> servlet = new ServletRegistrationBean<>(new MyServlet2());
servlet.addUrlMappings("/servlet2");
servlet.setName("MyServlet2");
return servlet;
}
@Bean
public FilterRegistrationBean<Filter> myFilter() {
FilterRegistrationBean<Filter> filter = new FilterRegistrationBean<>(new MyFilter2());
filter.addUrlPatterns("/*");
filter.setOrder(2); // 设置注册bean的顺序
filter.setName("MyFilter2");
return filter;
}
@Bean
public ServletListenerRegistrationBean<ServletContextListener> myListener() {
ServletListenerRegistrationBean<ServletContextListener> listener = new ServletListenerRegistrationBean<>(
new MyListener2());
return listener;
}
}
4、测试
启动springboot,浏览器访问:http://127.0.0.1:8088/servlet2
...
2020-03-23 14:43:49.329 [] INFO [main] com.example.myboot.MybootApplication :The following profiles are active: model1,model2,dev
2020-03-23 14:43:50.247 [] INFO [main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer :Tomcat initialized with port(s): 8088 (http)
2020-03-23 14:43:50.360 [] INFO [main] org.springframework.web.context.ContextLoader :Root WebApplicationContext: initialization completed in 1003 ms
MyListener2 init
app startup at 2020-03-23T14:43:50.424
MyListener1 init
app startup at 2020-03-23T14:43:50.424
MyFilter1 init
MyFilter2 init
2020-03-23 14:43:50.575 [] INFO [main] org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor :Initializing ExecutorService 'applicationTaskExecutor'
2020-03-23 14:43:50.697 [] WARN [main] o.s.b.a.t.ThymeleafAutoConfiguration$DefaultTemplateResolverConfiguration :Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
2020-03-23 14:43:50.787 [] INFO [main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer :Tomcat started on port(s): 8088 (http) with context path ''
2020-03-23 14:43:50.790 [] INFO [main] com.example.myboot.MybootApplication :Started MybootApplication in 1.809 seconds (JVM running for 2.19)
filter2 in
filter1 in
MyServlet2 in
MyServlet2 out
filter1 out
filter2 out
...
三、注解说明
1、@WebServlet
配置servlet的注解
2、@WebFilter
配置filter的注解
3、@WebListener
配置listener的注解
4、@ServletComponentScan
开启Servlet组件扫描功能,如果应用是用jar包形式启动,内嵌服务器不会直接执行Servlet3.0里面接口,所以需要添加。如果是放到tomcat中启动,则不需要扫描
参考资料:
https://blog.csdn.net/king_is_everyone/article/details/53116744
https://blog.csdn.net/weixin_34128501/article/details/92424885
https://www.cnblogs.com/li-yan-long/p/10772600.html
注:最新代码上传至https://github.com/csj50/myboot