struts2-OGNL和类型转换(structs 自动数据表单获取)

OGNL和类型转换

前面已经做了简单的介绍,将用户提交的内容映射成动作的属性,将属性内容通过标签显示在JSP页面中。这些过程是通过OGNLObject-Graph Navigation Language对象图导航语言)实现的。它在框架中实现两方面的功能:数据转移和类型转换。

数据转移就是上面的将参数转换成属性,或将属性显示在页面。类型转换就是:如何将页面上提交的String转换成属性中的floatdate属性。或反过来。OGNL的作用方式如下:

 

当我们发送一个HTTP请求(通过JSPservlet),请求内容可能是:username=sunyu&age=24:user.username=sunyu&user.age=24总之,HTTP请求的参数是以字符串形式发送的.请求经过框架时,框架会自动生成请求action 的实例,并将它放在值栈ValueStack.OGNL将值映射成属性(通过params拦截器,前面已经说过).JSP页面中,我们通过<s:property value=”user.age” />:<s:property />标签来访问ValueStack中的内容.

 

Struts2自带了一些类型转换器,可以对HTTP字符串和下列JAVA类型进行转换(自动进行):

1.       String

2.       Boolean/Boolean:truefalse字符串可以被转换成布尔值的原始类型有包装类.

3.       Character/char:

4.       Integer/int,Float/float,Long/long,Double/double

5.       Date:当前LocaleSHORT格式的字符串,:98/10/11

6.       Array:

7.       List:默认使用String填充.

8.       Map:默认使用String填充.

举例:

1.       原始类型

<input name=”user.username” />

<input name=”user.age” />

<input name=”user.birthday” />

类里:

private String username;

private Double age;

private Date birthday

框架会自动帮我们转换.我们能成功获得到.

2.       数组;

<input name=”ages” />

<input name=”ages” />

<input name=”ages” />

上面这些指向ages属性:Double[] ages

<input name=”names[0]” />

<input name=”names[1]” />

<input name=”names[2]” />

上面指向:String[] names

但要注意的是:当我们提交上面的整个表单时,HTTP请求如下:

ages=12,33,55

names[0]=jack

names[1]=green

names[2]=mary

可以看出差别了.

当框架转移ages参数时,它先找到ages属性,并且知道ages参数是一个有3个字符串的数组.由于动作上的ages属性也是一个数组,这样OGNL创建一个新的数组,值是参数的值,并将它赋给动作.并且它知道动作的属性agesdouble类型的.它会自动将参数的值转换成对应的类型.

3.       List

用法和数组一模一样.只不过JAVA中是List但注意,这里最好是用泛型来声明.不然它会自动将参数转换成String类型并存入List. 泛型用法:

<input name=”names[0].username” />

<input name=”names[1].username” />

接收:List<User> names

第一个Userusername为第一个input提交的值

4.       Map

list不同,Map需要一个键,一个值.:

<input name=”nameMap.mary” />

<input name=”nameMap.hellen” />

<input name=”nameMap[‘Sunyu’]” />

上面一种用点语法,一种用方括号.但两种意思一样,当我们提交上面表单后,后台获得的值如下:

Map<String,String> nameMap;值为:

mary --- >第一input提交的值.

hello --- >第二input提交的值.

…..

自定义类型转换

上面那些类型框架自带的类型转换器会帮我们完成转换.但有些时候我们会有一些自定义类型需要使用.这时候我们就要自定义类型转换器,告诉框架如何去转换.

所有类型转换器必须实现ognl.TypeConverter接口.因为HTTP请求的内容是String类型的,所以我们的类型转换器都是从String到某类型或从某类型到String.同样,我们自定义的类型转换器也要实现这两个方法.

Struts2提供了比ognl.TypeConverter更方便的方法:StrutsTypeConverter,它实现了前面的接口.而且定义了两个抽象方法,即我们要实现的方法.看下例:

String  Circle间转换

package manning.chapterFive.utils;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

import com.opensymphony.xwork2.util.TypeConversionException;

public class CircleTypeConverter extends StrutsTypeConverter {

 

         public Object convertFromString(Map context, String[] values, Class toClass) {

                   String userString = values[0];

                   Circle newCircle = parseCircle ( userString );

                   return newCircle;

         }

 

         public String convertToString(Map context, Object o) {

                  

                   Circle circle = (Circle) o;

                   String userString = "C:r" + circle.getRadius();

                  

                   return userString;

         }

        

         private Circle parseCircle( String userString ) throws TypeConversionException {

                   Circle circle = null;

                  

                   int radiusIndex = userString.indexOf('r') + 1;

                   System.out.println("userString = " + userString);

                  

                   if (!userString.startsWith( "C:r")  )

                            throw new TypeConversionException ( "Invalid Syntax");

                  

                   int radius;

                   try {

                            radius = Integer.parseInt( userString.substring( radiusIndex ) );

                   }catch ( NumberFormatException e ) {

                            throw new TypeConversionException ( "Invalid Integer Value for Radius"); }

                                                      

                   circle = new Circle();

                   circle.setRadius( radius );

                

                   return circle;

         }

}

有了转换逻辑,我们要让框架知道什么时候,在哪里使用这个转换器.有两种配置方式:

对给定action声明,或全局声明.

1.       专用声明

在要进行转换的类同级目录下新建资源文件:

ActionName-conversion.properties

ActionName就是要在上面应用转换的类名,:ConvertTest-conversion.properties

里面的内容是:

circle- CircleTypeConverter

前面的circle就是在要应用转换类里那个类型的变量名.后面就是转换类的详细路径,包括它的包路径.

2.       全局声明

和上面不同,全局声明要求在classpath下新建一个:

xwork-conversion.properties文件,里面内容:

包路径.Circle=转换器路径.CircleTypeConverter

等号前是目录类型的详细路径,后面的转换器类的全路径.


但要注意的是:

在实际开发中,最好少利用struts2的类型转换功能,因为框架帮我们自动进行类型转换的消耗是很大的,所以最好是我们在类中都保存字符类型的值,页面只负责显示就行了.比如时间,我们直接转换成2010-xx-xx...等格式的,而不保存为Date类型. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值