Struts2 + ECSide解决“查询->更新->回到原查询状态”的问题

经常有这样的情况:用户千辛万苦的查询数据,并且翻页呀翻页的找到一条,然后修改它,保存成功以后,查询结果和页数都不见了!下次修改不得不重复上述操作。
使用Struts2的Chain Result可以实现多个Action的连续执行,但是,上述场景中需要跨越两次以上的Requests,很多parameters都无法保留,入下图:
查询=>分页=>编辑(查询参数和分页参数丢失)=>保存=>查询(没有参数的查询)
解决的办法是保留parameters,可以写一个taglib来实现这个目的:
[code]
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;
}
}
[/code]
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" class="preStorageAction" method="pageQuery">
<interceptor-ref name="chain"></interceptor-ref>
<interceptor-ref name="basicStack"/>
<result name="success">list.jsp</result>
</action>
<!-- 使用chain,可以回到原来的查询状态 -->
<action name="save" class="preStorageAction" 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用起来还算方便,各位如果有更好的办法请多赐教,这篇博文权当抛砖。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值