struts2标签笔记

来源:互联网 发布:数据质量自查报告 编辑:程序博客网 时间:2024/03/29 10:00

一、select标签
常用的有以下几个属性:

(1)struts2中的select 标签中,必须设置的属性是list。

(2)select标签的list中必须有值,不然会报错。不过如果没有值,可以加上headerKey, headerValue,这样也可以通过。如:
<s:select list="manuList" name="manufacturersid"
     headerKey="0" headerValue="--制造商--"
     listKey="id" listValue="manufacturerName"/> 
其中,即使list中有值,我们也通常会加上headerKey, headerValue,即列表中显示的第一个选项。要注意的是,headerKey不可以为空,不可以为-1。

(3)list属性:通常是在action中定义的,必须是一个可以迭代的源,如为一个List, Map, Set等。如果是一个Map,那么map的key就对应于select标签中的value,map中的value就对应于select标签中的option。而如果是一个List或者是一个Set,那么可以通过listKey和listValue指定。

(4)listKey和listValue:listKey即对应于select标签中的value, listValue即对应于select标签中的option。

(5)name属性:即是表单中select的名称。

二、radio标签
例子:<s:radio list='#{1:"是",0:"否"}' name="isAdmin" value="isAdmin" key="isAdmin"/>
根据Action中isAdmin属性的值(0表示不是管理员,1表示是管理员),设置radio的选中状态。
对标签的理解:name表示对应action中的属性名,value表示radio的值,list大概是这个标签用来指定radio的选项的值-显示文字的列表。value的值被设定为什么,它所对应的选项就处于选中状态。
问题解决途径:首先用value='<s:property value="isAdmin" />' 来取这个属性的值,property标签单独写出来是可以取到值的,但是就是无法设置radio的选中项。网上搜了一下,据说如果value是字符串类型的需要给value值加上单引号,比如值为1就要写成'1',如果value是非字符串类型的,就不用加单引号了。isAdmin是Integer类型的,不需要加单引号。于是改变value的取值方式,直接写成value="isAdmin",可能是strust2标签都可以自己从Action中取属性值的,这回对radio选项的选中设置起效了。
新的问题:由于radio标签是放在迭代器标签里的,以上设置选中项只对最后一条记录起作用。
可能是因为radio标签的名字都是isAdmin的缘故,采用动态指定名字的方法:
<s:iterator value="list" id="user" status="st">  
<s:radio list='#{1:"是",0:"否"}' name="user.id" value="isAdmin" id="user.id"/>
</s:iterator>
不知道是name设置失败,还是无论将name设置为什么都默认为同一组radio,在同一页中,还是只有一个radio选项选中。
没办法,只好用html的radio标签了...
<s:iterator value="list" id="user" status="st"> 
 <s:if test="isAdmin== 1">
 <input type="radio" name='<s:property value="id" />' value="1" checked>是
 <input type="radio" name='<s:property value="id" />' value="0" >否
 </s:if>
 <s:else>
 <input type="radio" name='<s:property value="id" />' value="1">是
 <input type="radio" name='<s:property value="id" />' value="0" checked>否
 </s:else>
</s:iterator>
试了两三个小时还是得用html标签 崩溃了
接下来是radio的取值问题。在action中使用ServletActionContext.getRequest().getParameter("...")是无法取到radio的值的。为了能让action获得isAdmin这个值,在action中增加了isAdmin属性及其get、set方法,然后在jsp页面中增加名为isAdmin的隐藏字段,通过JavaScript给这个隐藏字段赋值
一,增加隐藏字段<s:hidden id="isAdmin" name="isAdmin">
二,在提交给action之前给这个隐藏字段赋值 通过按钮点击事件,由于生成的radio使用当前迭代对象的id作为name,因此可以这样写按钮 <input type="button" value="更 改" onclick="update('<s:property value="id" />')"/>
注意update里的取值方式,如果用el表达式,会出现取不到值的情况,不知道是不是struts2对EL支持问题。
然后脚本
 function update(radioName){
  var obj=document.getElementsByName(radioName);
  var radioValue="undefined";
  for(i=0;i<obj.length;i++){
   if(obj[i].checked){
    radioValue=obj[i].value;
    break;
   }
  }
  //alert("radioValue"+radioValue);
  document.getElementById("isAdmin").value=radioValue;
  //var v=document.getElementById("isAdmin").value;
  //alert("v"+v);
  var f=document.getElementById("userf");
  f.action="/edit.action";
  f.submit();
 }

