Ognl表达式语言

概述

  • OGNL表达式:
    OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts2 框架使用OGNL作为默认的表达式语言。
  • OGNL优势
    • 支持对象方法调用,如xxx.doSomeSpecial();
    • 支持类静态的方法调用和值访问,表达式的格式:
      @[类全名(包括路径名)]@[方法名|值名],例如:
      @java.lang.String@format(‘foo%s’,‘bar’)
      或@tutorial.MyConstant@APP_NAME;
    • 支持赋值操作和表达式串联,如price=100,discount=0.8
      calculatePrice(),这个表达式会返回80.
    • 访问OGNL上下文(OGNL context)和ActionContext;
    • 操作集合对象
  • 总结
    OGNL有一个上下文(context)的概念,上下文也就是一个MAP结构,它实现了java.util.Map的接口。

分析:

  • Struts框架默认支持ognl表达式语言(struts框架默认必须引入的包:ognl.jar)
  • 作用:
    • 页面取值使用。
    • EL表达式语言,用于页面取值,jsp页面取值标准,(默认直接可以使用)
    • ognl表达式语言,struts标签默认支持的表达式语言。必须配置struts标签用,不能离开struts标签直接使用。

OgnkContext对象

OgnkContext对象是Ognl表达式语言的核心。
源码类:public class OgnlContext implements Map {…}

//OgnlContext用法
public class OgmlDemo1{

    /**
     * 1.使用ognl表达式语言取值,取非根元素的值,必须要用#
     * @throws OgnlException
     */
    @Test
    public void testOgnl1() throws OgnlException {
        //创建一个Ognl上下文对象
        OgnlContext context = new OgnlContext();
        //存放数据
        context.put("cn","china");
        User user = new User();
        user.setId(1);
        user.setName("jack");
        //往非根元素放入数据,取值的时候表达式要用"#"
        context.put("user",user);


        //获取数据(map)
        String value = (String) context.get("cn");
        System.out.println(value);

        //构建一个ognl表达式,再解析表达式
        Object ognl = Ognl.parseExpression("#user.adress.province");

        Object value1 = Ognl.getValue(ognl,context,context.getRoot());
        System.out.println(value1);

    }

    /**
     * 2.使用ognl表达式语言取值,取根元素的值,不用带#
     * @throws OgnlException
     */
    @Test
    public void testOgnl2() throws OgnlException {
        //创建一个Ognl上下文对象
        OgnlContext context = new OgnlContext();
        User user = new User();
        user.setId(1);
        user.setName("jack");
        //往根元素放入数据,取值的时候表达式  不要用 "#"
        context.setRoot(user);
        //构建一个ognl表达式,再解析表达式
        Object ognl = Ognl.parseExpression("adress.province");

        Object value = Ognl.getValue(ognl,context,context.getRoot());
        System.out.println(value);


    }

    /**
     * 3.Ognl对静态方法调用的支持
     * @throws OgnlException
     */
    @Test
    public void testOgnl3() throws OgnlException {
        //创建一个Ognl上下文对象
        OgnlContext context = new OgnlContext();

        //Ognl表达式语言,调用类的静态方法
//        Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
        //由于Math类在开发中比较常用,所以也可以这样使用
        Object ognl = Ognl.parseExpression("@@floor(10.9)");
        Object value = Ognl.getValue(ognl,context,context.getRoot());
        System.out.println(value);
    }

}

ValueStack

ValueStack,即值栈对象
是整个struts数据存储的核心,即中转站。
	用户每次访问struts的action,都会创建一个action对象、值栈对象、ActionContext对象。
然后把Action对象放入到值栈中。最后再把值栈对象放到request中,传入jsp页面。
(key:struts.valueStack);开发者只需要通过ActionContext对象就可以访问struts的其他的
关键对象。(ActionContext是给开发者使用的,便于学习与使用)
问题:
  • OgnlContext与ValueStack的关系
    在这里插入图片描述

