JavaWeb框架SSH_Struts2_(三)
2. Struts2的拦截器(使用拦截器实现权限控制)
2.1 拦截器的概述
拦截器是Struts2的核心组成部分,它可以动态的拦截Action调用的对象,类似与Servlet中的过滤器。Struts2的拦截器是AOP(Aspect-Object-Programming,面向切面编程)的一种实现策略,是可插拔的,需要某一个功能时就“插入”这个功能的拦截器,不需要这个功能就“拔出”拦截器。开发者只需要提供拦截器的实现类,并将其配置在Struts.xml中即可。
2.1.2 拦截器的工作原理
通常情况下,拦截器都是一代理的方式调用的,它在一个Action执行前后进行拦截,围绕着Action和Result的执行而执行,其工作方式如下图所示,
Struts2拦截器实现原理与Servlet过滤器实现原理类似,它以链式执行,对真正要执行的方法(execute())进行拦截。首先执行Action配置的拦截器,在Action和Result执行之后,拦截器会再次执行(与先前调用的顺序相反),在此链式执行的过程中,每一个拦截器都可以直接返回,从而终止余下的拦截器、Action及Result的执行。
2.1.3 拦截器的配置
(1) 拦截器
拦截器的配置在struts.xml文件中完成的,它通常以<interceptor>标签开头,以</interceptor>标签结束。定义拦截器的语法格式如下:
<interceptor name="interceptorName" class="interceptorClass">
<param name="paramName">paramValue</param>
</interceptor>
上述语法格式中,name属性用来指定拦截器的名称,class属性用于指定拦截器的实现类。在定义时,使用<param>标签传入参数。
(2) 拦截器栈
在实际开发中,在Action执行前同时执行多个拦截动作,如用户登陆检查等,这时可以把多个拦截器组成拦截器栈。在使用时,可以将栈内的多个拦截器当成一个整体来引用。当拦截器栈被附加到一个Action上时,在执行Action之前必须先执行拦截器栈中的每一个拦截器。
定义拦截器栈使用<interceptors>和<interceptor-stack>子元素,当配置多个拦截器时,需要使用<interceptor-ref>元素来指定多个拦截器,配置语法如下:
<interceptors>
<interceptor-stack name="interceptorStackName">
<interceptor-ref name="interceptorName"/>
...
</interceptor-stack>
</interceptors>
上述语法中,interceptorStackName值表示配置的拦截器栈的名称,interceptorName值表示拦截器的名称。除此之外,在一个拦截器栈中还可以包含另一个拦截器栈,实例如下:
<package name="default"namespace="/"extends="struts-default">
<!--拦截器的声明-->
<interceptors>
<interceptor name="interceptor1" class="interceptorClass"/>
<interceptor name="interceptor2" class="interceptorClass"/>
<!--定义一个拦截器栈mystack,该拦截器栈中包括两个拦截器和一个拦截器栈-->
<interceptor-stack name="mystack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="interceptor1"/>
<interceptor-ref name="interceptor2"/>
</interceptor-stack>
</interceptors>
</package>
上述代码中定义的拦截器栈是myStack,在myStack栈中,除了引用了两个自定义的拦截器interceptor1和interceptor2外,还引用了一个内置拦截器栈defaultStack,这个拦截器是必须要引入的。
(3) 默认拦截器栈
默认拦截器可以对其指定包中的所有Action起到拦截的作用。一旦为某个包指定了默认拦截器,并且该包中的Action未显式地指定拦截器,则会使用默认拦截器。默认拦截器需要使用<default-interceptor-ref>元素,此元素为<package>元素的子元素。其语法格式如下:
<default-interceptor-ref name="拦截器(栈)的名称"/>
上述语法格式中,name属性的值必须是已经存在的拦截器或拦截器栈的名称。下面用该语法格式配置一个默认拦截器,示例代码如下:
<package name="default" namespace="/" extends="struts-default"> <!--拦截器的声明-->
<interceptors>
<default-interceptor-ref name="拦截器栈的名称"/>
<interceptors>
<interceptor name="interceptor1" class="interceptorClass"/>
<interceptor name="interceptor2" class="interceptorClass"/>
<!--定义一个拦截器栈mystack,该拦截器栈中包括两个拦截器和一个拦截器栈-->
<interceptor-stack name="mystack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="interceptor1"/>
<interceptor-ref name="interceptor2"/>
</interceptor-stack>
</interceptors>
<!-- 配置该包下的默认拦截器,既可以是拦截器,也可以是拦截器栈 -->
<default-interceptor-ref name="mystack"/>
<action name="login"class="cn.itcast.action.LoginAction">
<result name="input">/login.jsp</result>
</action> </package>
上述代码中,指定了包下的默认拦截器是一个拦截器栈,该拦截器栈将会作用于包下所有的Action。
Notice:一个包下只能定义一个默认拦截器,如果需要多个拦截器作为默认拦截器,则可以将这些拦截器定义为一个拦截器栈,再将这个拦截器栈作为默认拦截器即可。
2.2 Struts2的内建拦截器
2.2.1 内建拦截器的介绍
只要自定义的包继承了Struts2的struts-default包,就可以使用默认包中的拦截器,否则需要自己定义拦截器。在Struts-default.xml中每一个拦截器都具有不同的意义(具体拦截器说明--->省略)。
2.2.2 内建拦截器的配置
前面2.1已经介绍过相关配置,此处不再赘述。
2.3 Struts2自定义拦截器
struts2的内置拦截器可以实现大部分的拦截任务,但是一些与系统逻辑相关的通用功能(如权限的控制、用户登陆控制等),则需要通过自定义拦截器来实现。本节详讲如何自定义拦截器。
2.3.1 实现自定义拦截器
在程序开发过程中,如果需要开发自己的拦截器类,就需要直接或间接地实现com.opensymphony.xwork2. interceptor. Interceptor接口,具体代码如下:
import com.opensymphony.xwork2.DefaultActionInvocation;
import java.io.Serializable;
public interface Interceptor extends Serializable {
void init();
void destroy();
String interceptor (DefaultActionInvocation)throws Exception;
}
该接口提供一下三个方法:
- void init():该方法在拦截器被创建后会立即被调用,它在拦截器的生命周期只有内只被调用一次。可以在该方法中对相关的资源进行必要的初始化;
- void destroy():该方法与init()方法相对应,在拦截器实例被销毁之前,将调用该方法来释放与拦截器相关的资源。它在拦截器的生命周期内也只被调用一次。
- Spring intercept(ActionInvocation invocation)throws Exception:该方法是拦截器的核心方法,用来真正执行拦截工作的代码,实现具体的拦截工作。
2.3.2 应用案例-----使用拦截器实现权限控制
通过之前对拦截器学习,可以将自定义拦截器的使用分为一下三个步骤:
- 用户自定义拦截器类,必须实现Interceptor接口或者继承AbstractInterceptor类;
- 需要在struts.xml中,定义自定义拦截器;
- 在struts.xml中的Action中使用拦截器。
具体步骤如下:
(1)在intellij idea中创建Struts2的项目(可参考之前的博客 http://www.cnblogs.com/Mairr/p/7846747.html)
(2)web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!--首页(这一块儿是自己加进来的)-->
<welcome-file-list>
<welcome-file>main.jsp</welcome-file>
</welcome-file-list>
</web-app>
(3)在src目录下创建java包,如下
(4)User.java
package cn.Mairr.domin; 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;
}
}
(5)LoginAction.java
package cn.Mairr.action; import cn.Mairr.domin.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven; public class LoginAction extends ActionSupport implements ModelDriven <User> {
private static final long serialVersionUID = 1L;
private User user = new User(); public User getModel() {
return user;
} @Override
public String execute() throws Exception {
//获取ActionContext
ActionContext actionContext = ActionContext.getContext(); if ("Mairr".equals(user.getUsername()) && "123".equals(user.getPassword())) {
actionContext.getSession().put("user", user);
return SUCCESS;
} else {
actionContext.put("msg", "用户名或者密码不正确");
return INPUT;
}
}
}
(6) BookAction.java
package cn.Mairr.action; import com.opensymphony.xwork2.ActionSupport; public class BookAction extends ActionSupport {
public String add(){
System.out.println("book add");
return SUCCESS;
}
public String del(){
System.out.println("book del");
return SUCCESS;
}
public String update(){
System.out.println("book update");
return SUCCESS;
}
public String find(){
System.out.println("book find");
return SUCCESS;
}
}
(7)PrivilegeInterceptor.java
package cn.Mairr.interceptor; import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class PrivilegeInterceptor extends AbstractInterceptor{
private static final long serialVersionUID = 1L;
public String intercept(ActionInvocation invocation)throws Exception{
//得到ActionContext
ActionContext actionContext = invocation.getInvocationContext();
//获取user对象
Object user = actionContext.getSession().get("user");
if(user != null){
return invocation.invoke();
}else {
actionContext.put("msg","您还未登录,请先登陆");
return Action.LOGIN; //用户如果不存在,返回login直
}
}
}
(8) main.jsp
<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-11-28
Time: 下午5:18
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>main.jsp</title>
</head>
<body>
<a href="success.jsp">book del</a><br>
<a href="success.jsp">book add</a><br>
<a href="success.jsp">book update</a><br>
<a href="success.jsp">book find</a><br> </body>
</html>
(9) login.jsp
<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-11-28
Time: 下午5:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆</title>
</head>
<body>
<center>
${requestScope.msg}<br>
<form action="login.action" method="post">
<table>
<tr>
<td><label style="text-align: right;">用户名:</label></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><label style="text-align: right;">密码:</label></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td align="right" colspan="2">
<input type="submit" value="登陆">
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
(10)success.jsp
<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-11-28
Time: 下午5:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>成功页面</title>
</head>
<body>
用户${user.username}操作成功
</body>
</html>
(11) struts.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd"> <struts>
<package name="struts2" namespace="/" extends="struts-default">
<!--声明拦截器-->
<interceptors>
<interceptor name="privilege" class="cn.Mairr.interceptor.PrivilegeInterceptor"/>
<interceptor-stack name="mystack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="privilege"/>
</interceptor-stack>
</interceptors>
<!--用户登陆操作-->
<action name="login" class="cn.Mairr.action.LoginAction">
<result>/main.jsp</result>
<result name="input">/login.jsp</result>
</action>
<!--关于book操作-->
<action name="book_*" class="cn.Mairr.action.BookAction" method="{1}">
<result>/success.jsp</result>
<result name="login">/login.jsp</result>
<!--在action中使用自定义拦截器-->
<interceptor-ref name="mystack"/>
</action>
</package>
</struts>
完成上述程序之后,发布程序,登录本机http端口,查看拦截器实现功能;(http://localhost:8080/login.jsp)
- 登录界面如下:
--------->(登陆失败)
- 登陆成功(用户名:Mairr 密码:123 )
----------->(登陆成功,页面跳转到操作界面)
-------->(选择操作)
上面的案例中,创建了一个方法过滤拦截器PrivilegeInterceptor,然后在Struts.xml中配置了该拦截器,如果用户没有登陆,则无法对页面进行相应的操作,只有登陆后才有权操作页面的相应功能。
JavaWeb框架SSH_Struts2_(三)的更多相关文章
- JavaWeb框架SSH_Struts2_(二)
1. Struts2的核心配置(详解) 本章内容目录: 配置struts.xml文件 struts.xml文件 常量配置 包配置 包含配置 Action配置 实现Action控制类 配置Action ...
- JavaWeb框架SSH_Struts2_(一)
1. Struts2 框架入门及结合Intellj idea完成登陆demo测试 1.1 本章目录: 框架入门 Struts2简介 Struts2入门案例 Struts2执行流程分析 2. 具体 ...
- JavaWeb框架SSH_Struts2_(四)----->表达式语言OGNL
1. 表达式语言OGNL OGNL简介 OGNL基本语法 常量 操作符 OGNL表达式 OGNL基础 OGNL上下文 OGNL值栈 OGNL的访问 2. 具体内容 2.1 OGNL简介 OGNL(Ob ...
- JavaWeb框架_Struts2_(三)---->Struts2的拦截器
2. Struts2的拦截器(使用拦截器实现权限控制) 2.1 拦截器的概述 拦截器是Struts2的核心组成部分,它可以动态的拦截Action调用的对象,类似与Servlet中的过滤器.Struts ...
- JavaWeb框架之Struts2 ---- 系列学习
JavaWeb框架_Struts2_(七)----->文件的上传和下载 JavaWeb框架_Struts2_(六)----->Struts2的输入校验 JavaWeb框架_Struts2_ ...
- JavaWeb框架的基石
JavaWeb框架的基石(一) 初学JavaWeb开发,请远离各种框架,从Servlet开始. Web框架是开发者在使用某种语言编写Web应用服务端是关于架构的最佳实践.很多Web框架 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)
前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...
- JavaScript框架设计(三) push兼容性和选择器上下文
JavaScript框架设计(三) push兼容性和选择器上下文 博主很久没有更博了. 在上一篇 JavaScript框架设计(二) 中实现了最基本的选择器,getId,getTag和getClass ...
- 【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同 ...
随机推荐
- Python实现采集wordpress整站数据的爬虫
最近爱上了python,就非常喜欢使用python来练手,在上次的基础上完善一下代码,实现采集wordpress程序的网站的整站数据的爬虫程序,本站也是采用的wordpress,我就拿吾八哥网(htt ...
- Windows-universal-samples-master示例 XamlCommanding
Windows-universal-samples-master XamlCommanding 运行默认如果是 ARM会出现没有引用System,只要在调试选择CPU为PC的就好 默认 选择PC平台 ...
- 我的第一个python web开发框架(10)——工具函数包说明(一)
PS:原先是想直接进入功能开发,要用到什么函数时再创建,这样也容易熟悉每个函数的由来和使用方法,但考虑到这样操作,到时会经常在不同文件间切换,不好描述,容易造成混乱,所以还是使用函数库这种方式来说明. ...
- Kotlin——最详细的环境搭建
众所周知,Kotlin出来已经有一段时间了.Kotlin有着众多优势,不管是用于Android开发中,还是Java开发,都能缩减很大的代码量,大大提高了工作效率.而小生本人也是才从忙碌的个工作中抽身出 ...
- java 入门之八大内置基本类型
本文采用eclipse 工具演示,如果您对eclipse 工具不了解,请先学习下 eclipse 工具的使用,这个里面只是简单的介绍下输出和注释: 安装完成eclipse 以后,双击进入 后一次点击 ...
- Zookeeper 笔记-watch
ZooKeeper对Watch提供了什么保障 对于watch,ZooKeeper提供了这些保障: Watch与其他事件.其他watch以及异步回复都是有序的. ZooKeeper客户端库保证所有事件都 ...
- 详解 $().css('width')和$().width()的区别
在本次项目开发中,经常用jquery获取高度和宽度并且动态加载,有时候用$().css('width')或$().width()这两个方法获取宽度并设置,但是有时候出现获取不到的情况,查阅资料后发现他 ...
- left join 条件位置问题
表一:
- JavaScript+HTML5 实现打地鼠小游戏
一.游戏简介 打地鼠这个游戏相信大家都不陌生,也是童年时候一款经典的游戏.本次游戏的编写是以html文件形式完成的,并且使用HBulider软件进行编写,使用谷歌浏览器展示效果,游戏将会采用JavaS ...
- Web设计新手应知道的10个锦囊妙计
摘要:你在网页设计所学到的大多数教训都来自工作经验.学习是一个反复持续的过程,并且没有比犯错更好的方式来获得知识.在本文中,我们将讨论10个重要并常规的技巧,这是每位Web设计师新手都应该知道. 在做 ...