springboot的最大特点是把底层的servlet和容器都屏蔽起来,给我们暴露的就是controller和各种注解。本文介绍如何在springboot上要做一些低层次的servlet、filter、listener之类的开发。
在spring boot中添加自己的Servlet有两种方法:(Filter和Listener也是如此)。
1、在代码中添加注册的方式:
1)自定义servlet、filter、listener类;
2)在springboot主类中通过ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制。
2、通过注解自动注册方式:
1)自定义servlet、filter、listener类,并且使用@WebServlet、@WebFilter、@WebListener 注解自动注册;
2)在SpringBootApplication 上使用@ServletComponentScan 注解;
servlet示例(使用代码的方式):
1)自定义servlet:
package cn.edu.nuc.springbootmybatisdruid.servlet; import java.io.IOException; import java.io.PrintWriter; 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="/lx/myservlet", description="Servlet的说明") // 不指定name的情况下,name默认值为类全路径,即org.springboot.sample.servlet.MyServlet2 public class MyServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(">>>>>>>>>>doGet2()<<<<<<<<<<<"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(">>>>>>>>>>doPost2()<<<<<<<<<<<"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>大家好,我的名字叫Servlet2</h1>"); out.println("</body>"); out.println("</html>"); } }
2)主类:
@SpringBootApplication //mapper 接口类扫描包配置 @MapperScan("cn.edu.nuc.springbootmybatisdruid.dao.mysql") @EnableTransactionManagement public class App { @Bean public ServletRegistrationBean servletRegistrationBean() { return new ServletRegistrationBean(new MyServlet(), "/lx/*");// ServletName默认值为首字母小写,即myServlet } public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
默认springboot中的DispatcherServlet 会拦截所有请求(/)。如果在浏览器上输入http://XXX/lx/a 这样的请求,会被自定义的servlet执行到,规则是:“匹配的优先级是从精确到模糊,复合条件的Servlet并不会都执行”。
既然系统DispatcherServlet 默认拦截“/”,那么我们是否能做修改呢,答案是肯定的,我们在springboot主类中添加代码:
@Bean public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) { ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet); registration.getUrlMappings().clear(); registration.addUrlMappings("*.do"); registration.addUrlMappings("*.json"); return registration; }
filter示例(使用注解的方式):
1)自定义filter:
package cn.edu.nuc.springbootmybatisdruid.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; import javax.servlet.http.HttpServletRequest; @WebFilter(filterName="myFilter",urlPatterns="/*") public class MyFilter implements Filter { @Override public void destroy() { System.out.println("过滤器销毁"); } @Override public void init(FilterConfig arg0) throws ServletException { System.out.println("过滤器初始化"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String uri = ((HttpServletRequest)request).getRequestURI(); System.out.println(uri+",执行过滤操作"); chain.doFilter(request, response); } }
2)主类:
@SpringBootApplication //mapper 接口类扫描包配置 @MapperScan("cn.edu.nuc.springbootmybatisdruid.dao.mysql") @EnableTransactionManagement @ServletComponentScan public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
或者在主类中加入:
@Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new MyFilter()); List<String> urlPatterns = new ArrayList<String>(); urlPatterns.add("/api/dealer/out/list"); //这个请求会走filter。 比如是/api/product/out/list就不会走filter urlPatterns.add("/api/dealer/out/scanCheck"); urlPatterns.add("/api/dealer/out/detail"); urlPatterns.add("/api/dealer/out/scanStatus"); registrationBean.setUrlPatterns(urlPatterns); return registrationBean; }同样,对于自定义listener也是如此。
参考:
https://blog.csdn.net/catoop/article/details/50501686
https://blog.csdn.net/catoop/article/details/50501688