Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30480342
  • 博文数量: 708
  • 博客积分: 12163
  • 博客等级: 上将
  • 技术积分: 8240
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-04 20:59
文章分类

全部博文(708)

分类: Java

2008-04-15 13:01:26

上午要做一个更新功能,
是这样设计的:
首先是一个一览画面,把信息逐条显示,用
把ID属性作成超连接,并传递这个ID所在的bean,因为一览画面已经包含有每条所有信息,所以传递过去后直接显示在文本框中就ok,不用再查数据库。
问题就在这里:如何传递对象?
在网上查到文章:
 

关于<html:link>标签在URI后面传参数的问题
在struts标签<html:link>的page属性指定的URI后面传递参数可以有几种方式:
1.若明确参数名和参数值则直接在URI后输出,
如:<html:link page="/test.do?action=add">add</html:link>
2.对于参数值不确定的,paramName和paramProperty来输出,用paramId属性指定参数名。
对于paramName指定的对象应该存在于page、request、session、application其中之一。一般来说,是从Action类传过来的,作为request的属性之一(requst.setAttribute("name",object))。
如果paramName指定的对象是action的ActionForm,则无需使用request.setAttribute方法。
例:<html:link page="/test.do" paramId="userid" paramName="uid">uname</html:link>
若参数值是一个bean对象的属性值(比如ActionForm,或者集合中存放的对象)则:
<html:link page="/test.do" paramId="userid" paramName="user" paramProperty="uid">uname</html:link>

3.若两个参数,一个确定一个不确定,则是以上两种方法的结合,即:
<html:link page="/test.do?action=modify" paramId="userid" paramName="uid">modify</html:link>

4.对于多个参数的问题,可以使用一个HashMap集合对象来存放所有的参数名及对应的参数值的方式,paramName属性值指定为该HashMap集合对象即可。
举例:
<%
//代码理想的位置应该是在action中

//可以在jsp页面测试

java.util.HashMap pms = new java.util.HashMap();
pms.put("code", "001002");
pms.put("name", "tester");
pms.put("alias", new String[]{"matin","jack"});
request.setAttribute("params", pms);
%>
<html:link action="/test.do" name="params" >test</html:link>
编译后的结果:<a href="/test.do?code=001002&name=tester&alias=matin&alias=jack">test</a>
这种方式虽然可以解决传多参数的问题,但是实现起来也比较麻烦,特别是对记录集中的数据逐条列出的时候

5.针对有的网友在<html:link>标签中嵌入使用jsp脚本(scriptlet)的问题,
例如:
<html:link page="/test.do?code=<%=varible%>">add</html:link>,这种写法是错误的,是无法编译的。
有的网友认为在struts标签内是不允许使用jsp脚本的,这种说法也不准确。如果前面的写法改成:
<html:link page="<%="/test.do?code="+varible%>">add</html:link>,就可以被执行,但是要注意URL相对路径的问题。

虽然在struts标签中嵌入jsp脚本不是真正意义上的struts应用,但是有时在委曲求全的情况下也只能如此了,除非使用自定义标签。比如在form表单中可能需要根据具体数据让某个字段是只读的,就可以用嵌入jsp脚本来实现:
<%
boolean rdonly=false;
if(2==2) rdonly=true;
%>
<html:text property="userid" readonly="<%=rdonly%>" />


6.另外一种比较变态的方法,既不是真正意义上的struts,也不符合xml规范。那就是在<a>标签中用<bean:write>标签输出参数值。
如:<a href="test.do?uid=" property="userid"/>&name=" property="username"/>">test</a>



了解到这里之后,感觉到一丝遗憾,因为如果只有paramId,paramName,paramProperty这三个属性的话,那么对于html:link标签来说,就永远只能自定义一个参数,如果需要定义多个参数,如http://serverip:portno/projectcontextname/html-link.do?a=3&b=5&y=9这样的链接URL来说,就无能为力了

