Struts2学习(九)—拦截器之登录权限

来源:互联网 发布:会计电算软件 编辑:程序博客网 时间:2024/06/07 19:13

大部分 Action共享常见的关注点. 一些Action需要输入验证. 另外一些Action可能需要预处理文件上传. 还有一些 Action可能需要防止重复提交 . 许多Action需要在页面显示前生成下拉列表和其他控件.

框架使用 “拦截器” 策略使得解决共享这些关注点变得十分容易. 当你请求与某个 “action”匹配资源, 框架将调用 Action对象. 但是, 在Action执行前, 调用可以被另外的对象拦截. 在Action 执行完后, 调用可以再次被拦截. 毫无疑问, 我们称呼这些对象为 “拦截器.”
默认拦截器栈定义是为了满足大部分应用. 大部分应用不需要添加拦截器或修改拦截器栈 .
拦截器可以在Action调用前或后 执行代码. 框架的核心功能以拦截器方式实现. 特性如防重复提交,类型转换, 对象创建, 验证, 文件上传, 页面预处理等等,都是在拦截器中实现. 每个拦截器都是可插拔的, 因而你可以精确地决定哪些特性该Action需要支持.

每个Action可以配置不同的拦截集合. 你自定义的拦截器可以和框架内置的拦截器混合在一起使用. 拦截为 Action类 “设置状态” , 完成大部分 “heavy lifting” 在 Action执行前.

自定义拦截器

Interceptor接口

拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor 接口.

public interface Interceptor extends Serializable {    void destroy();    void init();    String intercept(ActionInvocation invocation) throws Exception;}

init 方法在拦截器实例化后且在调用intercept方法前调用.这里是放置资源分配代码的位置 .

intercept 方法是拦截器代码书写的地方. 正如 action方法, intercept 返回一个结果,让 Struts 使用该结果把请求转发到另外一个web资源 .调用ActionInvocation类型的参数的 invoke 方法将执行该action (如果是栈中最后一个拦截器) 或其它拦截器.
记住invoke将返回在result被执行后 (例如. 在JSP已经渲染后), 适合应用在 open-session-in-view 模式. 如果你想要在结果执行前做某些事情, 你需要实现一个PreResultListener.

重写 destroy 方法来释放资源当应用关闭时 .
AbstractInterceptor

AbstractInterceptor类提供了 init 和 destroy空实现, 它可以使用在不打算实现这些方法的地方.
映射

拦截器使用 interceptor 元素来声明, 嵌套在 interceptors 元素中. 摘自struts-default.xml:

<struts>   ...   <package name="struts-default">      <interceptors>         <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>         <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>         ...      </interceptors>   </package>   ...</struts>

示例

我们做一个用于登录权限验证的拦截器,实现当你没登录时访问action会给你转发到登录界面,做不了其他操作
代码如下:
登录界面:
login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>    <%@ page isELIgnored="false" %>    <%@ taglib uri="/struts-tags" prefix="s" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><s:head /><body>${message}<s:property value="#tip"/><s:property value="errors.message01[0]"/><s:form action="login">        <!--key作用         1、生成input的name         2、要查找属性文件的key         3、当找不到时,就显示key         -->         <s:textfield name="user.name" label="姓名"></s:textfield>          <s:textfield name="user.password" label="密码"></s:textfield>        <s:submit />    </s:form>    <s:debug></s:debug></body></html>

LoginAction

