Соглашение Struts2 и параметры перенаправления - PullRequest
1 голос
/ 19 марта 2012

Я использую плагин 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;
}

Когда, например, нет artGroup для указанного artikelgroep, он должен перенаправить 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;
    }
}

Ответы [ 2 ]

0 голосов
/ 21 марта 2012

То, что вы описываете, является поведением по умолчанию для 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+ шаблоны пространства имен могут быть извлечены как параметры запроса и привязаны кдействие.

Однако это в равной степени относится к тому, что происходит в действии, и это действительно кажется единственным поведением (где я мог бы предположить из «может быть», что будет другой выбор, когда этодолжен был быть написан как "... пространство имен / шаблоны действий извлекаются как параметр запросаs ... ") и, похоже, это применимо к сопоставлению с регулярным выражением в равной степени, было бы неплохо, чтобы документация более четко это указала.

Из ваших комментариев я могу лучше понять, что вы делаете ...

Почему бы вам просто не настроить три действия для:

*/*/*, */* and *

Тогда просто пройдитепронумерованные параметры в действии?

0 голосов
/ 20 марта 2012

Я копался в коде 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>
...