Struts标签

struts标签取值,就使用了ognl表达式语言。

<body>
  <h1>1.迭代list</h1><br/>
  <table border="1">
    <tr>
      <td>编号</td>
      <td>名称</td>
    </tr>
    <s:iterator var="user" value="#request.list" status="st">
    <tr class="<s:property value="#st.even?'even':'odd'"/> ">
      <td><s:property value="#user.id"/></td>
      <td><s:property value="#user.name"/></td>
    </tr>
      <%--<s:property value="#st.even"/><br/>--%>
    </s:iterator>
  </table><br/>

  <h1>2.迭代map</h1><br/>
  <table border="1">
    <tr>
      <td>编号</td>
      <td>名称</td>
    </tr>
    <s:iterator var="en" value="#request.map" status="st">
      <tr class="<s:property value="#st.even?'even':'odd'"/> ">
        <td><s:property value="#en.key"/></td>
        <td><s:property value="#en.value.name"/></td>
      </tr>
      <%--<s:property value="#st.even"/><br/>--%>
    </s:iterator>
  </table>
  <h1>1.构建list集合</h1><br/>
  <%--ognl表达式可以取值,也可以动态构建集合--%>
  <s:iterator var="str" value="{'a','b'}">
    <s:property value="#str"></s:property>
  </s:iterator>
  <h1>2.构建map集合</h1><br/>
  <s:iterator var="en" value="#{'cn':'China','usa':'American'}">
    <s:property value="#en.key"/>
    <s:property value="#en.value"/>
  </s:iterator>
//struts的数据流转
public class OgnlDemo3 extends ActionSupport {


    @Override
    public String execute() throws Exception {
        //测试迭代标签

        List<User> list = new ArrayList<User>();
        Map<Integer,User> map = new HashMap<Integer,User>();

        //初始化
        for(int i=1;i<11;i++){
            User user = new User(i,"jack"+i);

            list.add(user);
            map.put(user.getId(),user);
        }

        //保存非根
        ActionContext.getContext().getContextMap().put("list",list);
        ActionContext.getContext().getContextMap().put("map",map);
        //保存根
//        ActionContext.getContext().getValueStack().getRoot().push(list);


        return super.execute();
    }

}

struts ognl 中几个特殊符号
  • #:获取非根元素值,动态创建map集合
  • $:配置文件提取
  • %:提供一个ognl表达式运行环境
<h1>获取request域中的数据</h1><br/>
  <%--property标签是对象类型的标签,默认支持ognl表达式,会从根元素取China名称对应的值--%>
  <s:property value="China"/><br/>
  <%--从费根元素取值--%>
  <s:property value="#request.cn"/><br/>
  <s:property value="%{#request.cn}"/><br/>
  <%--如果直接赋值需要用单引号--%>
  <s:property value="'China'"/>

  <%--值类型的标签,value值默认就是值类型,不支持ognl表达式--%>
  国家:<s:textfield name="txtCountry" value="%{#request.cn}"/>

Struts中常用的几个技术

数据回显

数据回显必须要用struts标签

//Action代码:
/**************数据回显******************/
//获取值栈
ValueStack vs = ac.getValueStack();
//移除栈顶元素
vs.pop();
//入栈
vs.push(user);
//jsp代码:
<!--数据回显技术:s:textfield 会自动查找根元素数据(Ognl表达式语言取值)-->
<s:form action="#">
	用户名:<s:textfield name="name"/><br/>
	邮箱:<s:textfield name="email"/><br/>
</s:form>


模型驱动

Struts运行时候,会执行默认的拦截器栈,其中有一个拦截器,模型驱动拦截器:

<interceptor 
name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
@Override
    public String intercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();

        if (action instanceof ModelDriven) {
            ModelDriven modelDriven = (ModelDriven) action;
            ValueStack stack = invocation.getStack();
            Object model = modelDriven.getModel();
            if (model !=  null) {
            	stack.push(model);
            }
            if (refreshModelBeforeResult) {
                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
            }
        }
        return invocation.invoke();
    }

  • 引入

