struts2 Action的参数处理和应用(数据访问和处理)-技术培训

2013/06/11 13:59:36 No Comments

这是一次为部门作的技术培训ppt,以下将其贴出,以方便大家查看。
下载地址:http://download.csdn.net/download/fly_m/5562553

本培训从最基本的数据如何进行访问和如何调用方法开始,逐步深入,讲解在数据处理当中涉及到的数据访问,转换,封装以及数据创建等内容。然后结合struts2,讲解在struts2中是如何运用这些理论来处理这些事项,并且是如何运行的;最后讲解了一个之前提到过如何在sturts2中使用带参数进行方法调用,并且是如何作到的。
涉及到以下主题

基本的数据访问
数据链
Request请求中的数据处理
数据转换和封装
泛型映射
Struts2中的数据处理
方法参数映射
Struts2中的数据增强处理

基本的数据访问

1.1    javaBean

public class T1 {
	private String username;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}
}
获取数据
    ${t1.username}
    t1.getUsername();
设置数据
    t1.username = “贾丽”
    t1.setUsername(“贾丽”)

可以使用propertyDescriptor来访问一个类的bean属性

		PropertyDescriptor[] descriptors = Introspector.getBeanInfo(T1.class).getPropertyDescriptors();
		PropertyDescriptor userNameDescriptor = null;
		for(PropertyDescriptor descriptor : descriptors) {
			if(descriptor.getName().equals("username")) {//found it
				userNameDescriptor = descriptor;
				break;
			}
		}

		T1 t1 = new T1();
		userNameDescriptor.getWriteMethod().invoke(t1, "贾丽");
		userNameDescriptor.getReadMethod().invoke(t1);

使用javaBean有以下的这些要求和限制(基本)

  • 属性字段是不是必须的
  • 至少有一个set或get方法
  • set只能有一个参数
  • get必须无参数
  • 当返回boolean时,可以使用is代替get
  •  
  • 不需要javaBean时,需要小心定义方法避免被访问

1.2    使用方法进行数据访问,如下代码所示:

	public String fetchMergeUsername() {
		return "某个机构:" + username;
	}

获取数据
    ${t1. fetchMergeUsername()}
    <s:property value=“t1. fetchMergeUsername()”/>

数据链

t1.userList[0].username=“贾丽”
t1.getUserList().get(0).setUsername(“贾丽”)
t1.userMap[“贾”].xm	或 t1.userMap.贾.xm
t1.getUserMap().get(“53011111”).getXm()
t1.user[0].addressList[1].name
t1.getUser()[0].getAddressList().get(1).getName()

针对数据链,就有一与之相对应的数据路径匹配,如下所示

t1/userList[0]/username	t1/userList/username
t1.getUserList().get(0).setUsername(“贾丽”)
t1/userMap/5301111/xm	t1/userMap/5301111/xm
t1.getUserMap().get(“53011111”).getXm()
t1/user[0]/addressList[1]/name		t1/user/addressList/name
t1.getUser()[0].getAddressList().get(1).getName()

用于过滤不满足条件的数据链
用于进行数据判断和控制逻辑走向

Request请求参数处理

  • 获取单个数据 如果有多个,则返回第1个

        String param1 = request.getParameter("param1");

  • 获取多个数据,如果只有一个,则返回长度为1的数组

        String[] param1 = request.getParameterValues("param1");

  • 获取的数据为字符串
  • 不能进行数据过滤,如只需要指定的数据
  • 需要数据转换

数据转换

来源为字符串,字符串数组
目的数据    基本类型 int,short,boolean    数字    时间    数字串    数字/时间/字符串 数组

4.1    转换为基本类型

Integer.parseInt
Long.parseLong
Boolean.parseBoolean
String. charAt(0)

4.2    转换为数字封装类型

Integer.valueOf
Long.valueOf
Boolean.valueOf
Character.valueOf(String.charAt(0))

4.3    转换为时间

yy-M-d ahh'时'mm'分'ss'秒'
yy-M-d H:mm:ss
yy-M-d ah:mm
yyyy-MM-dd'T'HH:mm:ss
yy-M-d
yyyy-M-d
yyyy'年'M'月'd'日'

4.4    来源为字符串数组目的数据类型不是数组,进行数据转换

目的为非字符串    以最后一个字符串转换为准
目的为字符串    将各个子转换按,进行拼接    如参数为123和456,则最终将转换为 123,456 在这种情况下,如果后台需要再转换为数字并且没有作数据验证,将会产生程序错误

数据封装

  • 以数据链为基础

        单个参数值只能表示单个属性值

  • 参数名满足数据链路径条件

        t1.user.id=123456
        t1.userList[0].name=贾丽
        t1.userMap[‘511’].username=5111111222

  • 需要进行数据封装成最终对象
参数值:
t1.username=111111
t1.password=123456
t1.addressList[0].address=成都
t1.addressList[1].address=北京
转换值:
t1:{
	username:111111
	password:123456
	addressList:[
		{address:成都},
		{address:北京}
			]
}

5.1    创建对象

javaBean
    调用无参构建方法 new T1()
List
    默认实现	new ArrayList()
Map
    默认实现	new HashMap()
Array
    默认实现	Array.newInstance(数据类型, 参数值数组长度)

5.2    数据组织

参数值
    t1.username=111111				t1.password=123456
    t1.addressList[0].address=成都	t1.addressList[1].address=北京
组织过程
    T1 t1 = new T1();							t1 is null
    t1.setUsername(111111)
    t1.setPassword(123456)
    t1.setAddressList(new ArrayList<Address>())		t1.addressList is null
    t1.getAddressList().add(new Address())			 t1.addressList[0] is null
    t1.getAddressList().get(0).setAddress(成都)		
    t1.getAddressList().add(new Address())			 t1.addressList[1] is null
    t1.getAddressList().get(1).setAddress(北京)	
