如题。本篇,我们介绍写springboot (web工程)中mvc拦截器使用以及web servlet、filter、listener的使用。
spring mvc拦截器,能够拦截对指定路径的controller的访问 ,但不会拦截对servlet的访问,因为本质上讲springMVC(前端控制器)也是个servlet,试问servlet又怎么能够拦截对servlet的访问呢?
package com.tingcream.springWeb.spring.mvc; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** * mvc 拦截器 ,记录请求者ip和请求路径 * @author jelly * */ @Component public class MyMvcInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String clientIP= request.getRemoteAddr(); String contextPath=request.getContextPath(); String uri=request.getRequestURI(); String requestPage=uri.replaceFirst(contextPath, "").replaceAll("/+", "/"); System.out.println("请求者IP:"+clientIP+",请求页面:"+requestPage); return true; } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { } @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { } }
package com.tingcream.springWeb.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.tingcream.springWeb.spring.mvc.MyMvcInterceptor; /** * mvc interceptor 配置bean * * @author jelly * */ @Configuration public class WebMvcConfiguration extends WebMvcConfigurerAdapter { @Autowired private MyMvcInterceptor myMvcInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myMvcInterceptor).addPathPatterns("/**"); } }
servlet 、filter、listener 三者都是servlet web容器中的东西,它们跟web容器产生之间关联,而跟spring其实没有直接的联系。
其实spring不一定要非得运行在web环境中,只不过因为我们大多数人都是用spring开发web程序,所以会很自然地把web容器和spring容器相混淆。而在web环境中,spring容器是web容器所创建的一个环境,实际上web中的spring只不过是web容器的一个监听器(servlet listener)
咳咳,我们现在回到正题。
springboot web项目中由于没有了web.xml,传统的在web.xml中配置servlet、filter、listener的方式显然是行不通的了,那么怎么办呢?
其实在servlet3.0规范中,已经不建议开发者在web.xml中配置servlet、filter、listener了,而是采用@WebServlet、@WebFilter、@WebListener注解方式进行标记。
采用注解的方式能够有效避免web.xml配置文件的过于膨胀,并且注解方式使用起来更简洁,方便,对开发人员更友好。
MyServlet.java
package com.tingcream.springWeb.web.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; /** * servlet * * @author jelly * */ @WebServlet("/myServlet") public class MyServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("/myServlet 访问成功!!"); resp.setContentType("text/html;charset=utf-8"); resp.getWriter().write("/myServlet 访问成功!! "); } }
MyFilter.java
package com.tingcream.springWeb.web.filter; 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; /** * servlet 过滤器 * @author jelly * */ @WebFilter(filterName="myFilter",urlPatterns="/*") public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("myFilter==========init"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("myFilter==========doFilter"); chain.doFilter(request,response); } @Override public void destroy() { System.out.println("myFilter==========destroy"); } }
MyListener.java
package com.tingcream.springWeb.web.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * servet 监听器 * @author jelly * */ @WebListener public class MyListener implements ServletContextListener { /** * servlet 容器初始化 */ @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("MyListener-----servlet容器初始化 "); } /** * servlet 容器销毁 */ @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("MyListener-----servlet容器销毁 "); } }
package com.tingcream.springWeb; import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ImportResource; /** * spring-boot 入口程序 * * @author jelly * */ //@SpringBootApplication @SpringBootConfiguration @EnableAutoConfiguration(exclude={ DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, AopAutoConfiguration.class}) @ComponentScan @ImportResource({"classpath:/spring.xml"}) @ServletComponentScan public class SpringBootApp extends SpringBootServletInitializer{ //实现SpringBootServletInitializer接口 ,需实现此方法。 可以war包形式 发布到tomcat中 @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder builder) { return builder.sources(SpringBootApp.class); } public static void main(String[] args) { SpringApplication.run(SpringBootApp.class, args); } }
ok !!!
最后,笔者想简单说下关于spring web中的controller、servlet、filter、listener的初始化、执行、销毁顺序 。
(启动容器时)
Listener初始化
Filter初始化
servlet初始化
controller初始化
Filter过滤器可以对servlet和controller进行过滤,而mvc拦截器只能对controller进行过滤。
如果浏览器请求了一个controller路径,则执行顺序如下:
Filter过滤器
mvc拦截器
controller
......
如果浏览器请求了一个servlet路径,则执行顺序如下:
Filter过滤器
servlet
.....
(最后停止容器时)
controller销毁
servlet销毁
filter销毁
Listener销毁
Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1