Struts2约定和重定向参数



我使用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;
    }
}

您所描述的是com.opensymphony.xwork2.util.NamedVariablePatternMatcher和org.apache.struts2.util.RegexPatternatcher的默认行为,但它不是com.opensymhony.xwork2.util.WardcardHelper(默认实现)的行为

从您所展示的内容来看,默认实现可以处理您正在做的事情,而不那么麻烦(常规通配符匹配)。

查阅此页面:http://struts.apache.org/2.3.1.2/docs/wildcard-mappings.html

它为"命名空间中的参数"(我知道你没有使用这个)声明:

从Struts2.1+中,可以根据请求提取命名空间模式参数并绑定到操作。

然而,这同样适用于操作中发生的事情,而且它似乎是唯一的行为(我从"可能"中假设,当它真的应该写为"…命名空间/操作模式被提取为请求参数…"时,会有另一个选择),它似乎同样适用于正则表达式模式匹配,如果文档能更明确地说明这一点,那就太好了。

从你的评论中,我可以更好地理解你在做什么。。。

你为什么不简单地设置三个动作:

*/*/*, */* and *

然后将编号的参数传递到操作中?

我正在深入研究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>

最新更新