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

大部分 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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值