详解IDEA中SpringBoot整合Servlet三大组件的过程
作者:生于四海 发布时间:2023-05-06 15:23:13
Spring MVC整合
SpringBoot提供为整合MVC框架提供的功能特性
内置两个视图解析器:ContentNegotiatingViewResolver和BeanNameViewResolver
支持静态资源以及WebJars
自动注册了转换器和格式化器
支持Http消息转换器
自动注册了消息代码解析器
支持静态项目首页index.html
支持定制应用图标favicon.ico
自动初始化Web数据绑定器:ConfigurableWebBindingInitializer
Spring MVC功能扩展实现
项目环境搭建(结构如这篇博客)
功能扩展实现
注册视图管理器
/*
在config文件夹下编写配置类
实现WebMvcConfigurer接口,扩展MVC功能
测试前将LoginController控制类注释,更好的观察效果
*/
@Configuration
public class MyMVCConfig implements WebMvcConfigurer {
//添加视图管理
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 请求toLoginPage映射路径或者login.html页面都会自动映射到login.html页面
registry.addViewController("/toLoginPage").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
}
}
- 测试后发现,使用这种方式无法获取后台处理的数据,比如登录页面中的年份。
- 使用WebMvcConfigurer接口中的addViewControllers(ViewControllerRegistry registry)方法定制
视图控制,只适合较为简单的无参数视图Get方式的请求跳转,对于有参数或需要业务处理的跳转请求,最好还是采用传统方式处理请求。
注册自定义 *
/*
自定义一个 * 类,实现简单的拦截业务
*/
@Configuration
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 用户请求/admin开头路径时,判断用户是否登录
String uri = request.getRequestURI();
Object loginUser = request.getSession().getAttribute("loginUser");
if(uri.startsWith("/admin")&&null==loginUser){
response.sendRedirect("/toLoginPage");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {
//向request域中存放当前年份用于页面动态展示
request.setAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
- 自定义 * 类MyInterceptor实现了HandlerInterceptor接口。在preHandle()方法中,如果用户请求以“/admin”开头,
则判断用户是否登录,如果没有登录,则重定向到“/toLoginPage”请求对应的登录页面。
- 在postHandle()方法中,使用request对象向前端页面传递表示年份的currentYear数据。
- 在自定义配置类MyMVCConfig中,重写addInterceptors()方法注册自定义的 * ,如下
@Autowired
private MyInterceptor myInterceptor;
//添加 * 管理
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/login.html");
}
- 使用@Autowired注解引入自定义的MyInterceptor * 组件,重写其中addInterceptors()方法注册自定义的 *
- 使用addPathPatterns("/**")方法拦截所有路径请求,excludePathPatterns("/login.html")方法对“login.html”路径请求放行处理。
- 项目重启后,访问localhost:8080/admin,跳转到登录界面,自定义 * 生效。
Spring Boot 整合Servlet三大组件
组件注册方式整合Servlet三大组件
在Spring Boot中,使用组件注册方式整合内嵌Servlet容器的Servlet、Filter、Listener三大组件时,
只需要将这些自定义组件通过ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean类注册到容器中即可
组件注册方式整合 Servlet
/*
自定义Servlet类
使用@Component注解将MyServlet类作为组件注入Spring容器。该类继承自HTTPServlet,
通过HttpServletResponse对象向页面输出"hello MyServlet"
*/
@Component
public class MyServlet extends HttpServlet {
@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 {
resp.getWriter().write("hello MyServlet");
}
}
/*
嵌入式Servlet容器三大组件配置
@Configuration注解将该类标注为配置类,getServlet()方法用于注册自定义MyServlet,
返回ServletRegistrationBean类型的Bean对象
*/
@Configuration
public class ServletConfig {
// 注册Servlet组件
@Bean
public ServletRegistrationBean<javax.servlet.Servlet> getServlet(MyServlet myServlet){
return new ServletRegistrationBean<javax.servlet.Servlet>(myServlet,"/myServlet");
}
}
启动测试,访问myServlet,显示数据说明成功整合Servlet组件
组件注册方式整合Filter
/*
自定义Filter类
使用@Component注解将当前MyFilter类作为组件注入到Spring容器中
MyFilter类实现Filter接口,重写如下三个方法,在doFilter()方法中想控制台打印"hello MyFilter"
*/
@Component
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("hello MyFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
}
//注册Filter组件
@Bean
public FilterRegistrationBean<javax.servlet.Filter> getFilter(MyFilter myFilter){
FilterRegistrationBean<javax.servlet.Filter> registrationBean = new FilterRegistrationBean<>(myFilter);
registrationBean.setUrlPatterns(Arrays.asList("/toLoginPage","/myFilter"));
return registrationBean;
}
启动测试,访问/myFilter,控制台看到hello MyFilter
组件注册方式整合Listener
/*
自定义Listener类
*/
@Component
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized ...");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed ...");
}
}
//注册Listener组件
@Bean
public ServletListenerRegistrationBean<java.util.EventListener> getServletListener(MyListener myListener){
return new ServletListenerRegistrationBean<>(myListener);
}
程序启动成功后,会自动打印输出"contextInitialized ...",单击坐下的Exit关闭会输出销毁的监听信息,如果直接强制关闭程序,无法打印监听信息。
注意:当自定义的Servlet组件配置类ServletConfig全部注释并重启项目后,自定义的Servlet、Filter、Listener组件仍然生效。
原因:嵌入式Servlet容器对Servlet、Filter、Listener组件进行了自动化识别和配置,而自定义的Servlet、Filter、Listener都继承/实现了对应的类/接口,同时自定义的这三个组件都使用了@Component注解,会自动被扫描为Spring组件。
路径扫描整合Servlet三大组件
使用路径扫描的方式整合三大组件,需要再自定义组件上分别添加@WebServlet、@WebFilter、@WebListener注解进行声明,并配置相关注解属性,在主程序启动类上使用@ServletComponentScan注解开启组件扫描。
分别用以下三个注解代替@Component注解进行配置三个组件
@WebFilter(value={"/antionLogin","/antionMyFilter"})
@WebListener
@WebServlet("/annotationServlet")
启动类上加入
@ServletComponentScan
注解,开启基于注解的组件扫描支持对于Filter测试访问"/antionLogin","/antionMyFilter",对于Servlet测试访问"/annotationServlet",测试结果如上。
来源:https://blog.csdn.net/qq_39589936/article/details/109637242


