在web开发中,碰到了这样一种情况,输入用户密码登录成功跳转到主页面,我将主页面的访问链接复制,打开新的浏览器窗口,直接粘贴复制的地址,此时会发现没有经过登录直接进入了主页面。那么,我们该如何结果这种问题?在struts2框架中采用了拦截器解决了该问题,拦截器其实就相当于一个代理类,它的功能是在不改变原有业务类的基础上,使用代理模式结合现有的业务类增强业务功能。如下图所示,当我们提交请求时,请求会经过层层的拦截器之后,才会执行Action中的动作。
通过一个示例演示如何使用自定义拦截器:
案例实例:用户通过登录之后才能看到数据库中已有的 用户列表,但是没有经过登录窗口,即使用户记下了登录成功后用户列表的链接,也无法直接访问用户的信息,此时会跳转到登录页面先让用户登录。
①新建项目InterceptorDemo并配置struts2环境;
②编写用户信息的实体类Userinfo(包含三个字段userId,userName,userPass)并产生相应的get和set方法;
③创建UserAction类,在该类中判断用户登录的信息是否正确并且用户信息存储到session中;
public class UserAction extends ActionSupport implements SessionAware{
//由于要在用户列表中获得用户的信息,这个需要获得用户的信息,封装在Userinfo类中
private Userinfo user;
private Map session;
public Userinfo getUser() {
return user;
}
public void setUser(Userinfo user) {
this.user = user;
}
@Override
public String execute() throws Exception {
//这里假设我们登陆成功的用户名为amdin/admin
if("admin".equals(user.getUserName()) &&
"admin".equals(user.getUserPass())) {
session.put("userinfo", user); //我们将用户登录的信息包装到session对象中
return this.SUCCESS;
}
return this.LOGIN;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
}
④在配置文件中配置Action的信息
<!-- 配置UserAction的信息 -->
<action name="user" class="com.xiyou.jackielin.action.UserAction">
<span style="white-space:pre"> </span><!-- 配置成功根节点的信息,登陆成功跳转到listAction中 -->
<result name="success" type="redirectAction">list</result>
<result name="login">/login.jsp</result>
</action>
⑤编写用户登录成功跳转的ListAction,得到用户的信息之后并跳转到用户页面;
public class ListAction extends ActionSupport implements ServletRequestAware{
private static final long serialVersionUID = 1L;
//将用户列表的信息发送到页面中
private HttpServletRequest request ;
@Override
public String execute() throws Exception {
List<Userinfo> list = new ArrayList<Userinfo>();
//这里直接写入测试的数据
for(int i=1;i<10;i++){
Userinfo user = new Userinfo();
user.setUserId(i);
user.setUserName("测试" + i);
user.setUserPass("ceshi" + i);
//将用户信息添加到列表中
list.add(user);
}
request.setAttribute("list", list);
return this.SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
在配置文件中配置ListAction节点的信息并添加成功跳转的页面:
<!-- 配置ListAction的信息 -->
<action name="list" class="com.xiyou.jackielin.ListAction">
<result name="success">/list.jsp</result>
</action>
⑥接下来编写自定义的拦截器,当我们发送请求时,需要先经过拦截器拦截该请求进行处理,验证用户是否是通过正常的途径登录,如果登录途径异常则跳转到登录页面,这里采用自定义的拦截器。
public class MyInterceptor implements Interceptor{
@Override
public void destroy() {
System.out.println("destroy().....");
}
@Override
public void init() {
System.out.println("init()......");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("进入拦截器。。。。。。");
//在拦截器中获取Session对象
Map session = invocation.getInvocationContext().getSession();
Object user = session.get("userinfo");
//如果用户的信息不为空,则说明用户通过正规方式登录
if(user != null) {
return invocation.invoke();//将请求向下传递
}
//否则返回登录页面。
return "login";
}
}
⑦自定义的拦截器我们还需要在配置文件struts.xml配置引用之后才会经过该拦截器,接下来配置拦截器:
<struts>
<package name="interceptorDemo" extends="struts-default">
<!-- 配置自定义拦截器 -->
<interceptors>
<!-- 配置自定义的拦截器 -->
<interceptor name="myInter" class="com.xiyou.jackielin.Interceptor"></interceptor>
</interceptors>
<!-- 配置全局result节点信息login -->
<global-results>
<result name="login">/login.jsp</result>
</global-results>
<!-- 配置UserAction的信息 -->
<action name="user" class="com.xiyou.jackielin.action.UserAction">
<!-- 配置成功根节点的信息,登陆成功跳转到listAction中 -->
<result name="success" type="redirectAction">list</result>
<!-- <result name="login">/login.jsp</result> -->
</action>
<!-- 配置ListAction的信息 -->
<action name="list" class="com.xiyou.jackielin.action.ListAction">
<result name="success">/list.jsp</result>
<!-- 引入自定一个拦截器 -->
<interceptor-ref name="myInter"></interceptor-ref>
<!-- 引用默认的拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
⑧编写测试页面
登录界面:login.jsp
<body>
<h2 align="center">用户登录</h2>
<form action="user.action" method="post">
<table align="center">
<tr>
<td>用户名称:</td>
<td><input type="text" name="user.userName"/></td>
</tr>
<tr>
<td>用户密码:</td>
<td><input type="text" name="user.userPass"/></td>
</tr>
<tr>
<td><input type="submit" value="登录"/> </td>
<td><input type="reset" value="重置"/> </td>
</tr>
</table>
</form>
</body>
用户信息列表:list.jsp
<body>
<h2 align="center">用户列表</h2>
<table align="center">
<tr>
<td>用户编号</td>
<td>用户名称</td>
<td>用户密码</td>
</tr>
<c:forEach items="${requestScope.list}" var="u">
<tr>
<td>${u.userId}</td>
<td>${u.userName}</td>
<td>${u.userPass}</td>
</tr>
</c:forEach>
</table>
</body>