springMVC中Interceptor拦截器的使用
1.环境配置
首先,这是在所有SSM环境都部署好的情况下操作:
1.在springMVC的配置文件spring-servlet.xml中配置自动扫描的包(为了使用springMVC注解)
<context:component-scan base-package="controller"/>
2.在web.xml中配置拦截对象 <servlet-mapping> <servlet-name>spring</servlet-name>
<url-pattern>/back/*.do</url-pattern>
</servlet-mapping> 这里会拦截所有back为前缀,do为后缀的请求 2.前端页面 1.编写index.jsp前端代码 <p><a href="login.html">登录</a></p> <p><a href="user/home.html">用户中心</a></p> (请求为.do后缀) 2.编写login.jsp登录页面(提交到dologin.html),userhome.jsp用户中心界面(用于测试权限) <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!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>admin</title> </head> <body>
<form action="${pageContext.request.contextPath}/checkAdmin.do" method="post"> <table> <tr><td>用户名</td><td><input type="text" name="userName"/></td></tr> <tr><td>密码</td><td><input type="password" name="userPwd"></td></tr> <tr><td colspan="2"><input type="submit" value="登录"></td></tr> </table> </form>
</body> </html> 3.Interceptor类 package interceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import model.Admin; //拦截器 public class AuthorizationInterceptor implements HandlerInterceptor { //不拦截的页面 private static final String[] IGNORE_URI={"/adminPage","/uploadPage"}; //填写XX.do
/** * 请求之后执行,用于清理资源 * 在Interceptor的preHandle返回为true时执行 */ @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("方法AuthorizationInterceptor afterCompletion()"); } /** * Controller调用之后执行,可对ModelAndView操作 * 当Interceptor的preHandle返回为true时执行 */ @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("方法AuthorizationInterceptor postHandle()"); } /** * preHandle拦截使用,在controller执行之前 * 返回值为true才会向下执行,false的话请求就结束 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { System.out.println("方法AuthorizationInterceptor preHandle()"); boolean flag=false; //用于存储判断登录的结果 //对请求路径进行判断 String servletPath=request.getServletPath(); //判断请求是否需要拦截 for(String s:IGNORE_URI){ if(servletPath.contains(s)){ flag=true; //如果是不拦截的网站,flag为true,跳出循环,转向下个方法 break; } } //拦截请求 if(!flag){ //如果是非公开的页面↓ Admin admin=(Admin)request.getSession().getAttribute("ADMIN"); if(admin==null){ System.out.println("AuthorizationInterceptor拦截请求"); request.setAttribute("message", "请先登录管理员后再访问网站"); request.getRequestDispatcher("/error.jsp").forward(request, response); }else{ //用户登陆过,验证通过,放行 System.out.println("AuthorizationInterceptor放行请求"); flag=true; } }
return flag; }
}
4.运行测试 到这里环境的配置和代码的准备就完成了。用户点击前端页面的登录按钮之后,就会执行checkAdmin.do。(因为web.xml配置的拦截为/back/*,所以该请求不会被拦截),验证通过的话,页面会跳转到用户管理页,用户名会存入session。 验证用户的代码: @RequestMapping("/checkAdmin.do") public void checkAdmin(Admin admin,HttpSession session,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ System.out.println("进入了checkAmin的controller方法"); String path="/error.jsp"; if(adminDAO.checkAdmin(admin)){ session.setAttribute("ADMIN",Global.ADMIN); //将整个对象存入ADMIN的session中 path="/back/index.do"; //通过.do跳转才能发挥拦截器 } request.getRequestDispatcher(path).forward(request, response); } 这里就要提到拦截器的作用了,当用户没有登录(session没存入用户名),直接用/back/index.do访问用户管理页时,Interceptor就会先判断该页面是否是权限页面,是的话进一步判断用户是否已经存入session。如果没有存入,跳转到error页面。有存入session用户名则返回true放行。
这里有两个注意点: 1.有权限限制的XX.jsp页面的文件名不允许在前端代码出现,否者会被用户绕过X.do的拦截。如果非要在前端展示跳转链接,因使用*.do调用,在后台进行跳转: <a href="${pageContext.request.contextPath}/back/uploadPage.do">上传页面</a> 专门写一个controller方法进行跳转: /** * 跳转到上传页面 * @param request * @param response */ @RequestMapping("/back/uploadPage.do") public void toPlayUpload(HttpServletRequest request,HttpServletResponse response){ try { request.getRequestDispatcher("/admin/yuleruanjianUpload.jsp").forward(request, response); } catch (ServletException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 2.当我们把信息存入session中的时候,使用一个类进行静态常量的管理 package constan; //这个类用来放置全局常量 public class Global { public static final String ADMIN="ADMIN"; //存储管理员对象
} 使用以下方式存入: session.setAttribute(Global.ADMIN,admin); //将整个对象存入ADMIN的session中
2.在web.xml中配置拦截对象 <servlet-mapping> <servlet-name>spring</servlet-name>
<url-pattern>/back/*.do</url-pattern>
</servlet-mapping> 这里会拦截所有back为前缀,do为后缀的请求 2.前端页面 1.编写index.jsp前端代码 <p><a href="login.html">登录</a></p> <p><a href="user/home.html">用户中心</a></p> (请求为.do后缀) 2.编写login.jsp登录页面(提交到dologin.html),userhome.jsp用户中心界面(用于测试权限) <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!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>admin</title> </head> <body>
<form action="${pageContext.request.contextPath}/checkAdmin.do" method="post"> <table> <tr><td>用户名</td><td><input type="text" name="userName"/></td></tr> <tr><td>密码</td><td><input type="password" name="userPwd"></td></tr> <tr><td colspan="2"><input type="submit" value="登录"></td></tr> </table> </form>
</body> </html> 3.Interceptor类 package interceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import model.Admin; //拦截器 public class AuthorizationInterceptor implements HandlerInterceptor { //不拦截的页面 private static final String[] IGNORE_URI={"/adminPage","/uploadPage"}; //填写XX.do
/** * 请求之后执行,用于清理资源 * 在Interceptor的preHandle返回为true时执行 */ @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("方法AuthorizationInterceptor afterCompletion()"); } /** * Controller调用之后执行,可对ModelAndView操作 * 当Interceptor的preHandle返回为true时执行 */ @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("方法AuthorizationInterceptor postHandle()"); } /** * preHandle拦截使用,在controller执行之前 * 返回值为true才会向下执行,false的话请求就结束 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { System.out.println("方法AuthorizationInterceptor preHandle()"); boolean flag=false; //用于存储判断登录的结果 //对请求路径进行判断 String servletPath=request.getServletPath(); //判断请求是否需要拦截 for(String s:IGNORE_URI){ if(servletPath.contains(s)){ flag=true; //如果是不拦截的网站,flag为true,跳出循环,转向下个方法 break; } } //拦截请求 if(!flag){ //如果是非公开的页面↓ Admin admin=(Admin)request.getSession().getAttribute("ADMIN"); if(admin==null){ System.out.println("AuthorizationInterceptor拦截请求"); request.setAttribute("message", "请先登录管理员后再访问网站"); request.getRequestDispatcher("/error.jsp").forward(request, response); }else{ //用户登陆过,验证通过,放行 System.out.println("AuthorizationInterceptor放行请求"); flag=true; } }
return flag; }
}
4.运行测试 到这里环境的配置和代码的准备就完成了。用户点击前端页面的登录按钮之后,就会执行checkAdmin.do。(因为web.xml配置的拦截为/back/*,所以该请求不会被拦截),验证通过的话,页面会跳转到用户管理页,用户名会存入session。 验证用户的代码: @RequestMapping("/checkAdmin.do") public void checkAdmin(Admin admin,HttpSession session,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ System.out.println("进入了checkAmin的controller方法"); String path="/error.jsp"; if(adminDAO.checkAdmin(admin)){ session.setAttribute("ADMIN",Global.ADMIN); //将整个对象存入ADMIN的session中 path="/back/index.do"; //通过.do跳转才能发挥拦截器 } request.getRequestDispatcher(path).forward(request, response); } 这里就要提到拦截器的作用了,当用户没有登录(session没存入用户名),直接用/back/index.do访问用户管理页时,Interceptor就会先判断该页面是否是权限页面,是的话进一步判断用户是否已经存入session。如果没有存入,跳转到error页面。有存入session用户名则返回true放行。
这里有两个注意点: 1.有权限限制的XX.jsp页面的文件名不允许在前端代码出现,否者会被用户绕过X.do的拦截。如果非要在前端展示跳转链接,因使用*.do调用,在后台进行跳转: <a href="${pageContext.request.contextPath}/back/uploadPage.do">上传页面</a> 专门写一个controller方法进行跳转: /** * 跳转到上传页面 * @param request * @param response */ @RequestMapping("/back/uploadPage.do") public void toPlayUpload(HttpServletRequest request,HttpServletResponse response){ try { request.getRequestDispatcher("/admin/yuleruanjianUpload.jsp").forward(request, response); } catch (ServletException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 2.当我们把信息存入session中的时候,使用一个类进行静态常量的管理 package constan; //这个类用来放置全局常量 public class Global { public static final String ADMIN="ADMIN"; //存储管理员对象
} 使用以下方式存入: session.setAttribute(Global.ADMIN,admin); //将整个对象存入ADMIN的session中
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。