✨✨个人主页:沫洺的主页
📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏
📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏
💖💖如果文章对你有所帮助请留下三连✨✨
🍊Spring Boot注册Web原生组件
由于 Spring Boot 默认以 Jar 包方式部署的,默认没有 web.xml,因此无法再像以前一样通过 web.xml 配置来使用 Servlet 、Filter、Listener,但 Spring Boot 提供了 2 种方式来注册这些 Web 原生组件
通过组件扫描注册(注解)
使用 RegistrationBean 注册
🍒通过组件扫描注册
Servlet 3.0 提供了以下 3 个注解:
@WebServlet:用于声明一个 Servlet;
@WebFilter:用于声明一个 Filter;
@WebListener:用于声明一个 Listener
这些注解可直接标注在对应组件上,它们与在 web.xml 中的配置意义相同。每个注解都具有与 web.xml 对应的属性,可直接配置,省去了配置 web.xml 的繁琐。
想要在 SpringBoot 中注册这些原生 Web 组件,可以使用 @ServletComponentScan 注解实现,该注解可以扫描标记 @WebServlet、@WebFilter 和 @WebListener 三个注解的组件类,并将它们注册到容器中。
注意:@ServletComponentScan 注解只能标记在启动类或配置类上。
注解注册---Servlet
@WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().write("登录测试"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
启动类
@SpringBootApplication @ServletComponentScan public class App2 { public static void main(String[] args) { SpringApplication.run(App2.class, args); } }
注解注册---过滤器Filter
@WebFilter(filterName = "loginFilter") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { String token = request.getParameter("token"); if("123".equals(token)){ chain.doFilter(request,response); } else{ HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "令牌不正确"); } } public void init(FilterConfig config) throws ServletException { } public void destroy() { System.out.println("过滤器被销毁时调用的方法..."); } }
启动类同上还是使用@ServletComponentScan
注解注册---监听器Listener
@Slf4j @WebListener public class ServletListener implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent sre) { log.info("-----请求进来-----"); } @Override public void requestDestroyed(ServletRequestEvent sre) { log.info("-----请求结束-----"); } }
启动类同上还是使用@ServletComponentScan
🍎使用 RegistrationBean 注册
我们还可以在配置类中使用 RegistrationBean 来注册原生 Web 组件,不过这种方式相较于注解方式要繁琐一些。使用这种方式注册的原生 Web 组件,不再需要使用 @WebServlet 、@WebListener 和 @WebListener 等注解。(可将@ServletComponentScan注解注释掉,就无法识别这三种注解了)
RegistrationBean 是个抽象类,负责将组件注册到 Servlet 容器中,Spring 提供了三个它的实现类,分别用来注册 Servlet、Filter 和 Listener。
ServletRegistrationBean:Servlet 的注册类
FilterRegistrationBean:Filter 的注册类
ServletListenerRegistrationBean:Listener 的注册类
我们可以在配置类中,使用 @Bean 注解将 ServletRegistrationBean、FilterRegistrationBean 和 ServletListenerRegistrationBean 添加 Spring 容器中,并通过它们将我们自定义的 Servlet、Filter 和 Listener 组件注册到容器中使用。
通过ServletRegistrationBean注册---servlet
@Configuration public class ServletConfig { @Bean public ServletRegistrationBean<LoginServlet> servletServletRegistrationBean(){ ServletRegistrationBean<LoginServlet> bean = new ServletRegistrationBean<>(); bean.setServlet(new LoginServlet()); bean.addUrlMappings("/loginServlet"); return bean; } }
通过FilterRegistrationBean注册---Filter
@Configuration public class ServletConfig { @Bean public FilterRegistrationBean<LoginFilter> filterFilterRegistrationBean(){ FilterRegistrationBean<LoginFilter> bean = new FilterRegistrationBean<>(); bean.setFilter(new LoginFilter()); bean.addUrlPatterns("/*"); bean.setName("loginFilter"); bean.setOrder(1); return bean; } }
通过ServletListenerRegistrationBean注册---Listener
@Configuration public class ServletConfig { @Bean public ServletListenerRegistrationBean<ServletListener> servletListenerServletListenerRegistrationBean(){ ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(); bean.setListener(new ServletListener()); return bean; } }
🍈拦截器HandlerInterceptor
🍋Spring Boot拦截器
拦截器主要应用于登陆校验、权限验证、乱码解决、性能监控和异常处理等功能,Spring Boot 同样提供了拦截器功能。
🍍定义拦截器
在 Spring Boot 中定义拦截器十分的简单,只需要创建一个拦截器类,并实现 HandlerInterceptor 接口即可。
HandlerInterceptor 接口中定义以下 3 个方法,如下表。
返回值类型 方法声明 描述 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。 void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 该方法在控制器处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改。 void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 该方法在视图渲染结束后执行,可以通过此方法实现资源清理、记录日志信息等工作。 创建拦截器SexIntercepor
@Slf4j public class SexInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); log.info("请求的URI: "+requestURI); String sex = request.getParameter("sex"); if(sex==null||!sex.equals("girl")){ response.sendError(response.SC_UNAUTHORIZED,"你不是女生,出去!!!"); } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
注册拦截器
创建一个实现了 WebMvcConfigurer 接口的配置类(使用了 @Configuration 注解的类),重写 addInterceptors() 方法,并在该方法中调用 registry.addInterceptor() 方法将自定义的拦截器注册到容器中。
@Configuration public class MyWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SexInterceptor()).addPathPatterns("/api/**"); } }
指定拦截规则
@Configuration public class MyWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SexInterceptor()) .addPathPatterns("/api/**")//拦截所有请求,包括静态资源文件 //放行登录页,登陆操作,静态资源 .excludePathPatterns("/","/loginServlet","/css/**","/images/**","/js/**"); } }
在指定拦截器拦截规则时,调用了两个方法,这两个方法的说明如下:
addPathPatterns:该方法用于指定拦截路径,例如拦截路径为"/**",表示拦截所有请求,包括对静态资源的请求。
excludePathPatterns:该方法用于排除拦截路径,即指定不需要被拦截器拦截的请求。
创建接口测试拦截器
@RestController @RequestMapping("/api") public class LoginController { @GetMapping("/login") public String test(@RequestParam String token,@RequestParam String sex){ return token+sex; } }