读书人

Struts2 + ECSide解决“查询-gt;更新-gt;回

发布时间: 2012-10-28 09:54:44 作者: rapoo

Struts2 + ECSide解决“查询->更新->回到原查询状态”的问题
经常有这样的情况:用户千辛万苦的查询数据,并且翻页呀翻页的找到一条,然后修改它,保存成功以后,查询结果和页数都不见了!下次修改不得不重复上述操作。
使用Struts2的Chain Result可以实现多个Action的连续执行,但是,上述场景中需要跨越两次以上的Requests,很多parameters都无法保留,入下图:
查询=>分页=>编辑(查询参数和分页参数丢失)=>保存=>查询(没有参数的查询)
解决的办法是保留parameters,可以写一个taglib来实现这个目的:

public class ParametersTag extends BodyTagSupport {  private static Log log = LogFactory.getLog(ParametersTag.class);  /** 输出为input tag */  public static final String TYPE_INPUT_TAG = "inputTag";  /** 输出为query string */  public static final String TYPE_QUERY_STRING = "queryString";    /**   * 指定包含的parameters,如果没有指定,则包含全部。可以使用*、?作为通配符。   */  private String includes;  /**   * @see #TYPE_INPUT_TAG   * @see #TYPE_QUERY_STRING   */  private String type;  /**   * @see javax.servlet.jsp.tagext.BodyTagSupport#release()   */  @Override  public void release() {    includes = null;    type = null;    super.release();  }  /**   * @see javax.servlet.jsp.tagext.BodyTagSupport#doEndTag()   */  @Override  public int doEndTag() throws JspException {        Enumeration<String> keys = pageContext.getRequest().getParameterNames();    String str = "";        if(StringUtils.isBlank(type) || StringUtils.equals(TYPE_INPUT_TAG, type)) {      log.debug("Build Input Tags.");      str = buildInputTags(keys);    } else {      log.debug("Build query string.");      str = buildQueryString(keys);    }    try {      pageContext.getOut().write(str);    } catch (IOException e) {      e.printStackTrace();    }    return BodyTagSupport.EVAL_PAGE;  }    /**   * 根据参数构造queryString   * @param keys 参数名称   */  private String buildQueryString(Enumeration<String> keys) {    StringBuffer buf = new StringBuffer();    while(keys.hasMoreElements()) {      String key = keys.nextElement();      String value = pageContext.getRequest().getParameter(key);      if(StringUtils.isBlank(value)) {        continue;      }      buf.append(key)      .append("=")      .append(value);      if(keys.hasMoreElements()) {        buf.append("&");      }    }    return buf.toString();  }  /**   * 根据参数构造Input   * @param keys 参数名称   */  private String buildInputTags(Enumeration<String> keys) {    StringBuffer buf = new StringBuffer();    while(keys.hasMoreElements()) {      String key = keys.nextElement();      if(!isInclude(key)) {        continue;      }      String value = pageContext.getRequest().getParameter(key);      buf.append("<input type='hidden' name='")      .append(key)       .append("' value='")      .append((value == null) ? StringUtils.EMPTY : value)      .append("'/>");    }        return buf.toString();  }    /**   * 判断某个参数是否可以包含。   */  private boolean isInclude(String target) {    if(StringUtils.isBlank(includes)) {      return true;    }    PathMatcher matcher = new AntPathMatcher();    Set<String> incs = StringUtil.parseCommaSplitedString(includes);    for(String inc : incs) {      if(matcher.match(inc, target)) {        return true;      }    }        return false;  }      /**   * @return the includes   */  public String getIncludes() {    return includes;  }  /**   * @param includes the includes to set   */  public void setIncludes(String includes) {    this.includes = includes;  }  /**   * @return the type   */  public String getType() {    return type;  }  /**   * @param type the type to set   */  public void setType(String type) {    this.type = type;  }}

jsp页面中这样使用:
<s:form theme="simple" action="create" id="saveForm"><jsam:params includes="ec*,query*" type="inputTag"></jsam:params></s:form>

或者:
  <a href='edit.do?id=${item.id}&<jsam:params includes="ec*,query*" type="queryString"/>'>edit</a>

在Struts2的配置文件中和chain一起使用:
  <action name="preStorageQuery" method="pageQuery"><interceptor-ref name="chain"></interceptor-ref>        <interceptor-ref name="basicStack"/>    <result name="success">list.jsp</result>  </action>  <!-- 使用chain,可以回到原来的查询状态 -->  <action name="save" method="save">   <result name="success" type="chain">        <param name="actionName">preStorageQuery</param>    <param name="method">pageQuery</param>    <param name="namespace">/admin/drugstorage/pre</param> </result>    <result name="input">list.jsp</result> <interceptor-ref name="params" /> <interceptor-ref name="model-driven" />         <interceptor-ref name="validationWorkflowStack" />  </action>

上面的代码中省略了.tld中的内容,而且taglib只有includes属性,没有excludes属性。
使用taglib应该算是比较丑陋的做法,但是一时也想不到更好的方法,Ajax当然可以解决,可是我这个项目是改造遗留系统,总不能都改成Ajax的。其实这个taglib用起来还算方便,各位如果有更好的办法请多赐教,这篇博文权当抛砖。 1 楼 huazihun 2007-12-14 写的不赖,学习了。
但不知道楼主能否解决一下struts2+ecside的隐藏input表单问题,
在查询、翻页、排序时会发生错误。 2 楼 cats_tiger 2007-12-14 发生什么错误呀?从来没有遇到过。 3 楼 steven_652 2007-12-14 这里会有一个问题的,查询条件的字段很有可能会和编辑form的字段重复,导致提交form出错。比如查询条件中有合同号字段(ContractNo),在编辑记录的时候恰巧也有合同号信息需要进行修改,这样就会出现异常! 4 楼 huazihun 2007-12-15 @cats_tiger
发生错误类似:http://ecside.group.iteye.com/group/topic/3150
,望赐教! 5 楼 syncml 2007-12-21 我也为这种类型的操作犯愁 6 楼 yourenyouyu2008 2008-09-09 如果你们用seam中的对话的话,这样的问题相当的简单。 7 楼 soci 2008-09-09 GET提交

读书人网 >软件架构设计

热点推荐