OGNL

OGNL

    • OGNL的概述
        • EL表达式与OGNL的比较
    • OGNL的java环境入门
        • OGNL调用对象的方法
        • OGNL访问对象的静态资源
        • 将数据存入root访问
        • 将数据存入context访问
    • OGNL的Struts2环境入门
        • OGNL调用对象的方法
        • OGNL访问对象的静态资源
    • 值站(ValueStack)
        • 值站的概述
        • 值站的内部结构
    • 值栈的操作
        • 保存数据到值栈中的root以及获取root值栈的数据
            • 方式一:
            • 方式二:
        • 保存数据到值栈中的context以及获取context值栈的数据
    • OGNL中的特殊字符
        • #号
        • %号
        • $号

OGNL的概述

OGNL中文名对象图导航语言,是一个比EL表达式更加强大很多倍的语言

EL表达式与OGNL的比较

EL:从域对象中获取数据,从EL的11个对象中获取数据
OGNL:可以调用对象的方法,可以获取Struts2的值栈数据

OGNL的java环境入门

OGNL调用对象的方法

  1. 获得context对象
  2. 获得根对象
  3. 执行对象的方法
	public void demo1() throws OgnlException {
        //获得context
        OgnlContext context = new OgnlContext();
        //获得根对象
        Object root = context.getRoot();
        //执行表达式
        Object value = Ognl.getValue("'helloword'.length()", context, root);
        System.out.println(value);
    }

OGNL访问对象的静态资源

访问静态资源的表达式:
@类名@调用的方法

 	public void demo2() throws OgnlException {
        //获得context
        OgnlContext context = new OgnlContext();
        //获得根对象
        Object root = context.getRoot();
        //执行表达式:@类名@方法名
        Object value = Ognl.getValue("@java.lang.Math@random()", context, root);
        System.out.println(value);
    }

将数据存入root访问

  1. 创建一个实体类,生成get和set方法,以及有参无参
  2. 获得context对象
  3. 将数据存入root
  4. 获取根对象root
  5. 获取值
	public void demo3() throws OgnlException {
        //获得context
        OgnlContext context = new OgnlContext();
        //执行表达式
        context.setRoot(new User("aaa","21231"));
        //获得根对象
        Object root = context.getRoot();
        Object username = Ognl.getValue("username", context, root);
        Object password = Ognl.getValue("password", context, root);
        System.out.println(username+"..."+password);
    }

将数据存入context访问

  1. 获得context对象
  2. 获得根对象root
  3. 向context中存入数据
  4. 执行表达式,注意执行表达式时,键需要加上#
	public void demo4() throws OgnlException {
        //获得context
        OgnlContext context = new OgnlContext();
        //获得根对象
        Object root = context.getRoot();
        context.put("name","张三");
        Object value = Ognl.getValue("#name", context, root);
        System.out.println(value);
    }

OGNL的Struts2环境入门

导包

<%@ taglib prefix="s" uri="/struts-tags" %>

OGNL调用对象的方法

	<s:property value="'hello world'.length()">s:property>

OGNL访问对象的静态资源

  1. 配置struts.xml,修改常量struts.ognl.allowStaticMethodAccess的值,因为struts2默认是关闭静态资源访问的功能的

    <constant name="struts.ognl.allowStaticMethodAccess" value="true">constant>
    
  2. 访问静态资源

    <s:property value="@java.lang.Math@random()">s:property>
    

注意: 有的时候在struts.xml里配置常量的时候没有效果,我们也可以在web.xml里面配置常量的值

 	<filter>
        <filter-name>strutsfilter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
        <init-param>
            <param-name>struts.ognl.allowStaticMethodAccessparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>

    <filter-mapping>
        <filter-name>strutsfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

值站(ValueStack)

值站的概述

  • 值站其实类似于一个容器(Struts2的框架当中的数据都会保存在ValueStack中,在任何地方都可以取,可以在页面上取,可以在action中取,可以在配置文件中取,而request只能在页面中取)
  • ValueStack是一个接口,OgnlValueStack是它的实现类
  • ValueStack贯穿了整个action的生命周期(意思是有一个Action实例,就会有一个ValueStack对象)

