struts2要点总结 通配符、OGNL、拦截器

本文详细介绍了Struts2框架的配置方法,包括驼峰式和下划线式的通配符配置,以及服务器和客户端跳转的实现。同时深入探讨了OGNL表达式的应用,涵盖基本操作、集合处理及条件筛选等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

struts2配置文件
-------------------------------------------
*站位符{1}、{2}是分别取出通配符的值
***常用配置方式:
1)驼峰式:
<action name="*User" class="com.cyjch.action.UserAction" method="{1}">
    <result>/{1}UserSuc.jsp</result>
</action>

2)下划线式:
<action name="*_*" class="com.cyjch.action.{1}Action" method="{2}">
    <result>/{1}_{2}.jsp</result>
</action>

或:
<action name="*_*" class="com.cyjch.action.{1}Action" method="{2}">
    <result>/{0}.jsp</result>
</action>

//{0}表示action定义中的name值:*_* 

***Result
1)服务器跳转 type="chain"
<action name="test" class="com.cyjch.action.TestAction">
    <result name="success" type="chain">
        <param name="actionName">test</param>
    </result>
</action>
2)客户端跳转
<action name="test" class="com.cyjch.action.TestAction">
    <result name="success" type="redirectAction">
        <param name="actionName">test</param>
    </result>
</action>



注意:
1)有通配符时,是按顺序来访问
2)如果没有通配符时,优先级最高
3)ACTION文件启名要以Action结尾

//////////////////////////////// 

***OGNL应用:
------------------------------- 
OGNL和EL区别
EL在JSP中使用加${xxx},在STRUTS标签中使用OGNL表达式时不用加${xxx}直接写表达式即可
标签获取request中的值如:<s:property value="user.username"/>
调用值栈中的普通方法如:<s:property value="user.get()"/>//action中的属性会放到值栈中
调用ACTION中的静态方法如:<s:property value="@com.cyjch.action.LoginAction@get()"/>
调用JDK中类的静态方法如:<s:property value="@java.lang.Math@floor(4.6)"/>
调用静态属性如:<s:property value="com.cyjch.action.LoginAction@USERNAME"/>//静态属性应该为public的
调用普通的构造方法如:<s:property value="new com.cyjch.bean.Student('张三','23')/>

获取List集合:<s:property value="testList"/> //结果为:['list1','list2','list3']
获取List集合中某一个元素:<s:property value="testList[0]"/> //结果为:list1
获取Map集合中某一个元素:<s:property value="testMap['m1']"/> //结果为:map1
获取Map集合中所有元素的键:<s:property value="testMap.keys"/> 
获取Map集合中所有元素的值:<s:property value="testMap.values"/> 
获取List集合中的所有对象:<s:property value="students"/> //students为List,需要set和get方法
用投影获取List集合中所有对象的属性:<s:property value="students.{username}"/>//从集合中取出来一个子集合
用投影(子集合)获取List集合中某一个对象的属性:<s:property value="students.{username}[0]"/>
选择:? ^(开始) $(结束)
用选择?(有条件)获取List集合中的成绩极格的对象:<s:property value="students.{?#this.grade>=60}"/>//#this为循环的当前对象
用选择?(有条件)获取List集合中的成绩极格的第一个对象的username:<s:property value="students.{?#this.grade>=60}.{username}[0]"/>//#this为循环的当前对象
用选择^(有条件)获取List集合中的成绩极格的第一个对象的username:<s:property value="students.{^#this.grade>=60}.{username}[0]"/>//#this为循环的当前对象
用选择$(有条件)获取List集合中的成绩极格的最后一个对象的username:<s:property value="students.{$#this.grade>=60}.{username}[0]"/>//#this为循环的当前对象

***OGNL中的#的使用(可以取出堆栈上下文中的存放的对象,以下匀在<s:property value=""/>中使用)
-------------------------------
1)parameters 例:#parameters.id[0] <==> request.getParameter("id")

2)request 例:#request.userName <==> request.getAttribute("userName")