如果要定义多个参数,就需要手动拼URL,定义在page属性里面,这就失去了使用标签的意义了。

在此情况下,怀着失望的心情,打开了Struts的源码,开始查看这个标签的源码,忽然发现,这个标签完全是可以自定义多个参数的,关键就在name属性上
首先来看一段如何自定义多个参数的代码,如下:

=========================================================
<%
java.util.HashMap newValues = new java.util.HashMap();
newValues.put("floatProperty", new Float(444.0));
newValues.put("intProperty", new Integer(555));
newValues.put("stringArray", new String[]
{ "Value1", "Value2", "Value3" });
pageContext.setAttribute("newValues", newValues);
%>

<html:link page="/html-link.do" name="newValues">
Float, int, and stringArray via name (Map)
</html:link>
=========================================================

原来使用name属性就可以将一个Map类型的变量放入request、session、application、page四种范围的容器内,然后取个key值,填在name属性里就可以了
Struts将自动读取这个Map类型对象的所有key和key所定义的对象,然后自动生成HTML代码
好比上述的例子,将生成如下的HTML代码:
<a href="">
Float, int, and stringArray via name (Map)</a>

愿望终于达到了,也充分证明了Struts的实力,但在这段实现中,查找name定义的对象这点在前面几次的源码剖析中已经很明确了(使用的是TagUtils.java中的lookup方法)
但得到这个对象后,Struts是如何读出key值集合和key值对应的对象的呢?代码在此:

=========================================================
// Add the required request parameters

boolean question = temp.indexOf(?) >= 0;
//这里的params变量就是我们输入的Map类型的对象

//就是这句代码可以得到key值集合

Iterator keys = params.keySet().iterator();
while (keys.hasNext()) {
String key = (String) keys.next();
Object value = params.get(key);
if (value == null) {
if (!question) {
url.append(?);
question = true;
} else {
url.append(separator);
}
url.append(this.encodeURL(key));
url.append(=); // Interpret null as "no value"

} else if (value instanceof String) {
if (!question) {
url.append(?);
question = true;
} else {
url.append(separator);
}
url.append(this.encodeURL(key));
url.append(=);
url.append(this.encodeURL((String) value));
} else if (value instanceof String[]) {
String values[] = (String[]) value;
for (int i = 0; i < values.length; i++) {
if (!question) {
url.append(?);
question = true;
} else {
url.append(separator);
}
url.append(this.encodeURL(key));
url.append(=);
url.append(this.encodeURL(values[i]));
}
} else /* Convert other objects to a string */ {
if (!question) {
url.append(?);
question = true;
} else {
url.append(separator);
}
url.append(this.encodeURL(key));
url.append(=);
url.append(this.encodeURL(value.toString()));
}
}

以上是看一个网友的Blog上得来的,自己正在被这个问题困扰,在那本<struts程序员查询辞典>,关于<html: link>标签的name属性上是这么说明的:指定其元素作为查询字符串参数添加到当前链接的URL中的java.util.map对象的名字.如 果还指定了property属性,该属性定义的对象中的某个字段将调用一个获取值的方法,来返回其元素作为查询字符串参数被添加到当前连接的URL的 java.util.map对象.

   偶最终的实现方法,无奈,

<a href="../legalaid/legalAidSeAction.do?action=select7&id=" property="ID"/>&t19_n04=" property="t19_n04"/>">
     <bean:write name="legalaid3" property="t19_c02"/>
</a>

 

但是这里面就是没有怎么传递单个对象的

最后没辙,变相解决的,

思路:

把ID做request参数,传到这个页面的action中,遍历结果集中每个bean的id,

把相等的bean放入request,跳转更新页面。

这个已经实现,但是究竟能不能直接传递bean呢?

希望有高手回复一下。

阅读(3318) | 评论(0) | 转发(0) |
0

上一篇:Struts标签库-另一篇

下一篇:strust学习心得

给主人留下些什么吧!~~