2007-12-14
Struts2 + ECSide解决“查询->更新->回到原查询状态”的问题
关键字: ECSide,Struts2
经常有这样的情况:用户千辛万苦的查询数据,并且翻页呀翻页的找到一条,然后修改它,保存成功以后,查询结果和页数都不见了!下次修改不得不重复上述操作。
使用Struts2的Chain Result可以实现多个Action的连续执行,但是,上述场景中需要跨越两次以上的Requests,很多parameters都无法保留,入下图:
查询=>分页=>编辑(查询参数和分页参数丢失)=>保存=>查询(没有参数的查询)
解决的办法是保留parameters,可以写一个taglib来实现这个目的:
jsp页面中这样使用:
或者:
在Struts2的配置文件中和chain一起使用:
上面的代码中省略了.tld中的内容,而且taglib只有includes属性,没有excludes属性。
使用taglib应该算是比较丑陋的做法,但是一时也想不到更好的方法,Ajax当然可以解决,可是我这个项目是改造遗留系统,总不能都改成Ajax的。其实这个taglib用起来还算方便,各位如果有更好的办法请多赐教,这篇博文权当抛砖。
使用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" 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用起来还算方便,各位如果有更好的办法请多赐教,这篇博文权当抛砖。
评论
syncml
2007-12-21
我也为这种类型的操作犯愁
steven_652
2007-12-14
这里会有一个问题的,查询条件的字段很有可能会和编辑form的字段重复,导致提交form出错。比如查询条件中有合同号字段(ContractNo),在编辑记录的时候恰巧也有合同号信息需要进行修改,这样就会出现异常!
cats_tiger
2007-12-14
发生什么错误呀?从来没有遇到过。
huazihun
2007-12-14
写的不赖,学习了。
但不知道楼主能否解决一下struts2+ecside的隐藏input表单问题,
在查询、翻页、排序时会发生错误。
但不知道楼主能否解决一下struts2+ecside的隐藏input表单问题,
在查询、翻页、排序时会发生错误。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 93159 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
扩展Dojo 0.9之Resizable ...
在1.1.1下无法运行
-- by mybird -
让ecside2离开prototype. ...
我也是用JQuery的 谢谢了
-- by wuhui -
Jquery终于有两个看得过去 ...
stworthy 写道JQUERY的很多插件风格都不统一,不象EXT有统一的样式 ...
-- by ayeah -
Jquery终于有两个看得过去 ...
JQUERY的很多插件风格都不统一,不象EXT有统一的样式控制及操作风格。
-- by stworthy -
Jquery终于有两个看得过去 ...
jqgrid太臃肿,我放弃了,还是选择了flexigrid,功能虽然简单,也没有 ...
-- by ayeah






评论排行榜