使用该自定义标签,可以在JSP页面中动态执行某个Spring Bean对象的一个方法,方法返回的结果存储在ValueStack中。该自定义标签在Spring2、Struts2、Hibernate3环境下测试通过。
一、java源代码
1、ServiceTag源代码
public class ServiceTag extends BaseBodyTagSupport {
private String beanName;
private String methodName;
private String id;
public List params = new ArrayList();
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public void setId(String id) {
this.id = id;
}
public int doEndTag() throws JspException {
Object bean = null;
Method method = null;
//取得bean对象
try{
bean = SpringContextUtil.getBean(beanName);
}catch(Exception ex){
throw new JspException("get bean error: " + beanName);
}
//通过反射取得方法
if(bean != null){
try {
method = bean.getClass().getMethod(methodName, TagUtil.getParameterTypes(params));
}catch(Exception e) {
throw new JspException("get method error: " + beanName + "." + methodName);
}
}else{
throw new JspException("ServiceTag Error: bean [" + beanName + "] is null");
}
//通过反射执行方法,得到结果
Object result = null;
if(method != null){
try {
result = method.invoke(bean, TagUtil.getParameterValues(params));
}catch(Exception e){
throw new JspException("method invoke error");
}
}
//将结果存储在ValueStack中
ValueStack vs = TagUtils.getStack(pageContext);
vs.getContext().put(id, result);
return EVAL_PAGE;
}
}
2、ServiceParamTag源代码
public class ServiceParamTag extends BaseBodyTagSupport {
private String name;
private Object value;
private String type;
public void setName(String name) {
this.name = name;
}
public void setValue(Object value) {
this.value = value;
}
public void setType(String type) {
this.type = type;
}
public int doEndTag() throws JspException {
Tag parent = getParent();
if(parent instanceof ServiceTag){
Map p = new HashMap();
p.put("paramName", name);
p.put("paramValue", value);
p.put("paramType", type);
((ServiceTag)parent).params.add(p);
}
return EVAL_PAGE;
}
}
3、公共方法源代码
//参数类型数组
public static Class[] getParameterTypes(List params) throws Exception{
Class[] c = new Class[params.size()];
for(int i=0;i<params.size();i++){
Map p = (Map)params.get(i);
String type = (String)p.get("paramType");
c[i] = Class.forName(type);
}
return c;
}
//参数值数组
public static Object[] getParameterValues(List params) throws Exception{
Object[] o = new Object[params.size()];
for(int i=0;i<params.size();i++){
Map p = (Map)params.get(i);
o[i] = p.get("paramValue");
}
return o;
}
二、tld文件源代码
<tag> <name>serviceBean</name> <tag-class>com.cjm.web.taglib.ServiceTag</tag-class> <body-content>JSP</body-content> <attribute> <name>beanName</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>methodName</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>id</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>serviceParam</name> <tag-class>com.cjm.web.taglib.ServiceParamTag</tag-class> <body-content>JSP</body-content> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>value</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>type</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
三、范例
1、java源代码
public class RoleService extends BaseService {
private RoleDao roleDao;
public RoleDao getRoleDao() {
return roleDao;
}
public void setRoleDao(RoleDao roleDao) {
this.roleDao = roleDao;
}
public Role getRole(String roleId){
return (Role)get(Role.class, roleId);
}
}
2、JSP页面源代码
<cjm:serviceBean beanName="roleService" methodName="getRole" id="result">
<cjm:serviceParam name="roleId" value="ADMIN" type="java.lang.String"/>
</cjm:serviceBean>
<s:property value="#result.roleName"/>