拦截器就是过滤器的一种, 拦截器有且只能拦截Controller层(Servlet) ,本文实现一个登录拦截器,没有登录就不能访问登录之后的页面。
源码获取github
Java Web阶段学习过滤器
在web.xml中配置
<filter>
<filter-name>
<filter-class>
<init-param>
filter>
<filter-mapping>
<url-patterns>过滤的路径,我们自己可以设置规则 *.jsp *.html /*url-patterns>
<servlet-name>servlet过滤器名字servlet-name>
filter-mapping>
拦截器 : 理解为 拦截器就是过滤器的一种, 拦截器有且只能拦截Controller层(Servlet) @Controller的注解层次
MyInterceptor.java
package com.hs.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
///一般情况下,我们只是关心preHandle方法即可
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHandle:访问Controller之前执行");
// return false; //阻止访问下一个
return true; //访问下一个拦截器或资源
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle:访问到正确的视图之前");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion:JSP页面加载完毕之后执行");
}
}
在springmvc.xml中加入
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/sys/**"/>
<mvc:mapping path="/vip/**"/>
<mvc:exclude-mapping path="/vip/test02/"/>
<bean class="com.hs.interceptor.MyInterceptor"/>
mvc:interceptor>
mvc:interceptors>
DemoController.java
package com.hs.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class DemoController {
@GetMapping("/sys/test01")
public String test01() {
System.out.println("Controller层test01方法");
return "jsp/result01";
}
@GetMapping("/vip/test02")
public String test02() {
System.out.println("Controller层test02方法");
return "jsp/result02";
}
}
result01.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<% System.out.println("JSP-result01页面");%>
<h2>resulet01.jsph2>
body>
html>
result02.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<% System.out.println("JSP-result02页面");%>
<h2>resulet02.jsph2>
body>
html>
测试,在浏览器网址栏依次输入/sys/test01,/vip/test02,查看控制台输出
<mvc:interceptor>
<mvc:mapping path="/sys/**"/>
<mvc:exclude-mapping path="/sys/login"/>
<bean class="com.hs.interceptor.LoginInterceptor"/>
mvc:interceptor>
package com.hs.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/sys")
public class LoginController {
/**
* 在地址栏输入/sys/login 进行请求转发跳转页面
*
* @return
*/
@GetMapping("/login")
public String login() {
return "jsp/login";
}
/**
* 表单提交验证,存入session
*
* @param account
* @param request
* @return
*/
@PostMapping("/login")
public String login(String account,HttpServletRequest request){
System.out.println(account);
HttpSession session = request.getSession();
if("admin".equals(account)){
session.setAttribute("session_user", account);
//redirect重定向跳到另外一个controller里
return "redirect:/sys/main";
}
return "jsp/login";
}
/**
* 登录成功重定向到这个controller,然后这个controller请求转发到一个页面
* @return
*/
@GetMapping("/main")
public String main(){
return "jsp/result01";
}
}
<form action="login" method="post">
<input type="text" name="account">
<button>登录button>
form>
这里有一个很大的坑,自己纠结了很久,action的路径问题!!!
如果写sys/login是绝对路径,login相对路径,因为请求转发到login.jsp,但是网址栏还是在sys这层,表单提交要到login那个,要不然就用相对路径,要不然就是绝对路径,相对直接login就行,绝对路径就是要这样写
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
//项目的发布路径,例如: /rabc
String path = request.getContextPath();
/*
全路径,形式如下: http://127.0.0.1:8001/rbac/
request.getScheme() ——> http 获取协议
request.getServerName() --> 127.0.0.1 获取服务名
request.getServerPort() --> 8001 获取端口号
path --> /rbac 获取访问的路径 路
*/
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%--
标签解决路径问题
参考文章:http://www.cnblogs.com/muqianying/archive/2012/03/16/2400280.html
--%>
<html>
<head>
<base href="<%=basePath%>">
<meta charset="UTF-8">
<title>title>
head>
<body>
<h2>登录h2>
<%--action的路径问题,sys/login绝对路径,login相对路径,因为请求转发到login.jsp,但是网址栏还是在sys这层,表单提交要到login那个,要不然就用相对路径,要不然就是绝对路径,相对直接login就行,绝对就是这样上面那一大堆--%>
<form action="sys/login" method="post">
<input type="text" name="account">
<button>登录button>
form>
body>
html>
package com.hs.interceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
/**
* 登录拦截器
*/
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.获取HttpSession
HttpSession session = request.getSession();
//2.判断是否登录
if (session.getAttribute("session_user") == null) {
//3.防止浏览器的后退功能
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("");
out.flush();
out.close();
return false;
}
return true;
}
}