实现过程
    获取对象		t1.getAddressList()
    初始化null对象	t1.setAddressList(new ArrayList<Address>())	
    设置属性		t1.getAddressList().get(1).setAddress(北京)

5.3    实现过程

参数
    t1.addressList[0].address=成都
    t1.nn=25
root对象
    获取属性	t1
        null	new T1() 并重新set回root
        获取addressList
            null	new ArrayList() 并重新set回t1
                获取 [0]
                    null	new Address()并重新set回addressList	此处即add
                    设置address
                        需要数据转换	String[] -> String	转换为 成都
        获取属性	t1
            设置nn
                需要数据转换	String[] -> int	转换为数字25

泛型映射

涉及到基本API知识

Field.getGenericType	返回该字段的泛型化表示
ParameterizedType 表示参数化类型,如 Collection<String>
    getActualTypeArguments()	返回表示此类型实际类型参数的 Type 对象的数组。
    getRawType()	返回 Type 对象,表示声明此类型的类或接口。强转换之
List	t1.addressList<Address>
    getField(“addressList”). getGenericType().getActualTypeArguments()	[0].getRawType()
    返回Address.class
Map	t1.userMap<String,User>
    getField(“addressList”). getGenericType(). getActualTypeArguments()	[1].getRawType()
    返回User.class

继续看刚才的数据转换实现

T1	addressList<Address>
t1.addressList[0].address=成都
root对象
    获取属性	t1
        null	new T1() 并重新set回root
        获取addressList
            null	new ArrayList() 并重新set回t1
            获取 [0]
                null	这里获取泛型类型为Address,new Address()并重新set回addressList	此处即add
                设置address
                    需要数据转换	String[] -> String	转换为 成都

struts2数据处理

7.1    实例化要设置参数的action对象

valueStack
上下文context	可存放request,response,session,application等
    root	可存放要处理的对象	使用类stack实现	可存放多个对象
    setValue/setParameter	可设置值
    findValue	可读取值
实例化要设置参数的action对象
    找到我们要访问的action
    初始化valueStack
    放入valueStack root中,并默认置为顶层

7.2    获取待处理参数

actionInvocation	执行器
    actionContext	执行上下文
request.getParameterMap		Map<String,String[]>
actionContext.put(PARAMETERS, parameterMap)
actionContext.getParameters
    actionContext.get(PARAMETERS)

7.3    过滤并处理参数

清除可能影响系统运行的参数信息
    不允许参数以request,session,application等内置对象开头
清除不满足条件的参数名
    不允许以数字,_等开头
其它处理
    将所有前后空格trim化	自实现

7.4    设置参数

Ognl
    Object Graph Navigation Language的缩写(对象图形导航语言)
    用于处理数据链的属性获取,设置等
    允许额外上下文存储,存储与主root相关的信息
setValue(expressionTree,contextMap,root,value)
    表达式		数据链	t1.addressList[0].address
    上下文		额外的数据信息	如 {request:requestImpl,response:responseImpl}
    root(数据栈) 往哪个根对象上设置值	action数据栈
    value		设置哪个值	成都

此外,在具体实现时,struts2中作了很多处理,如

数据转换
    Ongl不支持自动转换数据,需要自行注册转换器
    使用XworkBasicConverter
Null处理
    Ognl不支持自动创建null对象,需要自行注册nullHander
    使用InstantiatingNullHander进行处理	默认创建null对象

高级篇    增强数据处理和实现

8.1    现有缺陷

所有的参数都要有set/get
字段太多
set/get 太多
并不是每一个方法都要用到所有字段
程序中容易出错

8.2    愿景

no field,no set/get
only	private long idx and setIdx/getIdx
参数		user.username	& user.password		& idx
action
public String login(User user) {
user	is valid && idx is valid
}
jsp
    <s:property value=“user.username”/>
    <s:property value=“idx”/>

8.3    实现基础

数据链
set	t1.user
    if execute method has a param named t1 then use it, then set the subProperty user
    use the action property t1 and subProperty user
get	t1.user
    if execute method has a param named t1 then use it, then access the subProperty user
    use the action property t1 and subProperty user

8.4    实现细节

获取待执行方法的参数名称
    public String login(User user,List<Address> addressList)
方法名	login
返回类型	String.class
参数1	类型	User.class	名称	user
参数2	类型	List.class	名称	addressList		泛类型	Address.class

//此处所涉及到的技术,获取参数名称
LocalVariableTypeTable 
    用于调试器,以获取在方法运行时泛型局部变量的信息
使用 javac –g	或 javac –g:vars	可生成之
LocalVariableTableParameterNameDiscoverer. getParameterNames		from spring

//具体实现所要求的处理逻辑
增强root对象
    创建模拟方法参数的actionParam对象,封装与参数名相关信息
    可使用map实现之
增强propertyAccesstor	数据链处理器
    在处理list或map时,考虑actionParam对象
增强应用模型
    不再限制于action无参执行方法,可带参数执行
    在调用方法时,需要显示传递相应的参数
    参数可由root中actionParam获取

8.5    实现结果

action中仅少数property,由多数方法所共同访问
传递参数由method定义,表现业务意义
    由方法定义可知业务所处理数据范围
界面可访问传递参数信息
    参数值修改了,同样可访问到(同一引用)
    使用setContextValue设置外传参数
提高开发效率,不用写set/get,也不用考虑哪个字段可用
    需要新参数,直接在方法上追加即可,推荐使用业务对象

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201306110001.html

相关文章:

留下足迹