首页 > 代码库 > Struts2:OGNL表达式详解

Struts2:OGNL表达式详解

OGNL用于操作ValueStack中的数据。它负责两件事。第一是在接收HTTP请求时将请求中的字符串转换成Java中的类型,比如int、String等,并赋值给ValueStack上的JavaBean,第二是在页面渲染的时候,从ValueStack中获取属性,并将Java类型转换成字符串进行输出。整个过程如下图:


(侵权可删)


在HTTP的请求参数中,可以包含OGNL表达式(这就是当初Struts2爆重大漏洞的原因了)。

  • user.name=xxx表示给user属性中的name属性进行赋值。
  • name[0]=xxxname[1]=xxx,表示一个数组。
  • user.name=xxx&user.name=yyy,表示一个List。由于框架只知道user是个列表,但不知道列表中元素的类型,因此需要在ClassName-conversion.properties文件中配置元素类型。这个文件的内容例如:Element_users=com.example.util.User
  • user[‘name‘],表示一个Map,默认Key和Value类型都是String。Key类型可以在ClassName-conversion.properties中指定,加入Key_user=java.lang.Integer即可。
  • #{1,2,3} 表示一个整数的list
  • #{1:"one",2:"two"} 表示一个map
  • users.{? #this.age > 30} 过滤出年龄在30岁以上的用户。不过,这种业务逻辑应该在数据库层面来完成,工程中不推荐使用。
  • @vs@USER 访问静态方法。

ClassName-conversion.properties要和class文件放在同一个目录中。

对于List、Map对象来说,开发者不能自己初始化List,否则会发生错误。List、Map的初始化应该由框架去完成。


在struts.xml的配置文件中,需要使用${xxx}来包含OGNL表达式,在普通的页面中,由于${xxx}是JSP自带的EL表达式语言,所以需要将$符号换成\%。


PHP中也有类似的语法,而且更加简洁。个人还是比较喜欢PHP中的参数语法。简洁明了:user[]表示数组,user[xxx]表示map,这种语法比较简洁。


自定义类型。将HTTP请求中的参数字符串转换成自定义类型的对象。可以通过继承StrutsTypeConverter进行实现。

public class CircleTypeConverter extends StrutsTypeConverter {
    public Object convertFromString(Map context, String[] values, Class toClass) {
        ...
    }
    
    public String convertToString(Map context, Object c) {
        ...
    }
}

实现了转换器之后需要告诉框架什么时候使用这个转换器。在ClassName-conversion.properties中指定字段的类型转换器:circle=com.example.CircleTypeConverter。这样就能将请求表单中的字符串转换成Circle对象了。上面的配置只能指定特定表单的特定字段使用我们自己定义的转换器,如果要让整个网站中所有的Circle对象都使用CircleTypeConversion,可以在WEB-INF/classes/xwork-conversion.properties中指定com.example.Circle=com.example.CircleTypeConverter


OGNL可以引用Servlet内置对象,下面几种示例展示了这种功能。它的原理是,由于ActionContext中有getSession、getRequest等方法,#号表示从ActionContext中通过getSession、getRequest等方法获取对象。
  • #session[‘user‘],使用session对象中的user。
  • #request[‘user‘],使用request对象中的user。


OGNL可以调用方法,默认调用栈顶对象中的方法。语法如下:

<s:property value=http://www.mamicode.com/"testMethod()"/>>

Struts2:OGNL表达式详解