1,自定义拦截器的实现步骤
1,定义拦截器需要完成的功能。
当用户已经登录的时候,拦截器让用户可以访问action,当用户没有登录的时候,则提示用户无法访问action。
实现该功能,首先制作一个简单的登录系统。
通过login.jsp,quit.jsp分别实现用户登录和退出。
login.jsp就是在session中添加一个user属性,而quit.jsp则是在移除user属性。因为拦截器要实现对action的访问控制。
所以这两个jsp,我们都定义在浏览器可以直接访问的位置,这里为webContent的目录下。
login.jsp内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
用户登录
<% pageContext.getSession().setAttribute("user", "dzr"); %>
用户已登录
quit.jsp的内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
<% pageContext.getSession().removeAttribute("user"); %>
用户退出登录!
2, 创建拦截器类。
拦截器类需要实现拦截器的接口。该接口为com.opensymphony.xwork2.interceptor.Interceptor。
我在src目录下创建这个拦截器。
package cn.dzr.interceptor;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class PermissionInterceptor implements Interceptor
{
@Override
public void destroy()
{
// TODO Auto-generated method stub
}
@Override
public void init()
{
// TODO Auto-generated method stub
}
@Override
public String intercept(ActionInvocation invocation) throws Exception
{
//该拦截器实现功能:用户登录,可以访问,用户未登录,禁止访问!
//所以,我们需要获取session中的参数
String user = (String)ServletActionContext.getRequest().getSession().getAttribute("user");
if(user!=null)
{
//表示用户可以登录,则能够访问拦截器
return invocation.invoke();
}
else
{
//用户未登录,则通过unsuccess Action访问一个页面。
ActionContext.getContext().getApplication().put("message", "您没有登录,无法访问本网站");
return "unsuccess";
}
}
}
3, 设置一系列的action,用于验证拦截器的功能!!!先创建Action类。
package cn.dzr.action;
public class InterceptorTestAction
{
private String message;
public String getMessage()
{
return this.message;
}
public String execute()
{
this.message = "execute";
//返回值为"success",表示执行对应的result。
return "success";
}
//通过给message设置不同的值,让页面显示内容不相同。
public String execute2()
{
this.message = "execute2";
//返回值为"success",表示执行对应的result。
return "success";
}
}
4, 完成struts.xml文件的配置。
/WEB-INF/page/message.jsp
5, 定义message.jsp如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Action访问页面
欢迎 ${user }访问
${message }
6,完成错误页面的配置。
/WEB-INF/page/nouser.jsp
这里未定义action中的class ,method 以及result中的name,则都是以默认值来完成访问。
7, 接着配置拦截器。
在struts.xml中进行如上的配置,则拦截器就设置完毕。
如果想试用拦截器,就可以在对应的action中添加该拦截器。但是一旦在action中使用了我们这个自定义的拦截器,那么系统其他默认的拦截器
就无法使用了。通常情况下,我们会创建一个拦截器栈,将默认的拦截器和我们自定义的拦截器放在一起。然后再将此拦截器栈做为系统action的
拦截器。
如下所示:
我们在这里就创建了一个名为permissionstack的拦截器栈。
8, 在我们的action中,添加进去该拦截器栈。
这个时候,我们的功能就实现了。下面检测一下,代码是否可以顺利执行!!
9,结果提示如下的错误:
SEVERE: 元素类型 "interceptor" 必须后跟属性规范 ">" 或 "/>"。 at (null:15:17)
org.xml.sax.SAXParseException; systemId:
file:/D:/apache-tomcat-7.0.42/webapps/struts/WEB-INF/classes/struts.xml;
lineNumber: 15; columnNumber: 17; 元素类型 "interceptor" 必须后跟属性规范 ">" 或 "/>"。
我不知道那一段代码怎么弄成这样,可能是我操作不当。
稍微进行下修改:
结果出现这样的错误提示:
九月 18, 2013 12:37:15 上午 org.apache.struts2.dispatcher.Dispatcher error
SEVERE: Dispatcher initialization failed
Unable to load configuration. - file:/D:/apache-tomcat-7.0.42/webapps/struts/WEB-INF/classes/struts.xml:15:17
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:70)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:446)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:490)
大概都是因为上面的错误导致的,令我不解的一个地方是。
file:/D:/apache-tomcat-7.0.42/webapps/struts/WEB-INF/classes/struts.xml:
而我是讲struts.xml放在src下,看来应该是src目录下的东西,一旦进行部署之后,就会存在于classes目录下。
9, 修改之后,我能够正常打开login.jsp.
http://localhost:8080/struts/test/ac_excute
当我试图通过如上的代码进行action访问的时候,出现了错误。
Struts has detected an unhandled exception:
Messages: cn.dzr.action.InterceptorTestAction.excute()
File: java/lang/Class.java
Line number: 1,624
--------------------------------------------------------------------------------
Stacktraces
java.lang.NoSuchMethodException: cn.dzr.action.InterceptorTestAction.excute()
java.lang.Class.getMethod(Class.java:1624)
我发现是excute这个方法,在我的action中是不存在的。
http://localhost:8080/struts/test/ac_execute
通过该路径和
http://localhost:8080/struts/test/ac_execute2
都可以正常访问。
接着就试下退出之后,是否能够正常的输出信息。
http://localhost:8080/struts/quit.jsp
执行完 该页面后,再去访问
http://localhost:8080/struts/test/ac_execute2
结果并不理想,拦截器并没有起到作用,程序照旧显示。并没有跳转到nouser.jsp页面。
首先检查struts.xml
/WEB-INF/page/nouser.jsp
里的配置应该没有问题。
然后再看拦截器类。
我也没有看到问题,我想在拦截器类中加入一条输出语句,看看执行情况。
这个时候,发现了几个错误。
Caught Exception while registering Interceptor class cn.itcast.interceptor.PermissionInterceptor - interceptor
- file:/D:/apache-tomcat-7.0.42/webapps/struts/WEB-INF/classes/struts.xml:15:88
at org.apache.struts2.impl.StrutsObjectFactory.buildInterceptor(StrutsObjectFactory.java:77)
Caused by: java.lang.ClassNotFoundException: cn.itcast.interceptor.PermissionInterceptor
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
看来是注册拦截器的时候出现的错误。
经过仔细观察,我发现我这里cn.itcast.interceptor.PermissionInterceptor
这个itcast是我从其它地方复制过来的,肯定有问题,因为我的拦截器类定义的包为cn.dzr.interceptor
对此进行修改,再次进行检测。
结果在用户登录成功之后
Struts Problem Report
Struts has detected an unhandled exception:
Messages: No result defined for action cn.dzr.action.InterceptorTestAction and result unsuccess
提示如上的错误,而且在控制台上打印
user == null
拦截器貌似已经运行,但是存在错误。
而且在已经登录的情况下,拦截器打印出user == null 的信息。
这说明拦截器本身也存在问题。
/WEB-INF/page/nouser.jsp
而例外一个问题则是拦截器中的return 貌似是跳到一个result中,而不是跳到一个action中。
但是这里我定义的却是一个name为unsuccess的action类。
但是我想先解决这里为何提示用户未登录的问题。
但是当我在傲游浏览器打开的时候,这里就是提示正确。我真的对这种问题很无语。
接下来,就解决用户未登录的问题。
我想必须明白拦截器的返回值到底是什么意思。
当然,根据上面的内容,拦截器返回的字符串值,应该是一个result的值。如今,我在全局result中,再添加一个name="unsuccess"的
result试试看。
/WEB-INF/page/message.jsp
/WEB-INF/page/nouser.jsp
我们不能定义两个全局的 results,但是能在一个全局result中定义多个result。
结果一切正常。