在Struts应用中,到JSP页面上显示下拉列表框应该是常有的事。
在基于是Struts的MVC框架中显示下拉框,有好些方法,用自定义标签库就是其中之一。
若我们的此下拉框是放在基于HtmlForm中的。Struts可以通过ActionForm来保存其历史记录(不排除我们人为地给此ActionForm清理一下)。然而此自定义标签库却没有此功能!因为它没有通过过ActionForm中的字段来保存其记录。所以选择的时候可以根据自己的需要来定(我觉得在ActionForm中处理List列表框真的是一件非常庞大的工程:) )。
JSP中对标签的应用:
<%
@ taglib uri
=
"
/WEB-INF/self-html.tld
"
prefix
=
"
test
"
%>
<
div
class
="formitem"
>
<
span
class
="parameter_name"
>
所属栏目:
</
span
>
<
span
class
="parameter_value"
>
<
test:category
name
="dto.id"
type
="17"
/>
</
span
>
</
div
>
web.xml配置文件中:
<!--
self Tag Library Descriptors
-->
<
taglib
>
<
taglib-uri
>
/WEB-INF/self-html.tld
</
taglib-uri
>
<
taglib-location
>
/WEB-INF/self-html.tld
</
taglib-location
>
</
taglib
>
self-html.tld定义:
<
taglib
>
<
tlibversion
>
1.0
</
tlibversion
>
<
jspversion
>
1.1
</
jspversion
>
<
shortname
>
netedu
</
shortname
>
<
tag
>
<
name
>
category
</
name
>
<
tagclass
>
com.CategoryTag
</
tagclass
>
<
bodycontent
>
empty
</
bodycontent
>
<
info
>
tag here
</
info
>
<
attribute
>
<
name
>
name
</
name
>
<
required
>
false
</
required
>
<
rtexprvalue
>
false
</
rtexprvalue
>
</
attribute
>
<
attribute
>
<
name
>
id
</
name
>
</
tag
>
</
taglib
>
以后自己就有什么扩展的需要就是在这儿加参数了!
总算是到了标签库的定义的地方了:
/** */
/**
*
@author
test
*/
public
class
CategoryTag
extends
TagSupport
{
/**/
/*
(non-Javadoc)
* @see javax.servlet.jsp.tagext.Tag#doStartTag()
*/
public
int
doStartTag()
throws
JspException
{
//
TODO Auto-generated method stub
try
{
JspWriter out
=
pageContext.getOut();
//
jspwriter是一个隐含对象,用于向jsp网页输出内容。输出的目标由
CategoryManager manager
=
getManager();
List options
=
null
;
if
(type
==
Constants.SORT_VALUE_ARCHIVE_YEAR)
options
=
getArchiveYear();
if
(options
==
null
||
options.size()
==
0
)
options
=
UMParameterUtil.getParameters(type);
if
(options
==
null
||
options.size()
==
0
)
options
=
manager.getCategorys(type);
BaseCategoryDTO dto;
ParametersDTO param;
Object o
=
null
;
if
(bean
!=
null
)
o
=
RequestUtils.lookup(pageContext, bean, property, scope);
if
(o
!=
null
&&
((
!
(o
instanceof
Integer))
&&
(
!
(o
instanceof
Long))
&&
(
!
(o
instanceof
List))
&&
(
!
(o
instanceof
Long[])) ))
throw
new
JspException(
"
bean or property must be instanceof Long or List
"
);
out.print(
"
<select
"
+
TaglibUtil.attrFormat(
"
name
"
, name));
out.print(TaglibUtil.attrFormat(
"
id
"
, id));
out.print(TaglibUtil.attrFormat(
"
multiple
"
, multiple));
out.print(TaglibUtil.attrFormat(
"
class
"
, styleClass));
out.print(TaglibUtil.attrFormat(
"
size
"
, String.valueOf(size)));
out.print(TaglibUtil.attrFormat(
"
onchange
"
, onchange));
out.print(TaglibUtil.attrFormat(
"
style
"
, style));
out.print(TaglibUtil.attrFormat(
"
disable
"
, disable));
out.print(
"
>
"
);
if
(showAll) out.print(
"
<option value=-1>不限</option>
"
);
if
(showNull) out.print(
"
<option value=''></option>
"
);
printOption(out, options, o);
out.print(
"
</select>
"
);
}
catch
(IOException ioException)
{
throw
new
JspException(ioException.getMessage());
}
//
catch
return
(SKIP_BODY);
//
return super.doStartTag();
}
注:
有options= manager.getCategorys(type);其中manager是CategoryManager类。此方法返回的一个List就是下拉框的值。具体实现可由我们自己来定义好了!记得在JSP中也有<test:category name="dto..id" type="17"/>,其中的type="17"(比如说可以是传一个DB中的一个表的一个外键)就是此方法中的初始化参数值了(关于此标签库的定义的一些setter and getter方法中也舍了).既然是库当然要通用。这个type就是通用的一个关键入口,不过显然这样一样可读性打了几分折扣。
TaglibUtil.attrFormat("name", name)的方法如下:
public
class
TaglibUtil
{
public
static
String attrFormat(String attrName, Object attrValue)
{
if
(attrValue
!=
null
)
return
"
"
+
attrName
+
"
=
"
+
"
\
""
+ attrValue +
"
\
""
;
else
return
"
"
;
}
}
还有一个就是printOption,这个方法应该比较重要了。它负责生成了列表框的选择的值与名称。如:
if
(
!
excludeFlag)
{
out.print(
"
<option
"
+
TaglibUtil.attrFormat(
"
value
"
, id
.toString()));
out.println(TaglibUtil.attrFormat(
"
sysValue
"
, sysValue));
if
(o
!=
null
)
{
if
(o
instanceof
Long)
{
if
(id.equals(o)) out.print(
"
selected
"
);
}
else
if
(o
instanceof
List)
{
if
(((List)o).contains(id))
out.print(
"
selected
"
);
}
else
if
(o
instanceof
Long[])
{
if
(isSelected(id,(Long[])o))
out.print(
"
selected
"
);
}
}
//
if (dto.getId().equals(o)) out.print("selected ");
out.print(
"
>
"
);
out.print(name);
out.print(
"
</option>
"
);
}
不要郁闷id是如何来的。当然是从options= manager.getCategorys(type)中来的了。
也许说得不是太详细,代码也有些残缺。不过实现过程基本全在这里了。我觉得它非常棒,直到我用到它的onchange,style时!简直在直接跟使用html中的list一样!
out.print(TaglibUtil.attrFormat("size", String.valueOf(size)));
out.print(TaglibUtil.attrFormat("onchange", onchange));
out.print(TaglibUtil.attrFormat("style", style));
out.print(TaglibUtil.attrFormat("disable", disable));
至少给我们指明了一些自定义标签库的经验!