前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【原创】006 | 搭上SpringBoot实战专车系列六:自定义拦截器

【原创】006 | 搭上SpringBoot实战专车系列六:自定义拦截器

作者头像
java进阶架构师
发布2021-02-22 14:29:39
4910
发布2021-02-22 14:29:39
举报
文章被收录于专栏:Java进阶架构师Java进阶架构师

专车介绍

该趟专车是开往SpringBoot自定义拦截器的实战专车,拦截器通常用来实现请求鉴权,判断用户是否具有当前请求资源的权限,如果存在权限,则允许用户访问该资源,如果不存在权限,则不允许用户访问该资源的权限。

专车问题

第一个问题:SpringBoot如何自定义拦截器?

第二个问题:如何使用SpringBoot拦截器实现请求鉴权?

专车实战

第一步:在父模块下面新建一个名为boot-example-interceptor的子模块

第二步:子模块添加如下依赖

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

第三步:创建拦截器

代码语言:javascript
复制
@Slf4j
public class WebRequestInterceptor implements HandlerInterceptor {

    /**
     * 业务前置处理
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("执行拦截器的前置方法");
        return true;
    }

    /**
     * 业务后置处理,只有preHandle返回true,该方法才会执行
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("只有preHandle返回true,该方法才会执行,此方法在业务方法执行完成之后执行");
    }

    /**
     * 用于资源释放,不管preHandle返回true或者false,该方法都会执行
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("不管preHandle返回true或者false,该方法都会执行,用于释放资源");
    }
}

第四步:注册拦截器

代码语言:javascript
复制
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WebRequestInterceptor()).addPathPatterns("/*");
    }
}

第五步:创建控制器

代码语言:javascript
复制
@RestController
public class IndexController {

    @RequestMapping("/")
    public String index() {
        return "hello interceptor";
    }
}

第六步:创建启动类

代码语言:javascript
复制
@SpringBootApplication
public class InterceptorApplication {

    public static void main(String[] args) {
        SpringApplication.run(InterceptorApplication.class, args);
    }
}

第七步:访问应用

http://localhost:8080/

代码语言:javascript
复制
执行拦截器的前置方法
只有preHandle返回true,该方法才会执行,此方法在业务方法执行完成之后执行
不管preHandle返回true或者false,该方法都会执行,用于释放资源

可以看到我们自定义的拦截器已经生效

那么我们如何使用拦截器来实现web请求鉴权功能呢?实现web请求鉴权首先我们要登录应用,在登录成功之后服务器会生成一个token返回给用户,用户每次请求资源的时候都需要携带这个token。服务器端判断用户的请求中是否有token,如果有的话,就放行,没有的话,就进行拦截,不让用户请求该资源。

接下来就根据以上思路来实现一个简易的鉴权功能

第一步:创建登录控制器

代码语言:javascript
复制
@RestController
@RequestMapping("/login")
public class LoginController {

    @GetMapping("/")
    public String login() {
        return "获取到的token为:" + UUID.randomUUID();
    }
}

第二步:创建用户控制器

代码语言:javascript
复制
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/")
    public String list() {
        return "user list page";
    }
}

第三步:修改拦截器注册配置

代码语言:javascript
复制
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WebRequestInterceptor()).addPathPatterns("/users/**");
    }
}

第四步:修改拦截器逻辑

代码语言:javascript
复制
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    log.info("开始鉴权");
    String token = request.getHeader("token");
    if (StringUtils.isEmpty(token)) {
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.getWriter().write("请先登录!!!");
        return false;
    } else {
        return true;
    }
}

第五步:访问用户列表页面

可以看到当前用户没有进行登录操作,不具有访问该资源的权限。那么按照提示,先进行登录操作

可以看到,登录成功之后,服务器端返回一个token标识,这个token用户判断客户端是否具有访问服务器资源的权限,如果有,那么服务器就允许访问,如果没有,那么服务器就不允许访问。既然已经登录成功,那么就可以访问用户列表页面了,只需要在访问的时候把token放在请求的header中

专车总结

第一个问题:定义拦截器首先要实现HandlerInterceptor接口,然后需要注册拦截器

第二个问题:要想实现web请求鉴权功能,需要在拦截器的preHandle方法中进行逻辑处理,该方法在目标方法执行前执行,如果鉴权通过该方法返回true,对请求放行,如果鉴权失败则返回false,对请求进行拦截

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java进阶架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 专车介绍
  • 专车问题
  • 专车实战
  • 专车总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档