一,为什么需要拦截器?
早期MVC框架将一些通用操作写死在核心控制器中,致使框架灵活性不足、可扩展性降低 Struts 2将核心功能放到多个拦截器中实现,拦截器可自由选择和组合,增强了灵活性,有利于系统的解耦
二,什么是拦截器?
拦截对Action请求的一个类。
实现Interceptor接口。继承AbstractInterceptor类
Struts 2大多数核心功能是通过拦截器实现的,每个拦截器完成某项功能
拦截器方法在Action执行之前或者之后执行
三,拦截器工作原理?
拦截器的执行过程是一个递归的过程
三阶段执行周期:
1、做一些Action执行前的预处理
2、将控制交给后续拦截器或返回结果字符串
3、做一些Action执行后的处理
四,Struts2 拦截器接口实现?
Struts2规定用户自定义拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口声明了3个方法,其中,init和destroy方法会在程序开始和结束时各执行一遍,不管使用了该拦截器与否,只要在struts.xml中声明了该Struts2拦截器就会被执行。intercept方法就是拦截的主体了,每次拦截器生效时都会执行其中的逻辑。
void init();
void destroy();
String intercept(ActionInvocation invocation) throws Exception;
1:所有拦截器都使用接口Interceptor ,Action去实现这个接口;
Init()方法:在服务器起动的时候加载一次,并且只加载一次;
Destroy()方法:当拦截器销毁时执行的方法;
Interceptor()方法:其中里边有一个参数invocation;
public String intercept(ActionInvocation invocation) throws xception {
System.out.println("interceptor!!");
String result=invocation.invoke();
return result;
}
其中intercept方法是拦截器的核心方法,所有安装的拦截器都会调用之个方法。在Struts2中已经在struts-default.xml中预定义了一些自带的拦截器,如timer、params等。如果在<package>标签中继承struts-default,则当前package就会自动拥有struts-default.xml中的所有配置。
Invocation.invoke()是如果只有一个拦截器执行完这个方法后,会返回给视图,如果有多个拦截器,它顺序的执行完所有的拦截器,才返回给视图,也就是调用后面的action继续执行。
五,Demo
1,创建实体类UserInfo
public class UserInfo { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
2,创建一个名称为LoginAction的类
public class LoginAction implements Action{ private UserInfo user=new UserInfo(); public String execute() throws Exception { System.out.println(user.getUsername()+"======user====="+user.getPassword()); Map<String,Object> session= ActionContext.getContext().getSession(); //如果你的用户名和密码都是admin,return success.反之,走到login if(user!=null){ if(user.getUsername().equals("1")&&user.getPassword().equals("1")){ System.out.println("===================="); //省略一个步骤,记录session session.put("username",user.getUsername()); return SUCCESS; }else { return LOGIN; } }else{ //不是登陆界面过来的 if(session!=null&&session.get("username")!=null){ return "success"; }else{ System.out.println("Action中的自定义代码"); return "login"; } } } public UserInfo getUser() { return user; } public void setUser(UserInfo user) { this.user = user; } }
3,设置自己的Interceptor进行拦截
public class MyInterceptor implements Interceptor { public void destroy() { } public void init() { } //ActionInvocation具备Action的执行权 public String intercept(ActionInvocation actionInvocation) throws Exception { System.out.println("对象"+actionInvocation); //Action是谁 Object action=actionInvocation.getAction(); System.out.println("action================"+action); String value; //将来对应的逻辑视图名 //判定session里面的key值对应的value是否存在 Map<String,Object> session= ActionContext.getContext().getSession(); //断定到底现在session中有没有uname这个key Object name=session.get("username"); String actionName=actionInvocation.getProxy().getActionName(); actionInvocation.getProxy().getNamespace();//user System.out.println(name+"=====name"); System.out.println("actionName======"+actionName); if(actionName.equals("loginInterceptor")) { System.out.println("=========Action是Login"); //user/login.Action value=actionInvocation.invoke(); }else if(name!=null){ //已经登陆了,,放行 让请求继续流转到下一个拦截器 或者是最终的请求处理管,action value =actionInvocation.invoke(); String method=actionInvocation.getProxy().getMethod(); System.out.println("方法"+method); }else{ //走到这个else,证明你访问的Action,既不是登陆,也不是被授权的操作 value="login"; } System.out.println("逻辑视图名"+value); return value; } }
4,配置struts.xml
<struts> <constant name="struts.devMode" value="true"/> <package name="Interceptoraction" namespace="/" extends="default"> <interceptors> <interceptor name="myInter" class="cn.happy.controller.Interceptor.MyInterceptor"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="myInter"></interceptor-ref> </interceptor-stack> </interceptors> <action name="loginInterceptor" class="cn.happy.controller.Interceptor.LoginAction"> <result name="success">/day01/success.jsp</result> <result name="login">/day01/login.jsp</result> </action> </package> </struts>
5,配置login.jsp页面
<%@taglib prefix="s" uri="/struts-tags" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <s:debug/> <s:form name="form1" namespace="/" method="post" action="loginInterceptor"> 请输入用户名:</br> <s:textfield name="user.username"/> 请输入密码:<s:password name="user.password"/> <s:submit value="登陆"></s:submit> </s:form> </body> </html>