简介
- struts2拦截器是在访问某个action方法,字段之前或者之后进行拦截
- struts2拦截器是可以拔插的
- struts2拦截器是AOP的一种实现
例子
login.jsp
<body>
<form action="user" method="post">
用户名:<input type="text" name="user.userName"/>
密码:<input type="text" name="user.password"/>
<input type="submit" value="登录"/>
</form>
</body>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="HelloWorld" extends="struts-default">
<!-- 拦截器配置 -->
<interceptors>
<interceptor name="MyInterceptor" class="com.java.interceptor.MyInterceptor">
</interceptor>
</interceptors>
<action name="user" class="com.java.action.UserAction">
<result name="success">success.jsp</result>
<result name="error">error.jsp</result>
<!-- 引用了MyInterceptor这个拦截器,其他的就不会引用了,所以要自己引用底层原本有的拦截器defaultStack -->
<!-- 先进入MyInterceptor,然后进入defaultStack -->
<interceptor-ref name="MyInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
MyInterceptor.java
package com.java.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("拦截器销毁的时候调用");
}
@Override
public void init() {
// TODO Auto-generated method stub
System.out.println("拦截器初始化时候调用");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("在action之前拦截");
String result = invocation.invoke();//调用内存的方法
System.out.println("result:"+result);
System.out.println("在action之后拦截");
return result;
}
}
Useraction.java
package com.java.action;
import com.java.model.User;
import com.java.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class UserAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private UserService userService=new UserService();
private User user=new User();
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println("执行了UserAction的默认方法");
if(userService.login(user)){
return SUCCESS;
}else{
return ERROR;
}
}
}
UserService.java
package com.java.service;
import com.java.model.User;
public class UserService {
public boolean login(User user){
if("java".equals(user.getUserName())&&"123456".equals(user.getPassword())){
return true;
}else{
return false;
}
}
}
User.java
package com.java.model;
public class User {
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;
}
}
启动tomcat
执行MyInterceptor的 init()初始化方法
public void init() {
System.out.println("拦截器初始化时候调用");
}
然后输入用户名密码进入到执行action之前的拦截器
initial()初始化拦截器
action之前的拦截器interceptor123
执行action、执行execute()、返回result完成action执行
action之后的拦截器interceptor
通过拦截器验证用户是否登陆
修改Useraction.java,每次登陆把用户信息放到session中。
package com.java.action;
import java.util.Map;
import com.java.model.User;
import com.java.service.UserService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class UserAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private UserService userService=new UserService();
private User user=new User();
private String error;//登陆错误信息
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println("执行了UserAction的默认方法");
if(userService.login(user)){
//通过获取actionContext来获取action
ActionContext actionContext = ActionContext.getContext();
//获得session
Map<String, Object> session= actionContext.getSession();
//把user对象放到session中
session.put("curentUser", user);
return SUCCESS;
}else{
this.error="用户名或者密码错误";
return "error";
}
}
}
增加一个YanZhengAction.java,用来验证没登陆时,拦截器是否拦截信息
package com.java.action;
import com.opensymphony.xwork2.ActionSupport;
public class YanZhengAction extends ActionSupport {
private static final long serialVersionUID = 1L;
public String execute() throws Exception {
System.out.println("用户已经登录");
return SUCCESS;
}
}
loginInterceptor.java
用来验证如果想执行yanzheng action,就要登陆才能进入
package com.java.interceptor;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.sun.net.httpserver.HttpServer;
public class loginInterceptor implements Interceptor {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("拦截器销毁的时候调用");
}
@Override
public void init() {
// TODO Auto-generated method stub
System.out.println("拦截器初始化时候调用");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("在进入yanzheg的action之前拦截判断用户是否登陆");
//通过获取actionContext来获取action
ActionContext actionContext = ActionContext.getContext();
//获得session
Map<String, Object> session= actionContext.getSession();
//获取登陆对象,判断是否用户登陆
Object curentUser = session.get("curentUser");
String result =null;
if(curentUser!=null){
result = invocation.invoke();//调用result结果,
//invocation.invoke() 就是通知struts2接着干下面的事情
//比如 调用下一个拦截器 或 执行下一个Action
//就等于退出了你自己编写的这个拦截器loginInterceptor了
System.out.println(result);
}else{
//获取request
HttpServletRequest request = (HttpServletRequest) invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
request.setAttribute("error", "请先登录");
System.out.println("这逼没登陆就想进来");
result = "error";
}
return result;
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="HelloWorld" extends="struts-default">
<!-- 拦截器配置 -->
<interceptors>
<interceptor name="MyInterceptor" class="com.java.interceptor.MyInterceptor"></interceptor>
<interceptor name="loginInterceptor" class="com.java.interceptor.loginInterceptor"></interceptor>
</interceptors>
<action name="user" class="com.java.action.UserAction">
<result name="success">success.jsp</result>
<result name="error">error.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<action name="yanzheng" class="com.java.action.YanZhengAction">
<result name="success">success.jsp</result>
<result name="error">error.jsp</result>
<!-- 想进入这个action就要验证是否登陆,如果没有登陆,是进不去的 -->
<interceptor-ref name="loginInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
验证:没登陆时,执行yanzheng action ,看看结果
结果:
后台:
登陆之后:
结果:
最后优化一下struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="HelloWorld" extends="struts-default">
<!-- 拦截器配置 -->
<interceptors>
<interceptor name="MyInterceptor" class="com.java.interceptor.MyInterceptor"></interceptor>
<interceptor name="loginInterceptor" class="com.java.interceptor.loginInterceptor"></interceptor>
<!-- 优化二:拦截器栈 -->
<interceptor-stack name="MyStack">
<interceptor-ref name="loginInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 使得HelloWorld这个包中每个action都使用拦截器栈 MyStack-->
<default-interceptor-ref name="MyStack"></default-interceptor-ref>
<!--优化一:每个action都有<result name="error">,所以放到全局的配置中-->
<global-results>
<result name="error">error.jsp</result>
</global-results>
<action name="user" class="com.java.action.UserAction">
<result name="success">success.jsp</result>
<!-- 登陆不需要使用loginInterceptor,所一就不需要MyStack -->
<!-- 所以使用defaultStack就不会去使用MyStack -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<action name="yanzheng" class="com.java.action.YanZhengAction">
<result name="success">success.jsp</result>
</action>
</package>
</struts>