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; }}
<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>
<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>