prams拦截器,可以把请求数据自动填充的action的属性中

举例1:
JSP
   <input type=text name=userName />
   <input type=text name=pwd />

Action
    class UserAction{
        // 封装请求数据
        private String userName;
        private String pwd;
        //.. set方法
    }

举例2:
JSP
   <input type=text name=user.userName />
   <input type=text name=user.pwd />

Action
    class UserAction{
        // 封装请求数据
        private User user;

        ..
    }

举例3:(模型驱动)
JSP
   <input type=text name=userName />
   <input type=text name=pwd />

Action
    class UserAction{
        // 封装请求数据
        private User user;

        ..
    }

  • 步骤及原理
    步骤:

    1. 实现ModelDriver接口
    2. 实现接口方法: 接口方法返回的就是要封装的对象
    3. 对象一定要实例化。

    分析:

/**
 * 1. 数据回显
 * 2. 模型驱动
 */
public class UserAction extends ActionSupport implements ModelDriven<User> {
	
	// 封装请求数据
	private User user = new User();
	public void setUser(User user) {
		this.user = user;
	}
	public User getUser() {
		return user;
	}
	
	// 实现模型驱动接口方法
	@Override
	public User getModel() {
		return user;
	}
	
	
	public String add() {
		// 测试: 使用了模型驱动,是否数据正常? Ok
		System.out.println(user);
		return "success";
	}

防止表单重复提交

Struts提供了防止表单重复提交拦截器:

<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>

案例:

  1. 建库建表
-- 删除数据库
DROP DATABASE hib_demo;
-- 创建数据库
CREATE DATABASE hib_demo DEFAULT CHARACTER SET utf8;
-- 建表
CREATE TABLE employee (
   id INT PRIMARY KEY AUTO_INCREMENT,
   empName VARCHAR(20),
   workDate DATE      -- 入职时间
);
  1. 搭建环境
    • 搭建struts环境
    • 组件:c3p0/dbutils/驱动
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OGNL(Object-Graph Navigation Language,对象图导航语言)是一个强大的表达式语言,可以用于Java的各种应用程序中,包括Struts、JavaServer Faces、JavaServer Pages等。在Mybatis中,OGNL表达式可以用于Mapper XML文件中的各种标签中,例如`<if>`、`<where>`、`<set>`、`<foreach>`等标签中。 OGNL表达式可以用于获取Java对象的属性值、调用Java对象的方法、进行算术运算、比较运算、逻辑运算等。例如: ```xml <select id="selectByCondition" resultType="com.example.User"> select * from user where name like #{keyword} and age >= #{minAge} <if test="maxAge != null"> and age <= #{maxAge} </if> </select> ``` 在这个例子中,`#{keyword}`、`#{minAge}`、`#{maxAge}`都是OGNL表达式,表示获取Java对象中的属性值。例如,如果传入的参数对象是一个`User`对象,那么`#{keyword}`可以表示`user.getKeyword()`方法的返回值,`#{minAge}`可以表示`user.getMinAge()`方法的返回值。 在OGNL表达式中,还可以进行算术运算、比较运算、逻辑运算等。例如,`age >= #{minAge}`表示将`age`和`#{minAge}`进行比较,判断`age`是否大于等于`#{minAge}`;`age <= #{maxAge}`表示将`age`和`#{maxAge}`进行比较,判断`age`是否小于等于`#{maxAge}`。 除了基本的运算符和表达式OGNL还提供了丰富的函数和操作符,例如`in`操作符、`not`操作符、`contains`函数、`size`函数等。这些函数和操作符可以方便地进行集合操作、字符串操作等。在使用OGNL表达式时,需要注意语法的正确性和安全性,以避免可能的安全漏洞。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值