Spring MVC功能扩展实现
Spring Boot整合Spring MVC进行Web开发时提供了多数的自动化配置,但在实际开发中还需要开发者对一些功能进行扩展实现。下面,通过一个具体的案例讲解Spring Boot整合Spring MVC框架实现Web开发的扩展功能。
1.项目基础环境搭建
使用Spring Initializr方式创建名称为chapter05的Spring Boot项目,并在Dependencies依赖选择中选择Web模块下的Web依赖启动器和Template Engines模块下的Thymeleaf依赖启动器,效果如图1所示。
图1 场景依赖选择图
为了更直观、快速的通过页面查看整合效果,这里将借用chapter04项目中所有编写好的文件复制到本章项目对应目录下。环境搭建完成后,结构如图2所示。
图2 项目初始化结构图
图2所示的chapter05项目目录结构与chapter04项目的目录结构完全一样,并且对应目录中的文件内容也完全一样。
完成chapter05项目的初始化搭建后,可以通过浏览器访问“http://localhost:8080/toLoginPage
”查看项目的登录页面login.html,读者可以自行测试,这里就不再展示说明了。
2.功能扩展实现
上一步中,使用传统的方式实现了简单的用户请求跳转功能。接下来,使用Spring Boot整合Spring MVC实现Web开发,使用框架中提供的WebMvcConfigurer接口来编写自定义配置完成上述需求,并演示一个常用的扩展功能。
(1)注册视图管理器。在chapter05项目的com.itheima.config包下创建一个实现WebMvcConfigurer接口的配置类MyMVCconfig,用于对MVC框架功能扩展,内容如文件1所示。
文件1 MyMVCconfig.java
1 import org.springframework.context.annotation.Configuration;
2 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
3 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
4 /**
5 * 实现WebMvcConfigurer接口,扩展MVC功能
6 */
7 @Configuration
8 public class MyMVCconfig implements WebMvcConfigurer {
9 // 添加视图管理
10 @Override
11 public void addViewControllers(ViewControllerRegistry registry) {
12 // 请求toLoginPage映射路径或者login.html页面都会自动映射到login.html页面
13 registry.addViewController("/toLoginPage").setViewName("login");
14 registry.addViewController("/login.html").setViewName("login");
15 }
16 }
文件1中,MyMVCconfig实现了接口WebMvcConfigurer的addViewControllers(ViewControllerRegistry registry)方法。在addViewControllers()方法内部,使用ViewControllerRegistry的addViewController()方法分别定义了"/toLoginPage"和"/login.html"的请求控制,并使用setViewName("login")方法将路径映射为login.html页面。
定制完MVC的视图管理功能后,就可以进行效果测试了。为了演示这种定制效果,将之前的用户登录控制类LoginController代码全部注释。重启chapter05项目,项目启动成功后,在浏览器上分别访问“http://localhost:8080/toLoginPage
”和“http:``//localhost:8080/login.html”,效果如图3所示。
图3 登录页访问效果
从演示效果可以看出,使用实现WebMvcConfigurer接口定义的用户请求控制方法也实现了用户请求控制跳转的效果,相比于传统的请求处理方法而言,这种方法更加简洁、直观和方便。同时也可以看出,使用这种方式无法获取后台处理的数据,例如登录页面中的年份。
需要说明的是,使用WebMvcConfigurer接口中的addViewControllers(ViewControllerRegistry registry)方法定制视图控制的方法,只适合较为简单的无参视图Get方式的请求跳转,对于有参数或需要业务处理的跳转需求还要使用传统的方式编写对应的请求控制方法。
(2)注册自定义拦截器。WebMvcConfigurer接口提供了许多MVC开发相关方法,例如,添加拦截器方法addInterceptors()、添加格式化器方法addFormatters()等。接下来,以WebMvcConfigurer接口中添加拦截器的方法addInterceptors()为例,讲解扩展Spring Boot框架的MVC功能。
首先,在项目com.itheima.config包下创建一个自定义拦截器类MyInterceptor,并编写简单的拦截业务代码,内容如文件2所示。
文件2 MyInterceptor.java
1 import org.springframework.lang.Nullable;
2 import org.springframework.stereotype.Component;
3 import org.springframework.web.servlet.HandlerInterceptor;
4 import org.springframework.web.servlet.ModelAndView;
5 import javax.servlet.http.HttpServletRequest;
6 import javax.servlet.http.HttpServletResponse;
7 import java.util.Calendar;
8 /**
9 * 自定义一个拦截器类
10 */
11 @Component
12 public class MyInterceptor implements HandlerInterceptor {
13 @Override
14 public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
15 Object handler) throws Exception {
16 // 用户请求/admin开头路径时,判断用户是否登录
17 String uri = request.getRequestURI();
18 Object loginUser = request.getSession().getAttribute("loginUser");
19 if (uri.startsWith("/admin") && null == loginUser) {
20 response.sendRedirect("/toLoginPage");
21 return false;
22 }
23 return true;
24 }
25 @Override
26 public void postHandle(HttpServletRequest request, HttpServletResponse response,
27 Object handler, @Nullable ModelAndView modelAndView) throws Exception {
28 // 向request域中存放当前年份用于页面动态展示
29 request.setAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
30 }
31 @Override
32 public void afterCompletion(HttpServletRequest request, HttpServletResponse
33 response, Object handler, @Nullable Exception ex) throws Exception {
34 }
35 }
文件2中,自定义拦截器类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”路径的请求进行了放行处理。
最后重启chapter05项目,项目启动成功后,在浏览器上访问“http://localhost:8080/admin
”,效果如图4所示。
图4 访问admin路径效果
从图4可以看到,访问“http://localhost:8080/admin
”路径时自动跳转到了用户登录页面,同时在页面中动态显示出了当前年份,这就说明此次定制的自定义拦截器生效。
需要说明的是,Spring Boot在整合Spring MVC过程中提供了许多默认自动化配置和特性,开发者可以通过Spring Boot提供的WebMvcConfigurer接口对MVC功能进行定制和扩展。如果开发者不想使用Spring Boot整合MVC时提供的一些默认配置,而是想要绝对的自定义管理,那么可以编写一个@Configuration注解配置类,同时添加@EnableWebMvc注解关闭Spring Boot提供的所有关于MVC功能的默认配置。