SpringMVC之拦截器实现登录验证
今天回头看之前发的javaweb学习路线图,发现把路线图中的也学的有一半多了,不过还是路漫漫。在前面的博客中有学习过spring的aop,它利用动态代理实现,在springmvc中也是一样,今天使用HandlerInterceptor来实现登录权限验证。我们平时在做系统时有些页面是需要先登录才能访问的,一种方法是在每个请求方法中都做登录判断,这样顶多是把登录功能封装起来,以后没新增一个代码都要加上,这样很不方便。其实这里我们可以使用拦截器进行登录验证,判断是否有session,如果有session就断定已经登录。拦截器不仅仅可以做登录,它做登录完成之后可能还有根据用户角色限制页面或工具的权限,我们还可以再增加一个拦截器,来判断用户权限等。还可以使用它做防盗链,这个防盗链的之前博客中也有类似的实现,今天就只演示下登录。
一、创建控制器
1.这里创建了LoginIntercepter类实现HandlerInterceptor来创建控制器.HandlerInterceptor它有3个方法,preHandle,postHandle,afterCompletion,3个方法在之前学习springmvc工作流程的时候也有介绍。我们做登录验证主要是在preHandle方法中来做校验。这里判断是不是登录页面,登录页面不能被拦截,不然它始终登录不上.然后判断是否有session,如果有则当做登录成功,没有则跳转到登录页面.

package com.cyw.web.Intercepter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginIntercepter implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub String requestURI = request.getRequestURI(); if(requestURI.indexOf("/login")<=0){ //说明处在编辑的页面 HttpSession session = request.getSession(); String username = (String) session.getAttribute("username"); if(username!=null){ //登陆成功的用户 return true; }else{ //没有登陆,转向登陆界面 request.getRequestDispatcher("../view/Login.jsp").forward(request,response); // response.sendRedirect("../login/login.action"); return false; } }else{ return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }
2.拦截器配置 在spring-mvc.xml中进行配置

<mvc:interceptors> <mvc:interceptor><mvc:mapping path="/**"/><bean class="com.cyw.web.Intercepter.LoginIntercepter"/></mvc:interceptor> <mvc:interceptor><mvc:mapping path="/**"/><bean class="com.cyw.web.Intercepter.LoginWebRequestInterceptor"/></mvc:interceptor> </mvc:interceptors>
这里配置了两个拦截器,LoginWebRequestInterceptor这个也是一拦截器.
二、创建jsp页面
这里创建了一个login.jsp的登录页面.

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <form action="../login/login.action" method="post"> 姓名:<input type="text" name="username"> <br><br> 密码: <input type="text" name="password"> <br><br> <input type="submit" value="登陆"> </form> </body> </html>
三、创建LoginController
这里创建了LoginController用来接收登录的post请求.

package com.cyw.web.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/login") public class LoginController { @RequestMapping(value = "/login.action",method = RequestMethod.GET) public ModelAndView login(HttpServletRequest request,HttpServletResponse response){ ModelAndView modelAndView = new ModelAndView("Login"); return modelAndView; } @RequestMapping(value = "login.action",method = RequestMethod.POST) public String clientLogin(HttpServletRequest request,HttpServletResponse response){ String username=request.getParameter("username"); String password=request.getParameter("password"); if(username.equals("cuiyw")&&password.equals("123456")){ //登陆成功 request.getSession().setAttribute("username",username); return "forward:/hello/testModelAndView"; }else{ //登陆失败 return "forward:/login/login.action"; } } }
但是上面的代码就会出现问题HTTP Status 405 – Method Not Allowed ,Request method 'POST' not supported。
为什么会出现这个错误呢?我开始以为是LoginController中的@RequestMapping配置有问题,但找了好久也没找到,而且再次输入页面时显示的是登录成功的,意思是session也是设置上的,抱着尝试的心态把return中的forward改成redirect,没想到成功了。这就尴尬了,这就涉及到forward与redirect的区别。
四、forward与redirect的区别
forward过程
转发,服务器端行为。web服务器把接受的请求,调用内部的方法在容器内部完成请求处理和转发动作,然后响应客户端,在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。
redirect过程
重定向,客户端行为。客户端发送http请求,web服务器接受后发送3**状态码响应及对应新的location给客客户端,客户端发现是3**响应,则自动再发送一个新的http请求,请求url是新的location地址,在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。重定向行为是浏览器做了至少两次的访问请求。
五、问题原因
上面的forward与redirect的区别也有介绍它们两个的区别,forward用的还是同一个请求,只是把这个请求转给另一个方法处理,redirect是响应给客户端3开头的状态码,然后客户端再次请求,这里我们登录的是post请求,而/hello/testModelAndView对应的testModelAndView方法设置的method = RequestMethod.GET,就没有post,所以报405的错误。
六、WebRequestInterceptor拦截器
springmvc中还可以使用WebRequestInterceptor来做拦截器,用法和HandlerInterceptor差不多,也是现实WebRequestInterceptor,然后重写父类的方法,配置到spring-mvc.xml中。实现的方法名是一样的,只是HandlerInterceptor中使用的HttpServletRequest,WebRequestInterceptor中使用的是WebRequest.
七.小结
其实原本不打算写拦截器呢,因为springmvc的参数传递还没写完,所以下篇还是要接着写参数传递,json与Controller的交互.
作者:社会主义接班人
出处:http://www.cnblogs.com/5ishare/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?