第六章:如何在SpringBoot项目中使用拦截器

作者: 恒宇少年 | 来源:发表于2017-04-07 22:15 被阅读35842次

拦截器对使用SpringMvc、Struts的开发人员来说特别熟悉,因为你只要想去做好一个项目必然会用到它。拦截器在我们平时的项目中用处有很多,如:日志记录(我们后续章节会讲到)、用户登录状态拦截、安全拦截等等。而SpringBoot内部集成的是SpringMVC控制框架,所以使用起来跟SpringMVC没有区别,只是在配置上有点不同。废话不多说,我们开始我们本章的内容!

本章目标

学习使用SpringBoot中是如何配置拦截器,使用拦截器来完成简单的用户登录状态判定。

构建项目

我们创建一个名字叫做Chapter6的SpringBoot项目,添加如下maven依赖:Web、MySQL、JPA、Druid等。复制上一章配置文件application.yml到本章对应目录下,具体项目结构如下图1所示:

图1

我们的application.yml文件内容需要修改添加JSP的支持,另外如果你下载后放到你本地的项目时,需要将数据库的地址以及用户名,密码修改成对应自己的配置信息。添加JSP路径配置支持如下图2所示:

图2

InteiiJ IDEA工具为我们创建的SpringBoot项目是不存在webapp、WEB-INF结构目录的,我们需要自行添加,如下图3所示:

图3

可以看到上述图3我们对应的创建了jsp目录,接下来我们分别创建名字叫做,index.jsp,login.jsp的JSP页面文件,index.jsp内填写“你已成功访问到主页面!”,login.jsp创建一个登录表单,输入一个用户名、密码字段,具体内容如下图4、图5所示:

图4 图5

配置控制器

上述JSP文件已经创建完成,下面我们需要让SpringBoot内置SpringMVC控制器转发到对应的JSP页面,我们创建名叫LoginController的类文件,并且加入登录用户的方法,如下图6所示:

图6

下面我们配置用户从数据库中读取,因为之前的表没有“密码”字段我们下图在之前的表内添加一个密码字段如下图7所示:

图7

表结构已经修改,我们根据表结构创建对应的实体,根据实体类直接创建SpringDataJPA的管理接口,SpringDataJPA的具体讲解我留到下面的章节给大家好好的梳理梳理,本章先使用最简单的部分查询功能。我下面直接贴对应的实体类代码以及JPA代码,如下图8、图9所示:

图8 图9

用户的实体以及JPA配置完成后我们再次打开LoginController,将UserJPA使用SpringBean的形式注入,然后完成简单的登录逻辑,如下图10所示:

图10

上图10可以看到我们使用SpringDataJPA从数据库中查询指定用户,然后再比对密码是否符合,我再次修改LoginController在登录成功的地方,添加将用户写入session中。如下图11所示:

图11

到现在我们还没有编写有关拦截器的相关内容,上述都是地基,我们接下来开始盖楼。

创建拦截器

在创建拦截器之前我们需要添加初始化登录页面的转发配置,我们创建IndexController添加初始化登录、首页页面转发配置,如下图12所示:

图12

完成上述操作后,创建一个名叫做SessionInterceptor的拦截器实体类,实现SpringMVC内部接口HandlerInterceptor,并且添加如果没有session状态直接跳转到/user/login_view地址也就是我们对应的login.jsp页面,拦截器配置如下图13所示:

图13

接下来我们需要将SessionInterceptor拦截器添加到SpringBoot的配置中,让SpringBoot项目有这么一个拦截器存在,我们新创建一个SessionConfiguration,将拦截器的配置以及拦截路径配置好,如下图14所示:

图14

好了,我们的所有工作都已经做好,下面我们来初尝试运行项目,看看有没有什么问题

初尝试运行

我们观察InteiilJ IDEA工具的控制台的日志如下图15所示,证明你的项目启动没有问题,那么我们先来访问首页地址尝试登录地址:127.0.0.1:8080/user/index,我们发现了一个意向不到的结果,如下图15所示:

图15

为什么会出现这个问题呢?我们已经排除了/user/login以及/user/login_view请求地址为什么还会出现这个问题呢?遇到这个问题我们可以去SessionInterceptor内打印request.getRequestURI()看看输出的地址,如下图16所示:

