一、以text标签为例
1.配置
web.xml中
<taglib>
<taglib-uri>/html</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
2.jsp中的使用
<%@ taglib uri="/html" prefix="html" %>
<tr id="auctionBidModel">
<td align="right">
<span class="fc-hong">*</span>规格说明:
</td>
<td><html:text property="bean.bidModel" styleClass="input-text" /></td>
</tr>
3.经过struts标签处理器转换成一下内容
<input type="text" name="bean.bidModel" value="hhl 壹号" class="input-text">
二、看其转换过程,源码解析
BaseFieldTag.java
public int doStartTag()
throws JspException
{
/* <-MISALIGNED-> */ /* 81*/ TagUtils.getInstance().write(super.pageContext, renderInputElement());
/* <-MISALIGNED-> */ /* 83*/ return 2;
}
protected String renderInputElement()
throws JspException
{
/* <-MISALIGNED-> */ /* 93*/ StringBuffer results = new StringBuffer("<input");/* 95*/ prepareAttribute(results, "type", type);
/* 96*/ prepareAttribute(results, "name", prepareName());
/* 97*/ prepareAttribute(results, "accesskey", getAccesskey());
/* 98*/ prepareAttribute(results, "accept", getAccept());
/* 99*/ prepareAttribute(results, "maxlength", getMaxlength());
/* 100*/ prepareAttribute(results, "size", getCols());
/* 101*/ prepareAttribute(results, "tabindex", getTabindex());
/* 102*/ prepareValue(results);
/* 103*/ results.append(prepareEventHandlers());
/* 104*/ results.append(prepareStyles());
/* 105*/ prepareOtherAttributes(results);
/* 106*/ results.append(getElementClose());
/* 107*/ return results.toString();
}
主要看其value值的获取
protected void prepareValue(StringBuffer results)
throws JspException
{
/* 116*/ results.append(" value=\"");
/* 117*/ if(super.value != null)
/* 118*/ results.append(formatValue(super.value));
/* 120*/ else/* 120*/ if(redisplay || !"password".equals(type))
{/* 121*/ Object value = TagUtils.getInstance().lookup(super.pageContext, super.name, super.property, null);
/* 124*/ results.append(formatValue(value));
}
/* 127*/ results.append('"');
}
lookup方法,其中name为name = "org.apache.struts.taglib.html.BEAN";
public Object lookup(PageContext pageContext, String name, String scopeName)
throws JspException
{
/* 887*/ if(scopeName == null)
/* 888*/ return pageContext.findAttribute(name);
/* 892*/ try
{
/* <-MISALIGNED-> */ /* 892*/ return pageContext.getAttribute(name, instance.getScope(scopeName));
}/* 895*/ catch(JspException e)
{
/* <-MISALIGNED-> */ /* 895*/ saveException(pageContext, e);
/* <-MISALIGNED-> */ /* 896*/ throw e;
}
}
public Object lookup(PageContext pageContext, String name, String property, String scope)
throws JspException
{
/* 930*/ Object bean = lookup(pageContext, name, scope);
/* 931*/ if(bean == null)
{/* 932*/ JspException e = null;
/* 933*/ if(scope == null)
/* 934*/ e = new JspException(messages.getMessage("lookup.bean.any", name));
/* 936*/ else/* 936*/ e = new JspException(messages.getMessage("lookup.bean", name, scope));
/* 940*/ saveException(pageContext, e);
/* 941*/ throw e;
}
/* 944*/ if(property == null)
/* 945*/ return bean;
/* 950*/ try
{
/* <-MISALIGNED-> */ /* 950*/ return PropertyUtils.getProperty(bean, property);
}/* 953*/ catch(IllegalAccessException e)
{
/* <-MISALIGNED-> */ /* 953*/ saveException(pageContext, e);
/* <-MISALIGNED-> */ /* 954*/ throw new JspException(messages.getMessage("lookup.access", property, name));
}
/* 958*/ catch(IllegalArgumentException e)
{
/* <-MISALIGNED-> */ /* 958*/ saveException(pageContext, e);
/* <-MISALIGNED-> */ /* 959*/ throw new JspException(messages.getMessage("lookup.argument", property, name));
}
/* 963*/ catch(InvocationTargetException e)
{
/* <-MISALIGNED-> */ /* 963*/ Throwable t = e.getTargetException();
/* <-MISALIGNED-> */ /* 964*/ if(t == null)
/* <-MISALIGNED-> */ /* 965*/ t = e;/* 967*/ saveException(pageContext, t);
/* 968*/ throw new JspException(messages.getMessage("lookup.target", property, name));
}
/* 972*/ catch(NoSuchMethodException e)
{
/* <-MISALIGNED-> */ /* 972*/ saveException(pageContext, e);
}
/* <-MISALIGNED-> */ /* 973*/ throw new JspException(messages.getMessage("lookup.method", property, name));
}
其中最主要的bean的获取
Object bean = lookup(pageContext, name, scope);
由于scope为null,所以走如下流程
if(scopeName == null)
/* 888*/ return pageContext.findAttribute(name);
其中name为 name = "org.apache.struts.taglib.html.BEAN";那么根据这个name获取到的bean是什么,还需要看form标签
三、form标签
1.jsp中form标签使用
<html:form method="post" action="/store/manager/product/auctionProductAdd" >
经过标签处理器后变为
<form name="storeProductForm" method="post" action="/yunboce/store/manager/product/auctionProductAdd.do">
2.看其中的处理
FormTag.java
public int doStartTag()
throws JspException
{
/* 443*/ lookup();
/* 446*/ StringBuffer results = new StringBuffer();
/* 448*/ results.append(renderFormStartElement());
/* 450*/ results.append(renderToken());
/* 452*/ TagUtils.getInstance().write(super.pageContext, results.toString());
/* 455*/ super.pageContext.setAttribute("org.apache.struts.taglib.html.FORM", this, 2);
/* 457*/ initFormBean(); //重要的对上述bean的处理
/* 459*/ return 1;
}
看initFormBean方法,其中
protected void initFormBean()
throws JspException
{
/* 469*/ int scope = 3;
/* 470*/ if("request".equalsIgnoreCase(beanScope))
/* 471*/ scope = 2;
/* 474*/ Object bean = super.pageContext.getAttribute(beanName, scope);
/* 475*/ if(bean == null)
{
/* 477*/ bean = RequestUtils.createActionForm((HttpServletRequest)super.pageContext.getRequest(), mapping, moduleConfig, servlet);
/* 483*/ if(bean instanceof ActionForm)
/* 484*/ ((ActionForm)bean).reset(mapping, (HttpServletRequest)super.pageContext.getRequest());
/* 486*/ if(bean == null)
/* 487*/ throw new JspException(messages.getMessage("formTag.create", beanType));
/* 489*/ super.pageContext.setAttribute(beanName, bean, scope);
}
/* 491*/ super.pageContext.setAttribute("org.apache.struts.taglib.html.BEAN", bean, 2); //上述bean是在此处加入的
}
那么这个bean是什么,首先看Object bean = super.pageContext.getAttribute(beanName, scope);中参数beanName,其值是在lookup中赋值的
protected void lookup()
throws JspException
{
/* 738*/ moduleConfig = TagUtils.getInstance().getModuleConfig(super.pageContext);
/* 740*/ if(moduleConfig == null)
{/* 741*/ JspException e = new JspException(messages.getMessage("formTag.collections"));
/* 742*/ super.pageContext.setAttribute("org.apache.struts.action.EXCEPTION", e, 2);
/* 743*/ throw e;
}
/* 745*/ servlet = (ActionServlet)super.pageContext.getServletContext().getAttribute("org.apache.struts.action.ACTION_SERVLET");
/* 750*/ String mappingName = TagUtils.getInstance().getActionMappingName(action);
/* 751*/ mapping = (ActionMapping)moduleConfig.findActionConfig(mappingName);
/* 752*/ if(mapping == null)
{/* 753*/ JspException e = new JspException(messages.getMessage("formTag.mapping", mappingName));
/* 754*/ super.pageContext.setAttribute("org.apache.struts.action.EXCEPTION", e, 2);
/* 755*/ throw e;
}
/* 759*/ FormBeanConfig formBeanConfig = moduleConfig.findFormBeanConfig(mapping.getName());
/* 760*/ if(formBeanConfig == null)
{/* 761*/ JspException e = new JspException(messages.getMessage("formTag.formBean", mapping.getName(), action));
/* 763*/ super.pageContext.setAttribute("org.apache.struts.action.EXCEPTION", e, 2);
/* 764*/ throw e;
} else
{
/* 768*/ beanName = mapping.getAttribute(); //beanName的值,mapping中获取
/* 769*/ beanScope = mapping.getScope();
/* 770*/ beanType = formBeanConfig.getType();
/* 771*/ return;
}
}
看到这儿应该明白了,beanName是获取mapping中的属性,其值是在struts配置文件中配置的
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<data-sources></data-sources>
<form-beans>
<form-bean name="storeProductForm"
type="com.aebiz.store.product.controller.ProductForm" />
</form-beans>
<global-forwards></global-forwards>
<action-mappings>
<action input="/store/manager/auctionProduct/auctionProductAdd.jsp"
name="storeProductForm" path="/store/manager/product/auctionProductAdd"
scope="session"
type="com.aebiz.store.auctionProduct.controller.AuctionProductAction">
<forward name="add"
path="/store/manager/auctionProduct/auctionProductAdd.jsp" />
</action>
</action-mappings>
</struts-config>
至此,text标签中用到的bean就知道是什么了(此例中是ProductForm),value就是利用
PropertyUtils.getProperty(bean, property);获取
public static Object getProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
/* 290*/ return PropertyUtilsBean.getInstance().getProperty(bean, name);
}
public Object getProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
/* 715*/ return getNestedProperty(bean, name);
}
public Object getNestedProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
/* 631*/ if(bean == null)
/* 632*/ throw new IllegalArgumentException("No bean specified");
/* 634*/ if(name == null)
/* 635*/ throw new IllegalArgumentException("No name specified");
/* 638*/ int indexOfINDEXED_DELIM = -1;
/* 639*/ int indexOfMAPPED_DELIM = -1;
/* 640*/ int indexOfMAPPED_DELIM2 = -1;
/* 641*/ int indexOfNESTED_DELIM = -1;
/* 643*/ do
{
/* <-MISALIGNED-> */ /* 643*/ indexOfNESTED_DELIM = name.indexOf('.');
/* <-MISALIGNED-> */ /* 644*/ indexOfMAPPED_DELIM = name.indexOf('(');
/* <-MISALIGNED-> */ /* 645*/ indexOfMAPPED_DELIM2 = name.indexOf(')');
/* <-MISALIGNED-> */ /* 646*/ if(indexOfMAPPED_DELIM2 >= 0 && indexOfMAPPED_DELIM >= 0 && (indexOfNESTED_DELIM < 0 || indexOfNESTED_DELIM > indexOfMAPPED_DELIM))/* 648*/ indexOfNESTED_DELIM = name.indexOf('.', indexOfMAPPED_DELIM2);
/* 651*/ else/* 651*/ indexOfNESTED_DELIM = name.indexOf('.');
/* 653*/ if(indexOfNESTED_DELIM < 0)
/* 654*/ break;
/* 656*/ String next = name.substring(0, indexOfNESTED_DELIM);
/* 657*/ indexOfINDEXED_DELIM = next.indexOf('[');
/* 658*/ indexOfMAPPED_DELIM = next.indexOf('(');
/* 659*/ if(bean instanceof Map)
/* 660*/ bean = ((Map)bean).get(next);
/* 661*/ else/* 661*/ if(indexOfMAPPED_DELIM >= 0)
/* 662*/ bean = getMappedProperty(bean, next);
/* 663*/ else/* 663*/ if(indexOfINDEXED_DELIM >= 0)
/* 664*/ bean = getIndexedProperty(bean, next);
/* 666*/ else/* 666*/ bean = getSimpleProperty(bean, next);
/* 668*/ if(bean == null)
/* 669*/ throw new NestedNullException("Null property value for '" + name.substring(0, indexOfNESTED_DELIM) + "'");
/* 673*/ name = name.substring(indexOfNESTED_DELIM + 1);
} while(true);
/* 676*/ indexOfINDEXED_DELIM = name.indexOf('[');
/* 677*/ indexOfMAPPED_DELIM = name.indexOf('(');
/* 679*/ if(bean instanceof Map)
/* 680*/ bean = ((Map)bean).get(name);
/* 681*/ else/* 681*/ if(indexOfMAPPED_DELIM >= 0)
/* 682*/ bean = getMappedProperty(bean, name);
/* 683*/ else/* 683*/ if(indexOfINDEXED_DELIM >= 0)
/* 684*/ bean = getIndexedProperty(bean, name);
/* 686*/ else/* 686*/ bean = getSimpleProperty(bean, name); //最终用到反射获取value
/* 688*/ return bean;
}
其中有对点字符的处理等,现获取bean的值在获取其中属性的值,因此最初的标签中的bean.bidModel的value就获取到了
public Object getSimpleProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
/*1088*/ if(bean == null)
/*1089*/ throw new IllegalArgumentException("No bean specified");
/*1091*/ if(name == null)
/*1092*/ throw new IllegalArgumentException("No name specified");
/*1096*/ if(name.indexOf('.') >= 0)
/*1097*/ throw new IllegalArgumentException("Nested property names are not allowed");
/*1099*/ if(name.indexOf('[') >= 0)
/*1100*/ throw new IllegalArgumentException("Indexed property names are not allowed");
/*1102*/ if(name.indexOf('(') >= 0)
/*1103*/ throw new IllegalArgumentException("Mapped property names are not allowed");
PropertyDescriptor descriptor;
/*1108*/ if(bean instanceof DynaBean)
{/*1109*/ descriptor = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
/*1111*/ if(descriptor == null)
/*1112*/ throw new NoSuchMethodException("Unknown property '" + name + "'");
/*1115*/ else/*1115*/ return ((DynaBean)bean).get(name);
}
/*1119*/ descriptor = getPropertyDescriptor(bean, name);
/*1121*/ if(descriptor == null)
/*1122*/ throw new NoSuchMethodException("Unknown property '" + name + "'");
/*1125*/ Method readMethod = getReadMethod(descriptor);
/*1126*/ if(readMethod == null)
{/*1127*/ throw new NoSuchMethodException("Property '" + name + "' has no getter method");
} else
{
/*1132*/ Object value = invokeMethod(readMethod, bean, new Object[0]);
/*1133*/ return value;
}
}