1

我使用 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/

所以基本上这是一个错误还是应该以这种方式工作?

也许这不是那么优雅的解决方案,但在这里我做了什么。我超越了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;
    }
}
4

2 回答 2

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>
于 2012-03-20T09:14:49.460 回答
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 *

然后只是将编号参数传递给动作?

于 2012-03-20T21:06:12.170 回答