No result defined for action 404 错误
1.spring中对bean的scope使用了默认的session值。这样做可能会导致的情况是参数被缓存,以致于登录失败后重新登录时,报上面的input未定义404错误。这种情况的话,可以设置bean的scope为prototype,这样重复提交就没有问题了。
2.没有通过struts2的validate验证。
3.页面元素中有重命名,而后台action类的对应的接收此同名参数的变量没有写成数组类型。这种错误,可以在action中重写ActionSupport中的addActionError,addActionMessage,addFieldError方法,然后在这三个方法的实现体中设置断点跟踪。或者在input转向的页面中加入标签s:fielderror查看错误信息。
4.页面属性与Action中属性数据类型不匹配,或者action中get,set方法没有写全。
5.Action中的属性值为空的时候,Struts2的默认拦截器会报错,但是又找不到input的Result,不能够把错误返回,所以报这种错误。解决方法:
1),在页面中给空值赋默认值。
2),重新定义一个Action,去掉空值的成员变量。
3),添加input的Result,并在这个页面给出提示<s:fielderror/>

终于找到原因了,在页面中加了一个s:hidden标签。在form是提交给分页action方法的基础上,想提交给修改isAdmin属性的一个action,结果首先分页的action出错了,一直报results的404错误。改了spring中对bean的scope设定,还是有问题,于是在struts2的xml配置文件中给分页action加了result,在result指向的页面中加了s:fielderror标签,输出错误信息:Invalid field value for field "isAdmin".意思是外地无效的字段值isAdmin。于是给这个隐藏字段赋了默认值,结果还是报错,么办法,把这个隐藏字段改为html标签的,然后把action中对应的isAdmin属性包括get set方法一起删了,终于没问题了。
但是,迭代器的list里面放的是user,user类里有isAdmin属性,为什么是"外地无效的字段值"呢?明明是能取到这个值的。而且,如果空属性也会导致result的错误,在页面还放了一个名为word的s:hidden标签,action中也有这个属性,为什么不报错呢???

三、doubleselect标签
<s:doubleselect headerValue="--选择商品类别--" headerKey="0"
     name="category"
     list="categoryList" listKey="id" listValue="categoryName"
     doubleName="product" doubleList="productMap.get(top)"
     doubleListKey="id" doubleListValue="title"
     formName="searchForm"/>  
说明:这是一个级联下拉框。根据选择的一级下拉框的值确定二级下拉框中的内容。
要注意的是,这个标签一定要放在form中,并且标签中的属性formName一定要赋值,这个值与包着它的form的name一致。如果不给formName赋值,会报错。
标签中的属性--name是一级下拉列表的名字,doubleName是二级列表的名字,这两个名字和action中的属性名对应。list是组成一级下拉列表的option集合,对应的doubleList是组成二级列表的集合。listKey指option项的值,listValue指option的显示内容,listkey和listvalue是list的成员。相对应的doubleKey与doubleValue是二级列表中的。
另外 这个标签是分行的,如果不需要分行,可以将form包在一个div中然后给div指定class=你的样式名,在style文件中写上
.noBr{
 .doubleselect br{
  display:none;
 }  
}
本来在s:doubleselect所在的td标签中加class,但是没效果,仍然分行了,没办法只好按照网上的方法,在form外面包一层div,设置div样式,可惜,还是不行。
疑问 现在的做法是,种类下拉列表框中是种类list: List<Category> categoryList;
产品下拉列表框中放的是各个种类对应的产品的list: Map<Category,List<Product>> productMap;
在标签中指定二级下拉列表框值是用 doubleList="productMap.get(top)" 。
一、top是指map中keylist还是valuelist或者其他的什么.
二、二级下拉列表框的map的key必须是一级列表框的成员么。

 

有人知道么??

原创粉丝点击