一、为什么要自定义拦截器
在struts2里面有很多拦截器,这些拦截器是struts2封装的功能,但是在实际开发中,struts2里面拦截器中可能没有要使用的功能,这个时候需要自己写拦截器实现功能
二、拦截器的结构
1、源代码看拦截器结构
-
继承类
image.png
image.png -
在接口里面有三个方法
image.png
image.png
image.png
2、开发中写类,继承
- 继承MethodFilterInterceptor:它可以让action里一些方法不进行拦截
3、让拦截器和action有关系
- 不是action调用拦截器的方法,而是通过配置文件方式建立关系
三、自定义登录拦截器
1、需求
在项目中,有许多action的超链接,实现只有是登录的状态,才可以点击action的超链接实现功能,如果不是登录,点击action链接返回登录页面
2、登录状态:session域对象实现
- 登录成功后,把数据放到session里面
- 判断session是否有值,可以知道登录状态
3、实现登录的基本功能
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<div align="center">
<h1>Login</h1>
<h3 style="color: red">${requestScope.msg }</h3>
<form action="${pageContext.request.contextPath }/checklogin" method="post">
username:<input type="text" name="username"/><br><br>
passwork:<input type="password" name="password"/><br><br>
<input type="submit" value="login"/>
</form>
</div>
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<c:if test="${''!=sessionScope.username && null!=sessionScope.username }">
欢迎 ${sessionScope.username }
</c:if>
<c:if test="${''==sessionScope.username || null==sessionScope.username }">
<a href="${pageContext.request.contextPath }/login.jsp"> 您好请登录!</a>
</c:if>
<br>
<a href="${pageContext.request.contextPath }/hehe">点我·····</a>
<br>
<a href="${pageContext.request.contextPath }/haha">点我·····</a>
</body>
</html>
CheckLogin.java
package work.zhangdoudou.Action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import work.zhangdoudou.Bean.UserBean;
public class CheckLogin extends ActionSupport implements ModelDriven<UserBean>{
private UserBean user;
@Override
public String execute() throws Exception {
HttpServletRequest request=ServletActionContext.getRequest();
if ("manman".equals(user.getUsername())&&"520".equals(user.getPassword())) {
// 登录成功
//向session放值
request.getSession().setAttribute("username", user.getUsername());
System.out.println(SUCCESS);
return SUCCESS;
}else{
//登录失败
request.setAttribute("msg", "账号或密码错误!");
System.out.println(ERROR);
return ERROR;
}
}
@Override
public UserBean getModel() {
if (null==user) {
user=new UserBean();
}
return user;
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="false" value="struts.enable.DynamicMethodInvocation"/>
<constant value="true" name="struts.devMode"/>
<package name="default" extends="struts-default" namespace="/">
<!--name:访问名称 -->
<action name="checklogin" method="execute" class="work.zhangdoudou.Action.CheckLogin">
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>struts2.Filter</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4、添加登陆拦截器
(1)判断是否登录:判断session里面是否有username的值
(2)拦截器的实现过程
- 创建一个类,继承MethodFilterInterceptor类
- 重写MethodFilterInterceptor里的方法,写拦截器逻辑
拦截器类Filter.java
package work.zhangdoudou.Filter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.client.Invocation;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class Filter extends MethodFilterInterceptor{
//这个方法里面写拦截器逻辑
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
//判断session是否有username值
//得到session
HttpServletRequest request=ServletActionContext.getRequest();
Object object=request.getSession().getAttribute("username");
//判断
if (null!=object) {
//登陆状态
//做类似于放行操作
return invocation.invoke();
}else{
//不是登陆状态
//不登录不执行action的方法,返回登陆页面
request.setAttribute("msg", "请登录!");
return "error";
}
}
}
(3)配置action和拦截器的关系(注册拦截器)
- 在要拦截的action标签所在的package标签里声明拦截器
- 在具体的action标签里使声明的拦截器
- struts2里面执行很多默认拦截器,但是如果在action里面配置自定义拦截器
问题:默认的拦截器不会执行了
解决:把默认的手动配置一次
特点:配置的拦截器会对action所有方法都会拦截
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="false" value="struts.enable.DynamicMethodInvocation"/>
<constant value="true" name="struts.devMode"/>
<package name="default" extends="struts-default" namespace="/">
<!-- 声明拦截器 -->
<interceptors>
<interceptor name="login" class="work.zhangdoudou.Filter.Filter"></interceptor>
</interceptors>
<!--name:访问名称 -->
<action name="checklogin" method="execute" class="work.zhangdoudou.Action.CheckLogin">
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
<action name="hehe" method="execute" class="work.zhangdoudou.Action.hehe">
<!-- 使用自定义的拦截器 -->
<interceptor-ref name="login"></interceptor-ref>
<!-- 默认拦截器手动使用一次 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</struts>
5、配置拦截器,不要对action的所有方法都进行拦截
- 直接通过配置方式让action里面某些方法不进行拦截
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="false" value="struts.enable.DynamicMethodInvocation"/>
<constant value="true" name="struts.devMode"/>
<package name="default" extends="struts-default" namespace="/">
<!-- 声明拦截器 -->
<interceptors>
<interceptor name="login" class="work.zhangdoudou.Filter.Filter"></interceptor>
</interceptors>
<!--name:访问名称 -->
<action name="checklogin" method="execute" class="work.zhangdoudou.Action.CheckLogin">
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
<action name="hehe" method="execute" class="work.zhangdoudou.Action.hehe">
<!-- 使用自定义的拦截器 -->
<interceptor-ref name="login"></interceptor-ref>
<!-- 默认拦截器手动使用一次 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
<action name="haha" method="haha" class="work.zhangdoudou.Action.hehe">
<!-- 使用自定义的拦截器 -->
<interceptor-ref name="login">
<!-- 配置某些方法不进行拦截 name属性excludeMethods -->
<param name="excludeMethods">haha</param>
</interceptor-ref>
<!-- 默认拦截器手动使用一次 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</struts>
6、实现效果
点击拦截进行登录
image.png
image.png
点击不拦截
image.png
网友评论