图16

我们发现不仅仅有/user/login_view,还存在一个/error页面,为什么出现这个呢?这时才恍然大悟,我们在pom.xml配置文件中并没有配置JSP的支持,我们打开pom.xml配置文件将jsp以及servlet的依赖添加进去,如下图17所示:

图17

完成依赖添加后,重启项目,再次访问127.0.0.1:8080/user/index,现在显示是没有问题了,我们没有登录直接访问index.jsp,当然会被拦截器拦截,拦截后直接跳转到登录页面(login.jsp),如下图18所示效果:

图18

我们现在输入数据库内存在的用户名:admin,密码:123456的测试用户进行登录,效果如下图19所示:

图19

显示我们已经登录成功,也就是说我们的登录用户消息已经存放到session内,那么我们来访问127.0.0.1:8080/user/index地址进行验证,如下图20所示:

图20

可以看到图20效果,我们可以访问到了index.jsp页面的内容了,我们的拦截器完美的完成的拦截使命。

总结

上述内容是本章的全部讲解内容,本章主要内容讲解SpringBoot项目是如果配置拦截器,并且实现简单的用户登录状态验证拦截实例。

本章代码已经上传到码云:

SpringBoot配套源码地址:https://gitee.com/hengboy/spring-boot-chapter

SpringCloud配套源码地址:https://gitee.com/hengboy/spring-cloud-chapter

SpringBoot相关系列文章请访问:目录:SpringBoot学习目录

QueryDSL相关系列文章请访问:QueryDSL通用查询框架学习目录

SpringDataJPA相关系列文章请访问:目录:SpringDataJPA学习目录

SpringBoot相关文章请访问:目录:SpringBoot学习目录,感谢阅读!

欢迎加入QQ技术交流群,共同进步。

QQ技术交流群

相关文章