3)session 例:#session.userName <==> session.getAttribute("userName")

4)application 例:#application.userName <==> application.getAttribute("userName")

5)attr(默认按顺序去读取context/request/session/application四种中的值) 例:attr.username


***OGNL中%{}的使用(可以取出存在值栈中的Action对象,直接调用它的方法)
------------------------------------
例:ACTION如继承了ActionSupport那么可以用<s:property value="%{getText('key')}"/>的方式拿出国际化的信息

***OGNL中的$使用
------------------------------------
1)用于国际化资源文件中
2)用于配置文件中

***valueStack为根对象,可以省写#
---------------------------------
<s:property value="user.username"/>

***服务器跳转时共用一个值栈

***使用top获取值栈中的第二个对象:<s:property value="[1].top"/>//[1]代表第二个对象

***使用N获取值栈中的第二个对象属性:<s:property value="[1].username"/>//[1]代表第二个对象

***使用@调用静态方法<s:property value="@vs1@getName()"/>//其中vs1代表第一个,vs2代表第二个栈中的Action


***自定义拦截器栈
-------------------------
<package name="test" extends="struts-defalut">
    <interceptors>
        <interceptor name="testInteceptor" class="com.cyjch.inteceptor.TestInteceptor"/>
    </interceptors>
    
    <action name="login" class="com.cyjch.action.LoginAction">
        <result name="success">/loginSuc.jsp</result>
        <result name="error">/loginFail.jsp</result>
        <interceptor-ref name="testInterceptor"/>
        <interceptor-ref name="defaultStack"/>
    </action>
</package>

代码:TestInteceptor.java

public class TestInteceptor extends AbstractInterceptor{

    public String intercept(ActionInvocation invocation)throws Exception{

        System.out.println("TestInterceptor--begin");
        long startTime = System.currentTimeMillis();
        String result = invocation.invoke();
        long endTime = System.currentTimeMillis();

        long time = endTime- startTime;//共执行多少时间

        System.out.println("执行全部--end");
        System.out.println("TestInterceptor--end");
        return result;
    }
}

***等待的拦截器(execAndWaitIntercept)-- 一般的拦截器在API文档中都有案例
<action name="login" class="com.cyjch.action.loginAction">
     <result name="wait">wait.jsp</result>
     <result name="success" type="dispatcher">/loginSuc.jsp</result>
     <interceptor-ref name="timer"/><!--可在控制台显示用的毫秒数-->
     <interceptor-ref name="defaultStack"/>
     <interceptor-ref name="execAndWait"><!--必须在最后一个拦截器-->
    <param name="delay">3000</param><!--延时3秒-->
     </interceptor-ref>
 </action>

wait.jsp
---------------
<%
   response.setHeader("refresh", "3;URL=login.action");
%>
<html>
  <head>
    <meta http-equiv="refresh" content="2;URL=login.action">
  </head>
<body>
    <h1>数据已经提交,正在等服务返回信息,请耐心等待。。。</h1>
</body>
</html>


***令牌<s:token> : 用来防止重复提交信息
服务器产生令牌并放置到客户端一份,客户端提交信息后
和服务器端令牌比较,如一致则正常跳转并清空令牌;
客户端再后退提交则和服务器端令牌不一致,显示错误提示

<!--方法一:拦截器“token”重复提交后转向错误提示页面-->
<action name="login" class="com.cyjch.action.LoginAction">
    <result name="success" type="dispatcher">loginSuc.jsp</result>
    <result name="login">/login.jsp</result>
    <result name="invalid.token">/repeaSubmitError.jsp</result>
    <interceptor-ref name="token"></interceptor-ref>
    <interceptor-ref name="defaultStack"></interceptor-ref>
</action>


<!--方法二:拦截器“tokenSession”重复提交后转向成功结果页面-->
<action name="login" class="com.cyjch.action.LoginAction">
    <result name="success" type="dispatcher">loginSuc.jsp</result>
    <result name="login">/login.jsp</result>
    <result name="invalid.token">/repeaSubmitError.jsp</result>
    <interceptor-ref name="tokenSession"></interceptor-ref>
    <interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<%@ taglib uri="/struts-tags" prefix="s"%>

