Struts2基础-4-2 -struts拦截器实现权限控制案例+ 模型驱动处理请求参数 + Action方法动态调用
1.新建项目,添加jar包到WEB-INF目录下的lib文件夹,并添加到builde path里面
整体目录结构如下
2.新建web.xml,添加struts2核心过滤器,和默认首页
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>main.jsp</welcome-file>
</welcome-file-list> <filter>
<filter-name>StrutsPrepareAndExecuteFilter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter> <filter-mapping>
<filter-name>StrutsPrepareAndExecuteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>
3. 新建一个User Javabean ,编写loginAction
在 cn.test.domain 包下建User类
package cn.test.domain; 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;
} @Override
public String toString() {
return "User [password=" + password + ", username=" + username + "]";
} }
在 cn.test.action 包下 建 LoginActoin,模拟用户登陆,判断登陆用户是否为指定用户,不是,就返回逻辑视图名" input ",跳转到login.jsp 去让用户登陆
package cn.test.action; import cn.test.domain.User; import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven; public class LoginActoin extends ActionSupport implements ModelDriven<User>{ private static final long serialVersionUID = 1L;
private User user = new User(); //必须要有该Javabean的实例
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
// 获取ActionContext
ActionContext context = ActionContext.getContext();
if("admin".equals(user.getUsername())&& "123".equals(user.getPassword())){
//把用户存储在session中
context.getSession().put("user", user);
return SUCCESS;
}else {
context.put("msg", "用户名密码不正确");
return INPUT;
} } }
注:这里使用了struts2的模型驱动来获取请求参数值。
在 Struts2中, Action处理请求参数还有另外一种方式,叫做模型驱动( Modeldriven)。过实现 Modeldriven接口来接收请求参数, Action类必须实现 Modeldriven接口,引入JavaBea的实例 ,并且重写 get Model()方法,这个方法返回的就是 Action所使用的数据模型对象。
模型驱动方式通过 Javabean模型进行数据传递。只要是普通的 Javabean,就可以充当模型部分。采用这种方式, Javabean所封装的属性与表单的属性一一对应, Javabean将成为数据传递的载体。使用模型驱动方式, Action类通过get*()的方法来获取模型,其中 * 代表具体的模型对象,代码如上LoginActoin 中背景颜色部分所示。
使用模型驱动时,其登录页面 userlogin.jsp也要做相应调整。使用ModelDriver的方式,一个Action只能对应一个Model,因此不需要添加 user前缀,页面上的username对应到这个Model的username属性。属性驱动的方法和模刑驱动的方法各有优缺点,实际开发中,应根据不同情况来选择使用。
4.在 cn.test.action 包下创建 BookAction ,写增删改查四个方法
package cn.test.action; import com.opensymphony.xwork2.ActionSupport; public class BookAction extends ActionSupport { private static final long serialVersionUID = 1L;
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;
} }
5.在 cn.test.interceptor 包下创建自定义拦截器类PrivilegeInterceptor ,根据session中有无指定用户,进行权限控制
package cn.test.interceptor; import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; /**
* 自定义拦截器类,获取session中有无登陆用户,完成页面跳转的权限控制
*
* @author Administrator
*
*/
public class PrivilegeInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1L; @Override
public String intercept(ActionInvocation invocation) throws Exception {
// 获取actionContext
ActionContext actionContext = invocation.getInvocationContext();
// 获取session中的用户
Object user = actionContext.getSession().get("user");
if (null != user) {
return invocation.invoke(); // 继续向下执行
} else {
actionContext.put("msg", "对不起,您还未登陆!");
return Action.LOGIN; // 返回逻辑视图名"login",由对应的result配置,跳转到登陆页面
}
} }
6.在webcontent目录下创建4个视图页面:主页main.jsp ,登陆页login.jsp ,操作成功页success.jsp , 404错误页error.jsp
(1)main.jsp 定义增删改查4个链接,请求路径中action的命名按照 book_* 的方式命名,方便struts里面配置Action的动态调用
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>main.jsp</title>
</head> <body>
<a href="<%=basePath%>book_add">bookAdd</a> <br>
16 <a href="<%=basePath%>book_del">bookDel</a> <br>
17 <a href="<%=basePath%>book_update">bookUpdate</a> <br>
18 <a href="<%=basePath%>book_find">bookFind</a> <br>
</body>
</html>
(2),登陆页login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登陆</title>
</head>
<body>
${requestScope.msg }
<br>
<form action="<%=basePath%>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 colspan="2" align="right"><input type="submit" value="登陆"/></td>
</tr>
</table>
</form>
</body>
</html>
(3)操作成功页success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>success.jsp</title>
</head> <body>
用户${user.username }操作成功!
</body>
</html>
(4) 404错误页error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>error page</title>
</head> <body>
您访问的页面不存在<br>
</body>
</html>
7.配置struts。xml,声明自定义拦截器,拦截器栈以及对book操作的action,和处理404错误的action
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts> <package name="intercepter" namespace="/" extends="struts-default">
<!-- 声明拦截器 -->
<interceptors>
<interceptor name="privilege" class="cn.test.interceptor.PrivilegeInterceptor"></interceptor> <!--自定义拦截器-->
<!-- 自定义拦截器栈,放入自定义的拦截器和struts的默认拦截器 -->
<interceptor-stack name="myStack">
13 <interceptor-ref name="privilege"></interceptor-ref>
14 <interceptor-ref name="defaultStack"></interceptor-ref>
15 </interceptor-stack>
</interceptors> <!-- 默认的 Action配置要放在拦截器配置的后面 -->
<default-action-ref name="defaultAction"></default-action-ref> <!-- 用户登陆操作 action里面不写方法名,默认之心execute()方法!!!-->
<action name="login" class="cn.test.action.LoginActoin" >
<result>/main.jsp</result>
<result name="input">/login.jsp</result>
</action>
<!-- book操作action -->
<action name="book_*" class="cn.test.action.BookAction" method="{1}">
<result name="success">/success.jsp</result>
<result name="login">/login.jsp</result>
<!-- 在action中使用自定义拦截器,对book操作的actoin进行权限控制
放在哪个action,就对那个action进行权限控制的拦截-->
<interceptor-ref name="myStack"></interceptor-ref>
</action> <!-- 注意,package元素里面的子元素是有顺序要求的,如果写错位置,启动时会报错,一般把action写在最后面 -->
<action name="defaultAction">
<result>/error.jsp</result>
</action>
</package> </struts>
book操作action类中只返回了一个success作为result 的name属性值, 下面action中配置的 <result name="login">/login.jsp</result> ,这个result是拦截器用的,当拦截器检测到用户没有登陆时,就返回“login”这个逻辑视图名;
关于动态调用,action 的method={1},表示 method属性值取 action的name属性的值里边的第一个*的值。如果请求里是book_add 那么method 就是add,则执行Action中的add方法。
<!-- book操作action -->
<action name="book_*" class="cn.test.action.BookAction" method="{1}">
<result name="success">/success.jsp</result>
<result name="login">/login.jsp</result>
<interceptor-ref name="myStack"></interceptor-ref> <!--调用拦截器栈 -->
</action>
8. 部署并测试
(1)访问http://localhost:8080/strutsstu4-2/ 自动跳转到main.jsp
(2)随便点击一个链接,比如update ,提示还未登陆,红框里面的提示消息是 PrivilegeInterceptor 拦截器类中返回的 ,说明拦截器工作了。
(3)输入错误用户名密码测试,提示用户名密码不正确,同时,页面跳转到了登陆页,可以看到浏览器中的地址成了login.action,
(4)输入admin 123登陆
可以在main.jsp中加入 当前登陆用户:${username } <br/> ,效果会看的更明显
点击bookFind,可以看到浏览器地址发生变化,请求book_find这个action
(5) 请求一个不存在的actoin:
遇到的问题:添加默认的 Action配置时,给放在了拦截器配置的前面,导致启动时报错,提示信息如下:
Caused by: 元素类型为 "package" 的内容必须匹配 "(result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)"。 - file:/D:/Tomcat/apache-tomcat-6.0.30/webapps/strutsstu4-2/WEB-INF/classes/struts.xml:42:12
其实括号里面的红字部分就已经提示了package中各个元素要遵从的顺序,可以看到,default-action-ref是在default-interceptor-ref?的后面,也就是说默认Action应该配置在拦截器后面
示例代码下载地址 https://github.com/liuch0228/Struts2SSH.git
Struts2基础-4-2 -struts拦截器实现权限控制案例+ 模型驱动处理请求参数 + Action方法动态调用的更多相关文章
- Struts2使用拦截器完成权限控制示例
http://aumy2008.iteye.com/blog/146952 Struts2使用拦截器完成权限控制示例 示例需求: 要求用户登录,且必须为指定用户名才可以查看系统中某个视图资源:否 ...
- 6、Struts2拦截器实现权限控制
1.创建如下项目结果 2.在com.entity包下创建 package com.entity; public class User { private String name; private St ...
- struts自己定义拦截器--登录权限控制
说明:该自己定义的拦截器实现用户登录的权限控制. login.jsp--->LoginAction--重定向-->MainAction--->main.jsp 一.1.整体的步骤: ...
- 使用Struts 拦截namespace进行权限控制
有时候我需要在几个包下都需要进行同一个权限控制.如在购物网站中,我们需要进入个人中心.下订单.评价商品等等都需要进行登录权限控制,但是这几个模块并不是位于同一个package下.Struts提供的拦截 ...
- [置顶] 使用struts拦截器+注解实现网络安全要求中的日志审计功能
J2EE项目中出于安全的角度考虑,用户行为审计日志功能必不可少,通过本demo可以实现如下功能: 1.项目中记录审计日志的方法. 2.struts拦截器的基本配置和使用方法. 3.struts拦截器中 ...
- 【Struts2学习笔记-6--】Struts2之拦截器
简单拦截器的使用 拦截器最基本的使用: 拦截方法的拦截器 拦截器的执行顺序 拦截结果的监听器-相当于 后拦截器 执行顺序: 覆盖拦截器栈里特定拦截器的参数 使用拦截器完成-权限控制 主要完成两个功能: ...
- Struts2基础-4 -struts拦截器
Struts2拦截器工作原理 拦截器围绕着 Action和 Result的执行而执行. Struts2拦截器的工作方式如图10.2所示.从上图中可以看出, Struts2拦截器的实现原理和 Servl ...
- struts 拦截器 Interceptor
拦截器是AOP中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用.正如上面 Struts2的Reference中讲述的,Stru ...
- struts2 javaweb 过滤器、监听器 拦截器 原理
转: 过滤器.监听器 拦截器 过滤器 创建一个 Filter 只需两个步骤: (1)创建 Filter 处理类: (2)在 web.xml 文件中配置 Filter . 创建 Filter 必须实现 ...
随机推荐
- Hadoop学习之路(二)HDFS基础
1.HDFS前言 HDFS:Hadoop Distributed File System,Hadoop分布式文件系统,主要用来解决海量数据的存储问题. 设计思想 分散均匀存储 dfs.blocksiz ...
- 2017数据科学报告:机器学习工程师年薪最高,Python最常用
2017数据科学报告:机器学习工程师年薪最高,Python最常用 2017-11-03 11:05 数据平台 Kaggle 近日发布了2017 机器学习及数据科学调查报告,针对最受欢迎的编程语言.不同 ...
- mysql之存储过程基础篇
1. 创建/使用数据库 mysql> create database me; mysql> use me; 2. 创建表 mysql> create table Stu(Sno ...
- delphi 牛逼 了 app (已在软件界掀起波澜)10分钟10行代码做出让人惊叹的程序
(已在软件界掀起波澜)10分钟10行代码做出让人惊叹的程序 http://v.qq.com/x/page/m0328h73bs7.html?ptag=bbs_csdn_net
- ES6中set的用法回顾
ES6中的set类似一个数组,但是其中的值都是唯一的,Set本身是一个构造函数,用来生成 Set 数据结构. set函数可以接受一个数组作为参数,用来初始化: const set = new Set( ...
- 第 2 章 前端基础之CSS
一.CSS语法 CSS规则由两个主要的部分构成:选择器,以及一条或多条声明. ''' selector { property: value; property: value; ... property ...
- vcsa6.5安装部署配置(vSphere vsan 6.5)
首先您最好先了解下vcenter和vcsa是啥:VMware Vsphere 几个不同的组件 esxi是在物理服务器安装的服务端,所有虚拟机是安装再esxi里面的,是服务端:vcenter是管理端 是 ...
- 网络流强化-HDU2732
第一次遇到加了“多余”的边会导致WA的——在我看来是很多余,见代码191行 之后会思考为什么,想出来再更. 问题弄明白了,如果你在连接边连了一条到没有柱子的点的边,这个没有柱子的点是不可能连到终点的, ...
- jmeter对响应数据做断言
单独校验某个接口中的某个字段时,断言就相当于检查点 添加http请求,输入路径url
- python支持的进程与线程
一.multiprocessing模块介绍 python中的多线程无法利用CPU资源,在python中大部分情况使用多进程.python中提供了非常好的多进程包multiprocessing. mul ...