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的关系
    Ognl表达式语言_第1张图片

Struts标签

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


  

1.迭代list


"> <%--
--%>
编号 名称

2.迭代map


"> <%--
--%>
编号 名称
  

1.构建list集合


<%--ognl表达式可以取值,也可以动态构建集合--%>

2.构建map集合


//struts的数据流转
public class OgnlDemo3 extends ActionSupport {


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

        List list = new ArrayList();
        Map map = new HashMap();

        //初始化
        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表达式运行环境

获取request域中的数据


<%--property标签是对象类型的标签,默认支持ognl表达式,会从根元素取China名称对应的值--%>
<%--从费根元素取值--%>

<%--如果直接赋值需要用单引号--%> <%--值类型的标签,value值默认就是值类型,不支持ognl表达式--%> 国家:

Struts中常用的几个技术

数据回显

数据回显必须要用struts标签

//Action代码:
/**************数据回显******************/
//获取值栈
ValueStack vs = ac.getValueStack();
//移除栈顶元素
vs.pop();
//入栈
vs.push(user);
//jsp代码:


	用户名:
邮箱:
模型驱动

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


@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
   
   

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

举例2:
JSP
   
   

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

        ..
    }

举例3:(模型驱动)
JSP
   
   

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

        ..
    }

  • 步骤及原理
    步骤:

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

    分析:

/**
 * 1. 数据回显
 * 2. 模型驱动
 */
public class UserAction extends ActionSupport implements ModelDriven {
	
	// 封装请求数据
	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提供了防止表单重复提交拦截器:


案例:

  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/驱动

你可能感兴趣的:(Ognl表达式语言)