我使用Struts2 Convention插件来映射我的动作。请帮我解决以下问题。这里我有一个动作映射
@Action(value="/{categorie:\\w+}/{hoofdgroep:\\w+}/{artikelgroep:\\w+}/", results = {
@Result(name="success", location="articlelist.jsp"),
@Result(name="maingroup", location="/%{categorie}/%{hoofdgroep}/", type="redirect"),
@Result(name="category", location="/%{categorie}/", type="redirect")
}, interceptorRefs = {
...
})
public String execute() throws Exception {
...
Category category = service.getCategory(categorie);
if (category == null) return NONE;
...
MainGroup mGroup = service.getMainGroup(hoofdgroep);
if (mGroup == null) return "category";
...
ArticleGroup artGroup = service.getArticleGroup(artikelgroep);
if (artGroup == null) return "maingroup";
...
return SUCCESS;
}
例如,当指定的artikelgroep没有artGroup时,它应该将link _http://site/categorie/hoofdgroep/artikelgroep/
重定向到url _http://site/categorie/hoofdgroep/
,它完全可以。这里唯一的问题是它还预先添加了不希望的附加参数。因此,链接_ http://site/categorie/hoofdgroep/artikelgroep/
会重定向到_http://site/categorie/hoofdgroep/?categorie=categorie&hoofdgroep=hoofdgroep&artikelgroep=artikelgroep.
我的问题是如何摆脱这些参数?
以下是我的struts.properties文件中的一些配置参数
...
struts.serve.static=false
struts.ognl.allowStaticMethodAccess=true
struts.enable.DynamicMethodInvocation=false
struts.action.extension= ,
struts.url.includeParams=none
struts.enable.SlashesInActionNames=true
struts.mapper.alwaysSelectFullNamespace=false
struts.patternMatcher=regex
struts.convention.default.parent.package=app-default
struts.convention.action.packages=...
struts.convention.action.alwaysMapExecute=false
struts.convention.package.locators.disable=true
struts.convention.relative.result.types=dispatcher
struts.convention.result.path=/WEB-INF/jsp/
所以基本上这是一个bug还是它应该这样工作?
也许这不是那么优雅的解决方案,但在这里我做了什么。我重写了org.apache.struts2.dispatcher.ServletRedirectResult#getProhibitedResultParams
public class ServletRedirectResult
extends org.apache.struts2.dispatcher.ServletRedirectResult
{
public ServletRedirectResult() {
super();
initProhibitedResultParams();
}
public ServletRedirectResult(String location) {
super(location);
initProhibitedResultParams();
}
public ServletRedirectResult(String location, String anchor) {
super(location, anchor);
initProhibitedResultParams();
}
private List<String> prohibitedParamNames;
private void initProhibitedResultParams() {
String[] parentParams = (String[])super.getProhibitedResultParams().toArray();
int len = parentParams.length;
String[] params = new String[len + 4];
for (int i = 0; i < len; i++) {
params[i] = parentParams[i];
}
params[len] = "statusCode";
// TODO: This is a temporary solution because RegexPatternMatcher puts parameters
// from urls into ResultConfig for some reason.
params[len+1] = "categorie";
params[len+2] = "hoofdgroep";
params[len+3] = "artikelgroep";
prohibitedParamNames = Arrays.asList(params);
}
protected List<String> getProhibitedResultParams() {
return prohibitedParamNames;
}
}
答案 0 :(得分:0)
我正在深入研究org.apache.struts2.dispatcher.ServletRedirectResult#doExecute
的代码。可能这篇文章预设了不需要的参数
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(invocation.getResultCode());
if (resultConfig != null)
{
Map<String, String> resultConfigParams = resultConfig.getParams();
for (Map.Entry<String, String> e : resultConfigParams.entrySet())
{
if (!getProhibitedResultParams().contains(e.getKey()))
{
String potentialValue = e.getValue() == null ? "" : conditionalParse(e.getValue(), invocation);
if (!suppressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0)))
{
requestParameters.put(e.getKey(), potentialValue);
}
}
}
}
此代码没有任何问题。问题是为什么这三个参数出现在ResultConfig中?因为它像你这样写作时的工作方式
<result name="maingroup" type="redirect">
<param name="location">/${categorie}/${hoofdgroep}/</param>
<param name="namespace">/</param>
<param name="categorie">${categorie}</param>
<param name="hoofdgroep">${hoofdgroep}</param>
<param name="artikelgroep">${artikelgroep}</param>
</result>
答案 1 :(得分:0)
您所描述的是com.opensymphony.xwork2.util.NamedVariablePatternMatcher和org.apache.struts2.util.RegexPatternMatcher的默认行为,但它不是com.opensymphony.xwork2.util.WildcardHelper的行为(这是默认实施)
从你所展示的内容来看,默认实现可以处理你正在做的事情,而不是头痛(常规通配符匹配)。
咨询此页面:http://struts.apache.org/2.3.1.2/docs/wildcard-mappings.html
它声明“命名空间中的参数”(我知道你没有使用它):
来自Struts 2.1+ 命名空间模式可以作为请求提取 参数并绑定到操作。
然而,这同样适用于动作中发生的事情,而且它似乎是唯一的行为(我可以从“可以”中假设当应该真的被写为“可以”时会有另一种选择。命名空间/动作模式 提取为请求参数...“)并且似乎同样适用于正则表达式模式匹配,文档更明确地说明这一点会很好。
从你的评论我可以更好地了解你在做什么......
为什么不简单地为以下内容设置三个操作:
*/*/*, */* and *
然后将编号参数传递给动作?