package com.lgh.bookstruts.action;import org.apache.struts2.ServletActionContext;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.Transaction;import com.lgh.bookstruts.model.User;import com.lgh.bookstruts.util.HibernateUtil;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport {    private User user;    public LoginAction() {    }    public User getUser() {        return user;    }    public void setUser(User user) {        this.user = user;    }    @Override    public String execute() throws Exception {        Session session = null;        Transaction ts = null;        try {            session = HibernateUtil.getSession();            ts = session.beginTransaction();            // 这里使用了hibernate对数据库进行操作            String hql = "select count(*) from User u where u.name = :name and u.password = :password";            Query query = session.createQuery(hql);            query.setParameter("name", user.getName());            query.setParameter("password", user.getPassword());            Long longNum = (Long) query.uniqueResult();            System.out.println(longNum);            if(longNum >0){                ActionContext.getContext().getSession().put("loginId", "hadLogin");                return SUCCESS;            }else{            //  ServletActionContext.getRequest().setAttribute("message", "用户名密码错误");                addFieldError("message01", "用户名密码错误!!");            }            ts.commit();        } catch (Exception e) {            if(ts != null){                ts.rollback();            }            e.printStackTrace();        }finally{            if(session != null){                session.close();            }        }        return INPUT;    }}

如果用户名和密码正确,就在session中放一个数据用于标记已登录

ActionContext.getContext().getSession().put("loginId", "hadLogin");

LoginAction-validation.xml
用于验证

<!DOCTYPE validators PUBLIC        "-//Apache Struts//XWork Validator 1.0.3//EN"        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">        <!-- 以上内容,根据使用版本的不同,有可能会引发错误 --><validators>    <validator type="requiredstring">        <param name="fieldname">user.name</param>        <message>用户名不能为空</message>    </validator>    <!-- 字段验证器 -->    <field name="user.password">        <field-validator type="requiredstring" short-circuit="true">            <message>密码不能为空</message>        </field-validator>    </field></validators>

配置:

 <action name="login" class="com.lgh.bookstruts.action.LoginAction"            method="execute">            <result name="success" type="redirect">/fileupload.jsp</result>            <result name="input">/login.jsp</result>        </action>

成功后的页面:
fileupload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><form action="upload" method="post" enctype="multipart/form-data">上传文件:<input name="book" type="file"><br>文件类型:<input name="books.desc" type="text"><input type="submit"></form></body></html>

这也是另一个action的页面
拦截器
LoginInterceptor.java

package com.lgh.bookstruts.interceptor;import java.util.Map;import com.opensymphony.xwork2.Action;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class LoginInterceptor extends AbstractInterceptor {    public LoginInterceptor() {        // TODO Auto-generated constructor stub    }    @Override    public String intercept(ActionInvocation invocation) throws Exception {        // 取得请求相关的ActionContext实例          ActionContext ctx = invocation.getInvocationContext();          Map session = ctx.getSession();          String res = (String) session.get("loginId");          if("hadLogin".equals(res)){             return invocation.invoke();          }        System.out.println("你还没有登录");        ctx.put("tip", "你还没有登录");          return Action.LOGIN;      }}

配置拦截器

<interceptors>            <interceptor name="needlogin"                class="com.lgh.bookstruts.interceptor.LoginInterceptor"></interceptor>            <interceptor-stack name="myStack">                <interceptor-ref name="needlogin"></interceptor-ref>                <interceptor-ref name="defaultStack"></interceptor-ref>            </interceptor-stack>        </interceptors>

在fileupload中使用新建的拦截器栈myStack

<!-- 定义全局Result -->        <global-results>            <!-- 当返回login视图名时,转入/login.jsp页面 -->            <result name="login">/login.jsp</result>        </global-results><action name="upload" class="com.lgh.bookstruts.action.FileUploadAction"            method="execute">            <interceptor-ref name="myStack" />            <result name="success" type="redirect">filelist</result>            <result name="input">/fileupload.jsp</result>        </action>

这里时我在这个项目中所使用的struts.xml,上面的有点乱,这里放上完全的

<?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>    <constant name="struts.devMode" value="true"></constant>    <!-- 设置上传文件的大小 -->    <constant name="struts.multipart.maxSize" value="3024000"></constant>    <package name="basicstruts2" extends="struts-default,json-default">        <interceptors>            <interceptor name="needlogin"                class="com.lgh.bookstruts.interceptor.LoginInterceptor"></interceptor>            <interceptor-stack name="myStack">                <interceptor-ref name="needlogin"></interceptor-ref>                <interceptor-ref name="defaultStack"></interceptor-ref>            </interceptor-stack>        </interceptors>        <!-- 定义全局Result -->        <global-results>            <!-- 当返回login视图名时,转入/login.jsp页面 -->            <result name="login">/login.jsp</result>        </global-results>        <action name="upload" class="com.lgh.bookstruts.action.FileUploadAction"            method="execute">            <interceptor-ref name="myStack" />            <result name="success" type="redirect">filelist</result>            <result name="input">/fileupload.jsp</result>        </action>        <action name="login" class="com.lgh.bookstruts.action.LoginAction"            method="execute">            <result name="success" type="redirect">/fileupload.jsp</result>            <result name="input">/login.jsp</result>        </action>        <action name="loginX">            <result name="success">/login.jsp</result>        </action>        <action name="filelist" class="com.lgh.bookstruts.action.FileListAction"            method="execute">            <interceptor-ref name="myStack" />            <result name="success">/booklist.jsp</result>        </action>        <action name="downloadX" class="com.lgh.bookstruts.action.FileDownloadXAction"            method="execute">            <result name="success" type="stream">                <param name="contentType">${contentType}</param>                <param name="inputName">is</param>                <param name="contentDisposition">attachment;filename="${f}";filename*=utf-8''${f}</param>                <param name="bufferSize">1024</param>            </result>        </action>    </package>    <include file="example.xml" />    <!-- Add packages here --></struts>

好了,写到这基本上登录权限拦截器基本上就可以使用了,我们进行一下测试
直接请求fileupload
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这时候进行上传文件就会上传成功,进入下载列表界面

1 0
原创粉丝点击