使用该自定义标签,可以在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"/>