<form>
    <s:token></s:token>
</form>

***自定义拦截器(以下的案例在登录时并不使用,只作演示,正常时应用过滤器实现,对整个目录过滤)
AuthInterceptor.java//登录拦截器
-----------------------
public class AuthInterceptor extends AbstractInterceptor{
    public  String intercept(ActionInvocation invocation) throws Exception{
        //Map session=invocation.getInvocationContext().getSession();
        Map session = ActionContext.getContext().getSession();    
        //如果SESSION为空,则跳转到登录页面
        if(session.get("login" == null){
            retrun Action.LOGIN;
        }else{
            invocation.invoke();//如果有session,则表示用户已经登录,那么直接执行下一步
        }

    
}
}

struts.xml中配置
-----------------------
<package name="test" extends="struts-default">
    <global-results>
        <result name="login">/login.jsp</result>
    </global-results>
    <interceptors>
        <interceptor name="authInterceptor" class="com.cyjch.interceptor.AuthInterceptor"/>
        <!--自定义一个拦截器栈-->
        <interceptor-stack name="authStack">
            <interceptor-ref name="authInterceptor"></interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
        </interceptor-stack>
    </interceptors>
    <action name="success" >
        <result name="success" type="despatcher">/loginSuc.jsp</result>
        <result name="input">/login.jsp</result>
    </action>
    <!--对登录后进入的主页进行拦截-->
    <action name="suc" >
        <interceptor-ref name="authStack"/><!--直接引用认证的栈-->
        <result>/admin/main.jsp</result>
    </action>
</package>
-----------------------


***类型转换
自动转换类型
--------------
String - String
String - age
String - Date
String - double
绝大多数情况下,数据的类型转换不需要关注

***上传下载需要再看
1. 用户与权限管理模块 角色管理: 学生:查看实验室信息、预约设备、提交耗材申请、参与安全考核 教师:管理课题组预约、审批学生耗材申请、查看本课题组使用记录 管理员:设备全生命周期管理、审核预约、耗材采购与分发、安全检查 用户操作: 登录认证:统一身份认证(对接学号 / 工号系统,模拟实现),支持密码重置 信息管理:学生 / 教师维护个人信息(联系方式、所属院系),管理员管理所有用户 权限控制:不同角色仅可见对应功能(如学生不可删除设备信息) 2. 实验室与设备管理模块 实验室信息管理: 基础信息:实验室编号、名称、位置、容纳人数、开放时间、负责人 功能分类:按学科(计算机实验室 / 电子实验室 / 化学实验室)标记,关联可开展实验类型 状态展示:实时显示当前使用人数、设备运行状态(正常 / 故障) 设备管理: 设备档案:名称、型号、规格、购置日期、单价、生产厂家、存放位置、责任人 全生命周期管理: 入库登记:管理员录入新设备信息,生成唯一资产编号 维护记录:记录维修、校准、保养信息(时间、内容、执行人) 报废处理:登记报废原因、时间,更新设备状态为 "已报废" 设备查询:支持按名称、型号、状态多条件检索,显示设备当前可用情况 3. 预约与使用模块 预约管理: 预约规则:学生可预约未来 7 天内的设备 / 实验室,单次最长 4 小时(可设置) 预约流程:选择实验室→选择设备→选择时间段→提交申请(需填写实验目的) 审核机制:普通实验自动通过,高危实验(如化学实验)需教师审核 使用记录: 签到 / 签退:到达实验室后扫码签到,离开时签退,系统自动记录实际使用时长 使用登记:填写实验内容、设备运行情况(正常 / 异常),异常情况需详细描述 违规管理:迟到 15 分钟自动取消预约,多次违规限制预约权限 4. 耗材与安全管理模块 耗材管理: 耗材档案:名称、规格、数量、存放位置、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值