网友评论

  • coolzpw:每天学一点!~ 顶个~ 另外博主,我现在就是比较困惑的是我对spring不熟,直接学习springboot,这样可以不? 是不是还是要学习下spring相关的基础?
    coolzpw:@恒宇少年 好的!~:smile:
    恒宇少年:@coolzpw 去看看基础吧,要不你学起来比较吃力
  • 882c4da1b7ee:写的不错,干练明了
  • cc0887f7415a:我的代码,碰到了用Optional<UserEntity> userEntity = userJPA.findOne(new Specification<UserEntity>()。用Optional修饰才可以,然后后续的获取userEntity的属性时,不能直接用userEntity。需要用userEntity.get().getPwd()才可以。我查了一下Optional,这是jdk8新引入的,避免nullPoint的一个类。
    ChristmasBoy:正在不解呢,看到老哥的评论。很给力
  • 我给你一个大大的YES:没有源码了吗,大佬
    恒宇少年:@我给你一个大大的YES 码云
  • 8630b7c5cd1a:评论区大家的问题都是按照前面到课程顺序做下来,使用到同一份代码,与前面FastJsonConfiguration的配置冲突.
    由于WebMvcConfigurerAdapter被弃用,因此要继承WebMvcConfigurationSupport或实现WebMvcConfigurer,.
    如果是继承WebMvcConfigurationSupport,则会与本节内容冲突,访问/user/index报错.
    如果是实现WebMvcConfigurer,则不会冲突,访问正常.
    8611196c60b4:冲突是指不能有两个类继承WebMvcConfigurationSupport吗,然后只会加载一个config类?我也遇到这样的问题.
    小炉炉:很幸运我是直接实现了WebMvcConfigure 没有踩到坑
  • koguma:response.sendRedirect("/user/login_view");
    根本就没有 /user/login_view 这个路由呀,一直404 .
    297c3b7e4efa:有的,在IndexController.java里面
  • stray_dog:已经全部按照上面配置了,拦截器管用了,但是在重定向“login”时Could not resolve view with name 'login' in servlet with name 'dispatcherServlet',请问楼主这个是怎么回事啊?
    46159825b0ed:先感谢大佬的教程,初步学习中,这个问题我也碰到了,后来找了半天发现是fastjson配置时messageConver的问题,把fastjson那个配置全部注释掉就正常了。另外问下大佬,如果站点又有有页面又有api接口时需要那个fastjson时需要怎么办。
    神豪VS勇士赢:请问 兄弟 这个问题你解决了吗
    恒宇少年:你加群截图发下吧
  • senselyan:谢谢
  • 和风拂柳花香醉人:首先感谢作者的分享。
    其次建议作者,下次项目编号用01代替1,这样子容易排序,就不用在几十个项目中翻来翻去找源码了。按现在的顺序找源码,总觉得不痛快,每次都要翻。
    恒宇少年:@Conca_Mo 我会注意的,感谢你的建议
    和风拂柳花香醉人:@恒宇少年 还有就是作者的代码格式不统一,一会C风格,一会java风格,重度强迫症患者表示看得着急。哈哈:smile:
    恒宇少年:@Conca_Mo 好的,谢谢
  • 6be3c6d729ed:UserEntity userEntity = userJPA.findOne(new Specification<UserEntity>() {

    @Override
    public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    criteriaQuery.where(criteriaBuilder.equal(root.get("name"), user.getName()));
    return null;
    }
    });
    我这里一直报错说不兼容的类型是怎么回事呢?
    ChristmasBoy:看26楼评论
    114e5d3b9305:Optional<UserEntity> userEntity = userJPA.findOne(new Specification<UserEntity>() {......
    就可以了
  • 咔dua翠嘞:WebMvcConfigurerAdapter 这个鬼过时咯 换成 WebMvcConfigurationSupport 用不了重定向次数太多。。。
    stray_dog:WebMvcConfigurationSupport自动配置失效,都得自己在配置文件中配置,具体表现比如访问不到静态资源(js,css等)了。建议自己写的配置类实现WebMvcConfigurer接口,这个接口的方法都加了jdk1.8的 default方法修饰,不强制实现所有的方法,可以根据实际实现相关的方法。
    咔dua翠嘞:@恒宇少年 okok 我先去瞅瞅
    恒宇少年:@咔dua翠嘞 直接实现它的接口,然后需要配置什么重写方法就可以了,我最新的文章有介绍
  • fb6df8a0a958:jdk1.8中findOne()返回的是Option<Entity> ,不能直接返回实体,需要改为Option<Entity>.get.getXXX()
    8181339ab7d1:我也遇到这个问题啦,确实是这样
    2890825173d7:我也遇到这个问题了 给你个👍
  • d13707a354c7:在loginController中UserEntity userEntity = userJpa.findOne(...);要写成Optional<UserEntity> userEntity = userJpa.findOne(...),后面用userEntity .get()来获取UserEntity实体,这是idea报错,研究了半天才搞懂,希望我的是错的,提出来和你分享一下
    255960569248:@霸王血痕 用java8的新特性 Optional 获取值得时候用userEntity.get().getPwd()
    霸王血痕:@d13707a354c7 你好,你获取实体报错解决了吗?怎么解决的。我现在也是同样的问题。谢谢
  • 1d7dd9d32393:现在可以用druid-spring-boot-starter 来进行配置,直接在配置文件配置,就不用再新建一个bean了
    d4696b38fb9d:@恒宇少年 starter里没有找到
    恒宇少年:@ElliotHolmes 建议使用druid的starter
    d4696b38fb9d:怎样配置druid登录的用户名呢?
  • f82781921e64:为啥我 直接 配置文件里面配置了 jsp视图,controller方法里面也是直接返回的index.但是就是找不到页面啊
    f82781921e64:@恒宇少年 试了n多遍,你的能够直接渲染到jsp视图,我昨天没成功.今天也没改啥,就好了. 可能是idea问题么.
    恒宇少年:@陈易寒 去看看我的源码,检查下你的配置,还有配置是否生效
  • kaws95:设置登录路径不拦截的那个地方,我写了两个路径
    if(request.getRequestURI().equals("/user/login") || request.getRequestURL().equals("/user/ws"))
    为什么/user/ws还是会给我重定向到/user/login呢
  • 7c33ce089512:代码跑通了,public String login(final UserEntity user,HttpServletRequest request){
    提示这个UserEntity需要声明为final。
  • 647643016d13:依赖了jpa sevlet支持 还是 此页面不能正确地重定向

    Firefox 检测到该服务器正在将指向此网址的请求无限循环重定向。
    647643016d13:@YouGuangFu印象中 没解决的了
    YouGuangFu:怎么解决的啊
  • 7ef834625ca1:为什么已经输入了正确的用户名和密码,并且表单的action与LoginController都已经对应,但还是登录不进去?并且也没有其它验证信息,比如登录失败等等。:fearful:
    恒宇少年:@Fengzhi志 这种问题,无非就是配置的问题,还有就是有些地址写错了,比对源码看看吧
    7ef834625ca1:试了很多次,不知道什么原因,坐等大神解答。
    恒宇少年:@Fengzhi志 进群吧
  • 73b3ffd5c08b:你好,我按你操作写的过滤servlet和jsp依赖都有但是仍然出
    This page isn’t working

    localhost redirected you too many times.
    Try clearing your cookies.
    ERR_TOO_MANY_REDIRECTS
    YouGuangFu:请问 解决了吗
    恒宇少年:@小孩卖报 下载源码测试运行
  • 行动的侏儒:你好,恒宇,我出现There was an unexpected error (type=Not Found, status=404).
    /WEB-INF/jsp/index.jsp 错误,配置我检查多次,未发现错误,其他查询数据接口能使用,但返回页面的都会报404
    恒宇少年:@行动的侏儒 没事的
    行动的侏儒:@恒宇少年 找到原因了,代码没问题,是因为我直接运行的Application类,而没有通过plugin启动,谢谢恒宇
    恒宇少年:@行动的侏儒 下载对应jsp文章源码,查看
  • 榕树下野猫:你好,我这里有个问题,就是在添加完jsp和servlet的依赖之后,访问地址127.0.0.1:8080/user/index 的时候,报了下面这个错误:
    Whitelabel Error Page

    This application has no explicit mapping for /error, so you are seeing this as a fallback.

    Wed Nov 22 15:24:24 CST 2017
    There was an unexpected error (type=Not Found, status=404).
    No message available

    在网上没有找到理想的解决办法,所以问下你可曾遇到,该如何解决呢? 谢谢
    小宋_ed76:这里其实有个巨坑,当然我不知道是不是我才疏学浅。我从头到尾的所有操作都是在前一章节的基础上操作的。所以在这章节我沿用了第五章节的代码。报了上面的错误。

    重点来了!重点来了!重点来了!
    把第五章中配置的fastJson的内容干掉,重新访问就ok了!暂时还不知道是为什么,但是这个问题我弄了大半天才折腾出来。
    恒宇少年:@就是一碗粗面_9711 这是页面404,你配置有问题
  • 2d8155720919:你好,如果允许多个路径通过,可以怎么配置了?总不能像上面那样,写一长串去匹配吧?
    恒宇少年:@守望半吊子 调用excludePathPatterns方法,这种设计一般都是成对出现的,存在拦截路径就会存在过滤的路径
    2d8155720919:@恒宇少年 这个是拦截的路径哦,我想知道的是有多个不拦截的路径怎么配置?
    恒宇少年:@守望半吊子 在配置使用拦截器时,addPathPatterns方法可以配置多个拦截路径
  • 08c8aac59b8f:哥们,按你的写法,我这边还是报:此网页包含重定向循环 添加了servlet依赖,但是我不用jsp ,用html,freemarker,不知道为什么
    恒宇少年:@TRY_f43e 你要排除登录地址的拦截,要不就会出现循环
  • 1eff7f40b465:你的README.MD挤到一块了
    恒宇少年:@chen_long 哪个地方
  • 无至:个人建议:能贴代码的就不要贴图片
    恒宇少年:@无至 文章下方有源码下载路径:smile::smile::smile:
  • LumiaKai:恒宇我有个小疑问,在demo中重定向到user/login_view上是在映射地址user/上映射的,应该是无法再次重定向到user/login_view上去吧,理论上mapping就成了/user/user/login_view,我简单尝试了一好像有点问题.
    恒宇少年:@LumiaKai 没事:smile:
    LumiaKai:@恒宇少年 :+1: 见笑了
    恒宇少年:@LumiaKai 你少写一个斜杠,拦截器跳转路径那里

本文标题:第六章:如何在SpringBoot项目中使用拦截器

本文链接:https://www.haomeiwen.com/subject/suqkattx.html