值站的内部结构

  • ValueStack中有两个主要的区域
    • root区域:其实就是一个ArrayList,里面一般放置一些对象。获取root的数据是不需要加#
    • context区域:其实就是一个Map,里面放置的是web开发常用的对象数据的引用,获取context数据需要加#
      • request
      • session
      • application
      • parameters
      • attr
  • 操作值栈,通常指的是操作ValueStack中的root区域。

查看值栈的结构:

<%@taglib prefix="s" uri="/struts-tags" %>

    <s:debug>s:debug>

值栈的操作

保存数据到值栈中的root以及获取root值栈的数据

方式一:
  1. 创建一个全局变量,并生成get方法
  2. 给全局变量赋值
  3. 前端获取数据

代码实现:
前端:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Titletitle>
head>
<body>
    <s:debug>s:debug>
    <s:property value="user.username">s:property>
    <s:property value="user.password">s:property>
body>
html>

后端:

public class ValueStackDemo1 extends ActionSupport {
    public User getUser() {
        return user;
    }

    private User user;
    @Override
    public String execute() throws Exception {
        user = new User("张三","2222");
        return SUCCESS;
    }
}

结果展示:
在这里插入图片描述
点击Debug:
OGNL_第1张图片

方式二:
  1. 获取valueStack对象
  2. 创建对象给对象赋值
  3. 将值压入值栈中

代码实现:
前端获取数据

	<s:debug>s:debug>
	<s:property value="username">s:property>
    <s:property value="password">s:property>
    <s:property value="name">s:property>

后端:

	 User user = new User("张三","2222");
	 ValueStack valueStack = ActionContext.getContext().getValueStack();
	 valueStack.push(user);
	 //set一般用来传集合
     valueStack.set("name","李四");

保存数据到值栈中的context以及获取context值栈的数据

后端存储数据:

		ServletActionContext.getRequest().setAttribute("name","张三");
        ServletActionContext.getRequest().getSession().setAttribute("name","李四");
        ServletActionContext.getServletContext().setAttribute("name","王五");

前端获取数据(EL表达式可以获取到request对象的值):

	<s:property value="#request.name">s:property>
    <s:property value="#session.name">s:property>
    <s:property value="#application.name">s:property>
    ${name}

OGNL中的特殊字符

#号

  1. 获取context的数据

  2. 构建map集合
    例如:
    使用s:iterator 标签遍历list集合{‘aa’,‘bb’,‘cc’},结果表示使用i和#i都可以取到值

    <s:iterator value="{'aa','bb','cc'}" var="i">
        <s:property value="i">s:property> -- <s:property value="#i">s:property> <br />
    s:iterator>
    

    在这里插入图片描述
    使用s:iterator 标签遍历map集合#{‘aa’:‘11’,‘bb’:‘22’,‘cc’:‘33’},结果表示使用key–value和#i.key–i.value都可以取到值

    	<s:iterator value="#{'aa':'11','bb':'22','cc':'33'}" var="i">
    	    <s:property value="key">s:property> -- <s:property value="value">s:property> <br />
    	
    	    <s:property value="#i.key">s:property> -- <s:property value="#i.value">s:property> <br />
    	s:iterator>
    

    OGNL_第2张图片

demo
比较下面两个代码的区别:

<s:radio list="{'',''}" name="sex" label="性别" /> <br />

<s:radio list="#{'1':'','2':''}" name="sex2" label="性别" /> <br>

%号

  • 强制解析成OGNL,在有些标签中是不识别OGNL的,需要使用%强制解析
    demo:

    <%
        request.setAttribute("name","张三");
    %>
    
    姓名:<s:textfield name="text" value="%{#request.name}">s:textfield>
    
  • 强制不解析OGNL表达式,在有些标签遇到OGNL表达式会自动解析,使用%可以让其不解析

    <s:property value="%{'#request.name'}">s:property>
    

$号

  • 在配置文件中使用OGNL

  • 属性文件:

    demo

    user.welcome=欢迎,${#session.user.username}
    
  • xml文件

    demo
    配置文件下载

    	<action name="download" class="xxx.DownloadAction">
    		<result type="stream">
    			<param name="Content-Type">文件类型param>
    			<param name="Content-Disposition">attachment;filename=${文件名}param>
    		result>
    	action>
    

你可能感兴趣的:(框架)