如何优雅地使用Spring Boot拦截器提升应用的用户体验?
🏆本文收录于《Spring Boot从入门到精通》,专门攻坚指数提升,2023 年国内最系统+最强(更新中)。
本专栏致力打造最硬核Spring Boot 系列教程,从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。
环境说明:Windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE
前言
在Web开发中,经常需要对请求进行预处理或后处理,在Spring Boot中则采用拦截器的方式来实现。拦截器可以在请求到达Handler前或请求返回前做一些处理,比如验证用户的登录状态、记录日志、修改请求参数等。本文将介绍Spring Boot中的拦截器相关知识,并提供实例代码。
摘要
本文将介绍Spring Boot中的拦截器,包括拦截器的基本概念、使用方法、实现原理等。并提供一个简单的示例代码,通过该示例代码可以更好地理解拦截器的应用场景和实现方法。
拦截器
概念
拦截器是一种在Web开发中常用的处理机制,可以在请求到达Controller前或请求返回前做一些处理。拦截器和过滤器类似,但是拦截器更加灵活,可以拦截Controller中的方法调用,而过滤器只能拦截请求和响应。拦截器可以用于实现登录验证、权限控制、日志记录等功能。
在Spring Boot中,拦截器是通过实现HandlerInterceptor
接口来实现的。
应用场景
拦截器主要用于对请求进行处理,在请求到达controller之前或之后对请求进行一些处理。
- 登录验证,比如用户请求某一个需要登录才能访问的接口时,先判断是否登录,未登录则跳转到登录界面,已登录则继续访问。
- 路径权限控制,在访问某一个路径时,根据登录用户的权限来判断是否可以访问,如不能访问则返回相应的错误信息。
- 日志记录,拦截器可以在请求到达或离开controller时记录一些请求相关信息,方便后续日志分析。
- 请求参数验证,拦截器可以对请求参数进行验证,如果参数不符合要求则返回相应的错误信息。
优缺点
优点
- 拦截器可以在请求到达controller之前或之后对请求进行处理,比如对请求参数进行验证、记录请求日志等。
- 拦截器可以对多个接口进行统一处理,提高代码复用性和开发效率。
- 拦截器可以进行链式拦截,如一个请求需要经过多个拦截器处理,可以配置多个拦截器按照一定的顺序进行处理。
缺点
- 拦截器只能对controller的请求进行处理,无法拦截到像静态资源等不经过controller的请求。
- 拦截器只能对请求进行处理,无法进行响应结果处理,如返回结果加密等操作。
- 拦截器可能会增加请求处理时间,对系统性能有一定的影响。
代码演示
首先,我们需要编写一个实现了HandlerInterceptor
接口的拦截器类,如下所示:
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求到达Controller前做一些处理
return true; // 返回true表示继续执行,返回false表示中断执行
}
@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 {
// 在请求完成后做一些处理
}
}
其中,HandlerInterceptor
接口有三个方法需要实现:
preHandle
方法在请求到达Controller前执行,返回值表示是否继续执行,如果返回false表示中断执行。postHandle
方法在请求返回前执行,可以修改响应内容或重定向。afterCompletion
方法在请求完成后执行,可以做一些资源清理等工作。
接下来,我们需要在Spring Boot中注册该拦截器,有两种方式可以实现。
第一种方式是在WebMvcConfigurer
接口中注册拦截器,如下所示:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
这种方式需要实现WebMvcConfigurer
接口,并重写addInterceptors
方法。通过registry.addInterceptor
方法注册拦截器,并使用addPathPatterns
方法指定需要拦截的请求路径。
第二种方式是通过注解方式来注册拦截器,如下所示:
@Configuration
public class InterceptorConfig {
@Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor()).addPathPatterns("/**");
}
};
}
}
这种方式需要使用@Configuration注解来声明InterceptorConfig类是一个配置类,通过@Bean注解将拦截器注册到Spring容器中,并通过WebMvcConfigurerAdapter
类的子类来实现addInterceptors
方法。与第一种方式相比,这种方式更加灵活,可以在拦截器中使用@Autowired等注解自动装配其他Spring组件。
实现原理
拦截器的实现依赖于Spring MVC框架中的HandlerInterceptor
接口。当请求到达DispatcherServlet时,DispatcherServlet会依次调用注册在WebMvcConfigurer
中的所有拦截器的preHandle
方法,如果返回true则继续处理,否则返回错误信息。在Controller中的方法调用完成之后,DispatcherServlet会依次调用注册在WebMvcConfigurer
中的所有拦截器的postHandle
方法。
示例代码
以下示例代码演示了如何在Spring Boot中实现拦截器。假设我们需要实现登录状态的拦截器,当用户未登录时,返回错误信息,否则继续执行。
首先,我们需要在Spring Boot中实现一个登录功能,代码如下所示:
@RestController
public class LoginController {
@PostMapping("/login")
public String login(@RequestBody User user) {
// 登录验证
if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) {
return "登录成功";
} else {
return "登录失败";
}
}
}
这里假设我们使用POST请求来登录,请求体中包含用户名和密码。
然后,我们需要实现一个拦截器来验证用户的登录状态,代码如下所示:
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断用户是否登录
HttpSession session = request.getSession();
if (session.getAttribute("user") == null) {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("请先登录");
return false;
}
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 {
}
}
这里我们判断用户是否登录是根据Session中是否存在“user”属性来判断的。如果未登录,我们返回错误信息。
最后,我们需要将拦截器注册到Spring Boot中,代码如下所示:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/hello");
}
}
这里我们使用了第一种方式将拦截器注册到Spring Boot中,并指定了拦截路径为/hello。
最后,我们使用一个Controller类来测试拦截器的效果,代码如下所示:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello World";
}
}
这里我们定义了一个简单的/hello接口,请求该接口会返回“Hello World”字符串。
当我们未登录时,请求该接口会返回“请先登录”字符串。当我们登录后,请求该接口会正常返回“Hello World”字符串。
测试用例
以下是一个简单的测试用例,用于测试拦截器的效果:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class LoginInterceptorTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testLoginInterceptor() {
String response = restTemplate.getForObject("/hello", String.class);
assertEquals("请先登录", response);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{\"username\":\"admin\",\"password\":\"123456\"}", headers);
restTemplate.postForObject("/login", entity, String.class);
response = restTemplate.getForObject("/hello", String.class);
assertEquals("Hello World", response);
}
}
这里我们使用TestRestTemplate
来发送HTTP请求,测试拦截器的效果。首先请求/hello接口,会返回“请先登录”字符串,然后通过/login接口登录,再次请求/hello接口,会正常返回“Hello World”字符串。
小结
本文通过一个简单的示例代码演示了如何在Spring Boot中实现拦截器,并使用测试用例测试了拦截器的效果。通过本文,我们可以了解到:
- 拦截器可以用于在请求被处理之前或之后,对请求进行相关的处理;
- 在Spring Boot中,可以通过实现HandlerInterceptor接口来实现拦截器;
- 可以使用两种方式将拦截器注册到Spring Boot中,一种是通过@Configuration配置类实现WebMvcConfigurer接口,另一种是使用@WebFilter注解;
- 常用的拦截器应用场景包括:登录验证、请求参数验证、请求日志记录等。
附录源码
如上涉及所有源码均已上传同步在「GitHub」,提供给同学们一对一参考学习,辅助你更迅速的掌握。
总结
本文介绍了在Spring Boot中实现拦截器的方法,以一个登录状态验证的示例为例进行讲解。我们通过实现一个登录功能和一个拦截器来验证用户的登录状态,并将拦截器注册到Spring Boot中,验证了拦截器的效果。
总结来说,拦截器是Spring Boot中常用的一种功能,在需要对请求进行统一处理、验证登录状态等场景下非常有用。通过本文的学习,我们可以掌握拦截器的基本使用方法,并应用到实际的开发中去。
☀️建议/推荐你
无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Spring Boot」,从入门到精通,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大,指数级提升。
最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。
同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。
📣关于我
我是bug菌,CSDN | 掘金 | InfoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。
- 点赞
- 收藏
- 关注作者
评论(0)