在struts中,我们都知道他拥有自己的标记,如下:
最后,他们会生成如下html标签:
有的时候,我们会选择不采用struts的html便签等等,其实这样的话,不是一个很好的处理,因为struts的标签不仅仅是相对于重复代码的封装,更多的是为了配合其自身某些功能的实现;
比如,我们会问,为什么我们会使用html标签呢,他真的比我们直接使用html标签更加的方便吗,我们还得花费时间来学习他,其实不是这样的,你看了下面的例子就会明白;
一个页面有两个标签,分别采用的是上面的两种表单形式,我们在actionmapping的action中进行配置;
我们可以看见我们把scope设置成为了session,我们填充这个表单进行提交到一个新的页面,然后在往回跳转,如果采用struts的html标签的话,我们可以看见我们的表单中自动填充了我们进行提交的值,而如果我们采用的是html的标签,那么这个表单是空的,默认实现的,这一节,我们来分析一个html表单与后台的对应,以及后台的值如何推到前台;
首先,在页面上,脚本会将前台页面的表单form与后台的actionForm对应起来,这是前台与后台的对应,我们来看一下如何实现的:
在RequestProcessor的process的方法中,存在下面两句代码:
在createActionForm方法中,我们可见如下:
在populate方法中,有如下:
我们可以看见知道这里为止,前台页面和后台的数据对应起来了;
那么,我们怎么可能使得修改后台的actionForm表单的数据使得前台和后台的数据对应起来呢?就像我们一开始的时候那样,actionForm是session范围的,使用了struts的标签我们依然能够使得其自动填充表单;
那么我们就要分析一下struts的标签了;
首先,在页面上,我们会解析<html:form action=“” />标签,表单控件要与后台对应起来,那么这个对应的单位是form,所以,空间应用都被包含在一个form中;
form表单据称于TagSupport,他为整个表单与后台的对应做了很多预先的工作;
lookUp()
initFormBean:初始化了表单对象;
然后接下来就是解析<html:text property="name" />之类的表单控件呢:
最后,会为form元素“封口”
从上面,我们可见在struts里面是不支持表单嵌套的,表单的顺序定义还是可以的;这样不会造成pageContext页面标记的被覆盖等现象;
- <html:form action="coreyForm">
- <html:text property="name" />
- <html:password property="pwd" />
- <html:submit value="submit" />
- </html:form>
- <form action="./coreyForm.do">
- <input type="text" name="name" />
- <input type="password" name="pwd" />
- <input type="submit" value="submit" />
- </form>
比如,我们会问,为什么我们会使用html标签呢,他真的比我们直接使用html标签更加的方便吗,我们还得花费时间来学习他,其实不是这样的,你看了下面的例子就会明白;
一个页面有两个标签,分别采用的是上面的两种表单形式,我们在actionmapping的action中进行配置;
- <action path="/coreyForm" type="CoreyFormAction" scope="session"/>
首先,在页面上,脚本会将前台页面的表单form与后台的actionForm对应起来,这是前台与后台的对应,我们来看一下如何实现的:
在RequestProcessor的process的方法中,存在下面两句代码:
- ActionForm form = processActionForm(request, response, mapping);
- processPopulate(request, response, form, mapping);
- protected ActionForm processActionForm(HttpServletRequest request,
- HttpServletResponse response, ActionMapping mapping) {
- //生成一个新的ActionForm
- ActionForm instance =
- RequestUtils.createActionForm(request, mapping, moduleConfig,
- servlet);
- if (instance == null) {
- return (null);
- }
- // Store the new instance in the appropriate scope
- if (log.isDebugEnabled()) {
- log.debug(" Storing ActionForm bean instance in scope '"
- + mapping.getScope() + "' under attribute key '"
- + mapping.getAttribute() + "'");
- }
- //从ActionMapping中得到其scope,保存到设置的范围中;
- if ("request".equals(mapping.getScope())) {
- request.setAttribute(mapping.getAttribute(), instance);
- } else {
- HttpSession session = request.getSession();
- session.setAttribute(mapping.getAttribute(), instance);
- }
- return (instance);
- }
- ActionForm instance =
- //在其范围域中查找ActionForm对象,如果存在则复用,
- lookupActionForm(request, attribute, mapping.getScope());
- if ((instance != null) && config.canReuse(instance)) {
- return (instance);
- }
- //如果不存在,则重新生成新的;
- return createActionForm(config, servlet);
- 如果不是上传的文件,那么:
- if (!isMultipart) {
- names = request.getParameterNames();
- }
- //得到该页面提交的参数
- while (names.hasMoreElements()) {
- String name = (String) names.nextElement();
- String stripped = name;
- if (prefix != null) {
- if (!stripped.startsWith(prefix)) {
- continue;
- }
- stripped = stripped.substring(prefix.length());
- }
- if (suffix != null) {
- if (!stripped.endsWith(suffix)) {
- continue;
- }
- stripped =
- stripped.substring(0, stripped.length() - suffix.length());
- }
- Object parameterValue = null;
- if (isMultipart) {
- parameterValue = multipartParameters.get(name);
- } else {
- parameterValue = request.getParameterValues(name);
- }
- // Populate parameters, except "standard" struts attributes
- // such as 'org.apache.struts.action.CANCEL'
- if (!(stripped.startsWith("org.apache.struts."))) {
- properties.put(stripped, parameterValue);
- }
- }
- // 将参数和actionForm的属性对应起来;形成了页面数据和后台的对应;
- try {
- BeanUtils.populate(bean, properties);
- } catch (Exception e) {
- throw new ServletException("BeanUtils.populate", e);
- } finally {
- if (multipartHandler != null) {
- // Set the multipart request handler for our ActionForm.
- // If the bean isn't an ActionForm, an exception would have been
- // thrown earlier, so it's safe to assume that our bean is
- // in fact an ActionForm.
- ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
- }
- }
- }
我们可以看见知道这里为止,前台页面和后台的数据对应起来了;
那么,我们怎么可能使得修改后台的actionForm表单的数据使得前台和后台的数据对应起来呢?就像我们一开始的时候那样,actionForm是session范围的,使用了struts的标签我们依然能够使得其自动填充表单;
那么我们就要分析一下struts的标签了;
首先,在页面上,我们会解析<html:form action=“” />标签,表单控件要与后台对应起来,那么这个对应的单位是form,所以,空间应用都被包含在一个form中;
- public class FormTag extends TagSupport
- public int doStartTag() throws JspException {
- postbackAction = null;
- //查找表单的范围域,bean的名字,以及类型;
- this.lookup();
- //生成html的form控件的text;
- StringBuffer results = new StringBuffer();
- results.append(this.renderFormStartElement());
- results.append(this.renderToken());
- //将<form action="XXXX" 等输入到页面上;
- TagUtils.getInstance().write(pageContext, results.toString());
- //将当前的form信息保存在pageContext下面
- //使得在form标记结束之前,之间的表单控件能够找到
- //自己所属的form,以及后台的actionForm;
- pageContext.setAttribute(Constants.FORM_KEY, this,
- PageContext.REQUEST_SCOPE);
- this.initFormBean();
- return (EVAL_BODY_INCLUDE);
- }
- protected void lookup() throws JspException {
- // 首先查找到模块;
- moduleConfig = TagUtils.getInstance().getModuleConfig(pageContext);
- if (moduleConfig == null) {
- JspException e =
- new JspException(messages.getMessage("formTag.collections"));
- pageContext.setAttribute(Globals.EXCEPTION_KEY, e,
- PageContext.REQUEST_SCOPE);
- throw e;
- }
- //得到其标签的action属性,我们需要根据他在模块配置信息中找到
- //对应的配置信息;
- String calcAction = this.action;
- // If the action is not specified, use the original request uri
- if (this.action == null) {
- HttpServletRequest request =
- (HttpServletRequest) pageContext.getRequest();
- postbackAction =
- (String) request.getAttribute(Globals.ORIGINAL_URI_KEY);
- String prefix = moduleConfig.getPrefix();
- if (postbackAction != null && prefix.length() > 0 && postbackAction.startsWith(prefix)) {
- postbackAction = postbackAction.substring(prefix.length());
- }
- calcAction = postbackAction;
- } else {
- //找到了对应的action配置信息;
- ActionConfig actionConfig = moduleConfig.findActionConfigId(this.action);
- if (actionConfig != null) {
- this.action = actionConfig.getPath();
- calcAction = this.action;
- }
- }
- servlet =
- (ActionServlet) pageContext.getServletContext().getAttribute(Globals.ACTION_SERVLET_KEY);
- // Look up the action mapping we will be submitting to
- String mappingName =
- TagUtils.getInstance().getActionMappingName(calcAction);
- //得到了actionMapping信息;
- mapping = (ActionMapping) moduleConfig.findActionConfig(mappingName);
- if (mapping == null) {
- JspException e =
- new JspException(messages.getMessage("formTag.mapping",
- mappingName));
- pageContext.setAttribute(Globals.EXCEPTION_KEY, e,
- PageContext.REQUEST_SCOPE);
- throw e;
- }
- // 得到了表单的配置信息;
- FormBeanConfig formBeanConfig =
- moduleConfig.findFormBeanConfig(mapping.getName());
- if (formBeanConfig == null) {
- JspException e = null;
- if (mapping.getName() == null) {
- e = new JspException(messages.getMessage("formTag.name", calcAction));
- } else {
- e = new JspException(messages.getMessage("formTag.formBean",
- mapping.getName(), calcAction));
- }
- pageContext.setAttribute(Globals.EXCEPTION_KEY, e,
- PageContext.REQUEST_SCOPE);
- throw e;
- }
- beanName = mapping.getAttribute();
- beanScope = mapping.getScope();
- beanType = formBeanConfig.getType();
- }
- protected void initFormBean()
- throws JspException {
- int scope = PageContext.SESSION_SCOPE;
- if ("request".equalsIgnoreCase(beanScope)) {
- scope = PageContext.REQUEST_SCOPE;
- }
- Object bean = pageContext.getAttribute(beanName, scope);
- if (bean == null) {
- // New and improved - use the values from the action mapping
- bean =
- RequestUtils.createActionForm((HttpServletRequest) pageContext
- .getRequest(), mapping, moduleConfig, servlet);
- if (bean instanceof ActionForm) {
- ((ActionForm) bean).reset(mapping,
- (HttpServletRequest) pageContext.getRequest());
- }
- if (bean == null) {
- throw new JspException(messages.getMessage("formTag.create",
- beanType));
- }
- pageContext.setAttribute(beanName, bean, scope);
- }
- pageContext.setAttribute(Constants.BEAN_KEY, bean,
- PageContext.REQUEST_SCOPE);
- }
- public class TextTag extends BaseFieldTag {
- /**
- * Construct a new instance of this tag.
- */
- public TextTag() {
- super();
- this.type = "text";
- doReadonly = true;
- }
- }
- public int doStartTag() throws JspException {
- //将html写入到页面上去;
- TagUtils.getInstance().write(this.pageContext, this.renderInputElement());
- return (EVAL_BODY_TAG);
- }
- protected String renderInputElement()
- throws JspException {
- StringBuffer results = new StringBuffer("<input");
- prepareAttribute(results, "type", this.type);
- prepareAttribute(results, "name", prepareName());
- prepareAttribute(results, "accesskey", getAccesskey());
- prepareAttribute(results, "accept", getAccept());
- prepareAttribute(results, "maxlength", getMaxlength());
- prepareAttribute(results, "size", getCols());
- prepareAttribute(results, "tabindex", getTabindex());
- //在这里,将会到后台对应的actionForm中去拿值;
- //把后台的数据推到前台来;
- prepareValue(results);
- results.append(this.prepareEventHandlers());
- results.append(this.prepareStyles());
- prepareOtherAttributes(results);
- results.append(this.getElementClose());
- return results.toString();
- }
- protected void prepareValue(StringBuffer results)
- throws JspException {
- results.append(" value=/"");
- //如果设置了值的属性;那么显示他;
- if (value != null) {
- results.append(this.formatValue(value));
- //如果没有的话,那么从后台数据中取得;
- } else if (redisplay || !"password".equals(type)) {
- Object value =
- TagUtils.getInstance().lookup(pageContext, name, property, null);
- results.append(this.formatValue(value));
- }
- results.append('"');
- }
- public Object lookup(PageContext pageContext, String name, String property,
- String scope) throws JspException {
- //从页面中取得bean
- Object bean = lookup(pageContext, name, scope);
- if (bean == null) {
- JspException e = null;
- if (scope == null) {
- e = new JspException(messages.getMessage("lookup.bean.any", name));
- } else {
- e = new JspException(messages.getMessage("lookup.bean", name,
- scope));
- }
- saveException(pageContext, e);
- throw e;
- }
- if (property == null) {
- return bean;
- }
- try {
- //从表单中取得该property标记的属性的值,返回,输出到页
- //面;
- return PropertyUtils.getProperty(bean, property);
- } catch (IllegalAccessException e) {
- saveException(pageContext, e);
- throw new JspException(messages.getMessage("lookup.access",
- property, name));
- } catch (IllegalArgumentException e) {
- saveException(pageContext, e);
- throw new JspException(messages.getMessage("lookup.argument",
- property, name));
- } catch (InvocationTargetException e) {
- Throwable t = e.getTargetException();
- if (t == null) {
- t = e;
- }
- saveException(pageContext, t);
- throw new JspException(messages.getMessage("lookup.target",
- property, name));
- } catch (NoSuchMethodException e) {
- saveException(pageContext, e);
- String beanName = name;
- // Name defaults to Contants.BEAN_KEY if no name is specified by
- // an input tag. Thus lookup the bean under the key and use
- // its class name for the exception message.
- if (Constants.BEAN_KEY.equals(name)) {
- Object obj = pageContext.findAttribute(Constants.BEAN_KEY);
- if (obj != null) {
- beanName = obj.getClass().getName();
- }
- }
- throw new JspException(messages.getMessage("lookup.method",
- property, beanName));
- }
- }
- public int doEndTag() throws JspException {
- // 从页面上下文中消除掉当前form的标记
- pageContext.removeAttribute(Constants.BEAN_KEY,
- PageContext.REQUEST_SCOPE);
- pageContext.removeAttribute(Constants.FORM_KEY,
- PageContext.REQUEST_SCOPE);
- //封闭form标记;
- StringBuffer results = new StringBuffer("</form>");
- // 显示当前的焦点;
- if (this.focus != null) {
- results.append(this.renderFocusJavascript());
- }
- // 显示到页面上去;
- JspWriter writer = pageContext.getOut();
- try {
- writer.print(results.toString());
- } catch (IOException e) {
- throw new JspException(messages.getMessage("common.io", e.toString()));
- }
- postbackAction = null;
- // 继续执行该页面;
- return (EVAL_PAGE);
- }