猜你喜欢
- 一、定义1、T 代表一种类型可以加在类上,也可以加在方法上1)T 加在类上class SuperClass<A>{//todo}
- 项目背景因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中
- 1.概述做一个项目,突然需要实现回复功能,所依记录一下此次的一个实现思路,也希望给别人分享一下,估计代码还是不够完善,有空在实现分页功能。话
- 这篇文章主要介绍了spring boot多数据源动态切换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 添加maven依赖<?xml version="1.0" encoding="UTF-8"?&
- 一、线程优先级的介绍java 中的线程优先级的范围是1~10,默认的优先级是5。“高优先级线程”会优先于“低优先级线程”执行。java 中有
- 栈的变化规则:1、方法调用会导致栈的生长,具体包括两个步骤:一、插入方法返回地址(下图中的Fn:);二、将实际参数按值(可以使用ref或ou
- 本文实例为大家分享了Android 自定义弹窗提示的具体代码,供大家参考,具体内容如下Java文件:private void showSet
- Runtime.getRuntime().exec 路径包含空格1. 现象java代码通过Runtime.getRuntime().exec
- 应用启动数据初始化接口CommandLineRunner和Application详解在SpringBoot项目中创建组件类实现Command
- 关于注入数据说明1.不通过配置文件注入数据通过@Value将外部的值动态注入到Bean中,使用的情况有:注入普通字符串注入操作系统属性注入表
- SpringBoot自带Tomcat,所以我们的项目可以单独部署,不需要依赖Window、Linux系统中的服务器,所以打包出来的Jar包是
- 将int数组转化为Integer数组这里使用java8的stream来进行转化,详细步骤如下所示://初始化int数组int[] nums
- 这篇文章主要介绍了JAVA内存溢出解决方案图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参
- Hystrix Dashboard,它主要用来实时监控Hystrix的各项指标信息。通过Hystrix Dashboard反馈的实时信息,可
- 使用场景在 Java 应用中,对于访问频率高,更新少的数据,通常的方案是将这类数据加入缓存中。相对从数据库中读取来说,读缓存效率会有很大提升
- Android Studio + Gradle的组合用起来非常方便,很多第三方开源项目也早都迁移到了Studio,为此今天就来介绍下查看、编
- 前段时间因为看JUC的源码,里面有大量关于unsafe的操作,所以就来看看了.写点笔记总结下(本文基于jdk1.8):unsafe可以帮我们
- 本文我将要介绍一下mybatis的框架原理,以及mybatis的入门程序,实现用户的增删改查,她有什么优缺点以及mybatis和hibern
- 前言Stream是一个来自数据源的元素队列并支持聚合操作,其中具有以下特性:Stream只负责计算,不存储任何元素,元素是特定类型的对象,形