Struct2_定义拦截器并使用注解方式作用在Action的方法中
一、目的:通过在方法上加注解控制哪些方法需要登陆后才能访问
二、方式:利用拦截器判断用户是否登陆
三、实现步骤
- 定义配置文件
struts.xml添加节点
1234567891011121314151617181920<packagename="custom-default"extends="struts-default"><interceptors><!-- 声明自定义的权限控制拦截器 --><interceptorname="loginInterceptor"class="interceptors.LoginInterceptor"/><!-- 把自定义的权限控制拦截器和默认的拦截器栈加到新的自定义的拦截器栈 --><interceptor-stackname="myInterceptors"><interceptor-refname="loginInterceptor"/><interceptor-refname="defaultStack"/></interceptor-stack></interceptors><!-- 指定新的自定义的拦截器栈为默认的拦截器栈,这样自定义的权限控制拦截器就可以发挥作用了 --><!-- 这里name属性值对应的是上述interceptor-stack name属性值 --><default-interceptor-refname="myInterceptors"></default-interceptor-ref><!-- 这里对应拦截器中return Action.LOGIN对应的页面--><global-results><resultname="login">/WEB-INF/content/LoginInfo/login.jsp</result></global-results></package> -
定义注解
注解主要是作用在方法上,拦截器根据方法是否定义注解来处理登陆判断
123456789101112131415packageannotations;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target({ElementType.METHOD})@Retention(value = RetentionPolicy.RUNTIME)public@interfaceAuthority {/*** @return The namespace value.*/String value();} -
定义拦截器
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748packageinterceptors;importjava.lang.reflect.Method;importjava.util.Map;importorg.apache.struts2.convention.annotation.InterceptorRef;importcom.opensymphony.xwork2.Action;importcom.opensymphony.xwork2.ActionContext;importcom.opensymphony.xwork2.ActionInvocation;importcom.opensymphony.xwork2.interceptor.AbstractInterceptor;importannotations.Authority;importcommon.Constants;@SuppressWarnings("serial")publicclassLoginInterceptorextendsAbstractInterceptor {@OverridepublicString intercept(ActionInvocation invocation)throwsException {String methodName = invocation.getProxy().getMethod();Class clazz = invocation.getAction().getClass();// 获取类对象Method currentMethod = clazz.getMethod(methodName);//获取拦截的方法//方法上添加了注解if(currentMethod.isAnnotationPresent(Authority.class)) {// 取得当前请求的注解的actionActionContext context = invocation.getInvocationContext();Map session = context.getSession();//Constants.UserName=="UserName"String user = (String) session.get(Constants.UserName);System.err.println("拦截器起作用");if(user ==null)// 未登陆,跳转到登录页{System.err.println("进入拦截器:未登陆");context.put("tip","你还没有登录");returnAction.LOGIN;}else{//已登录,继续后续流程System.err.println("进入拦截器:已登录");returninvocation.invoke();}}else{System.err.println("进入拦截器:没有使用注解");returninvocation.invoke();}}} - 定义Action类及方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package action;import org.apache.struts2.convention.annotation.Action;import org.apache.struts2.convention.annotation.InterceptorRef;import org.apache.struts2.convention.annotation.Namespace;import org.apache.struts2.convention.annotation.ParentPackage;import org.apache.struts2.convention.annotation.Result;import org.apache.struts2.convention.annotation.Results;import org.apache.struts2.interceptor.validation.SkipValidation;import annotations.Authority;import common.Constants;import org.apache.struts2.convention.annotation.InterceptorRefs;@SuppressWarnings("serial")@ParentPackage("custom-default") //这里对应的配置文件中包的名称public class LoginAction extends SuperActionSupport { @Action(value = "loginValidate", results = { @Result(name = "success", location = "/WEB-INF/content/LoginInfo/success.jsp"), @Result(name = "input", location = "/WEB-INF/content/LoginInfo/login.jsp") }) @Authority("") //定义注解后未登录回到登陆页,否则执行后续步骤 public String loginValidate() throws Exception { return SUCCESS; }} |
四、实现过程中遇到的坑
-
内置的注解@InterceptorRefs/@InterceptorRef只能作用在类文件上,不能作用到方法上(从其@Target属性即可看出)
-
类上的注解@ParentPackage("custom-default")必须对应structs.xml中package的name属性,否则注解不起效
-
structs.xml中default-interceptor-ref的name值对应的是interceptor-stack的name值,否则注解不起效
五、参考资料

浙公网安备 33010602011771号