struts2 -升级后控制器映射错误



从Struts版本2.1.8.1升级到2.3.16.3后,我有一些控制器映射的问题。升级前一切正常,但现在60多个控制器中有3个出现了下一个错误:

ERROR [ActionComponent] Could not execute action: //vendor-tree!index命名空间"/"和操作名称"vendor-tree!index"没有动作映射。-[未知位置]

这个动作必须在/vendor-tree!index而不是在//vendor-tree!index,但我不明白为什么Struts只在错误的地方寻找这3个控制器。我把所有这些控制器都命名为

 <#escape x as x?html>
    <@s.action name="vendor-tree!index" executeResult="true" /> 
 </#escape>

<constant name="struts.enable.DynamicMethodInvocation" value="true" />不改变任何东西

Struts2: method attribute in Button doesn't work是另一种情况,它不能解决这个

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.ui.theme" value="xhtml"/>
    <constant name="struts.locale" value="bg_BG"/>
    <constant name="struts.ui.templateDir" value="template" />
    <constant name="struts.custom.i18n.resources" value="global, ajax, help, xhtml" />
    <constant name="struts.devMode" value="false" />
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.action.extension" value="html,xhtml,,xml,json" />
    <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="mymapper" class="stemo.ActionMapper.HierarchicalRestActionMapper"/>
    <constant name="struts.mapper.class" value="mymapper"/>
    <!--
     enable the NamedVariablePatternMatcher to enable {variables} in the action namespace
    -->
    <bean type="com.opensymphony.xwork2.util.PatternMatcher" name="namedVariablePatternMatcher"
          class="com.opensymphony.xwork2.util.NamedVariablePatternMatcher"/>
    <constant name="struts.patternMatcher" value="namedVariablePatternMatcher"/>
    <!--
    <constant name="struts.convention.action.checkImplementsAction" value="false"/>
    <constant name="struts.convention.action.checkAnnotation" value="false"/>
    <constant name="struts.convention.action.defaultMethodName" value="index"/>
    -->
    <constant name="struts.convention.action.suffix" value="Controller"/>
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <constant name="struts.convention.default.parent.package" value="controllers"/>
    <constant name="struts.convention.result.path" value="/"/>
    <!-- constant name="struts.convention.package.locators.basePackage" value="stemo"/ -->
    <constant name="struts.convention.package.locators" value="controllers"/>
    <!--  Overwrite Convention -->

    <package name="controllers" extends="struts-default" namespace="/" >
        <interceptors>
            <interceptor name="storeMessages" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
            <!--interceptor name="messMessage" class="stemo.ActionMapper.RedirectMessageInterceptor"/ -->
            <interceptor name="cachingHeadersInterceptor" class="stemo.ActionMapper.CachingHeadersInterceptor"/>
            <interceptor name="myCookie" class="stemo.ActionMapper.CookiesInterceptor"/>
            <interceptor name="myLogger" class="stemo.ActionMapper.LoggerInterceptor"/>
            <interceptor-stack name="myStack">
                 <!-- interceptor-ref name="messMessage"/ -->
                <interceptor-ref name="storeMessages" >
                    <param name="operationMode">AUTOMATIC</param>
                </interceptor-ref>
                 <interceptor-ref name="myCookie"/>
                <interceptor-ref name="myLogger"/>
                <interceptor-ref name="defaultStack" />
            </interceptor-stack>
        </interceptors>
        <default-interceptor-ref name="myStack"/>
    </package>
    <!-- for JBoss -->
    <constant name="struts.convention.exclude.parentClassLoader" value="true" />
    <constant name="struts.convention.action.fileProtocols" value="jar,vfsfile,vfszip" />
    <constant name="struts.convention.classLoader.excludeParent" value="false" />

    <!-- for Struts version 2.3.18+ -->
    <constant name="struts.multipart.parser" value="jakarta-stream" />
    <constant name="struts.multipart.maxSize" value="50242880" />
    <!--
    <constant name="struts.freemarker.manager.classname" value="org.apache.struts2.views.freemarker.FreemarkerManager" />
     -->
    <constant name="struts.freemarker.manager.classname" value="customFreemarkerManager"/>
    <constant name="struts.freemarker.mru.max.strong.size" value="250" />
    <constant name="struts.freemarker.templatesCache.updateDelay" value="1800" />

    <package name="json" extends="json-default">
        <action name="brand-ajax" class="stemo.json.BrandAjaxController">
            <result type="json">
                <param name="root">model</param>
                <param name="excludeProperties">LHarakt, Harakt</param>
            </result>
        </action>
        <action name="vendor-ajax" class="stemo.json.VendorAjaxController">
            <result type="json">
                <param name="root">model</param>
                <param name="excludeProperties">LHarakt, Harakt</param>
            </result>
        </action>
    </package>
</struts>                     
<<p> 问题控制器/strong>
package stemo.controllers;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import stemo.hibernate.ObjectUtils;
import stemo.hibernate.model.DAO.VendorDAO;
import stemo.hibernate.model.entity.Vendor;
import stemo.hibernate.model.filters.*;
import java.util.List;
import java.util.Map;

@Results({
        @Result(name = "success", type = "freemarker",  location = "/vendortree.ftl")
})
public class VendorTreeController implements ModelDriven<Object>, SessionAware
{
    private VendorDAO vendorDAO;
    private List<Vendor> vendors;
    private String sklad_check;
    private String promo_check;
    private String newprice_check;
    private String lowprice_check;
    private String newproduct_check;
    private String oldproduct_check;
    private String withgift_check;
    private String sch_check;
    private FilterManager filters = null;
    private Map<String, Object> sessionMap;

    @Autowired
    public void setVendorDAO(VendorDAO vendorDAO)
    {
        this.vendorDAO = vendorDAO;
    }

    private FilterManager initFilters()
    {
        if (filters != null)
        {
            return filters;
        }
        filters = new FilterManager();
        if (!ObjectUtils.isEmpty(sklad_check))
        {
            StoreFilter f = new StoreFilter();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(promo_check))
        {
            PromoFilter f = new PromoFilter();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(newproduct_check))
        {
            NewProductFilter f = new NewProductFilter();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(withgift_check))
        {
            ProductsWithGift f = new ProductsWithGift();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(newprice_check))
        {
            ProductsWithNewPrices f = new ProductsWithNewPrices();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(lowprice_check))
        {
            ProductsWithLowerPrices f = new ProductsWithLowerPrices();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(oldproduct_check))
        {
            OldProductsFilter f = new OldProductsFilter();
            filters.addFilter(f);
        }
        if (!ObjectUtils.isEmpty(sch_check))
        {
            SecondHandFilter f = new SecondHandFilter();
            filters.addFilter(f);
        }
        return filters;
    }

    public HttpHeaders index()
    {
        sklad_check = (String) sessionMap.get("sklad_check");
        promo_check= (String) sessionMap.get("promo_check");
        newprice_check = (String) sessionMap.get("newprice_check");
        lowprice_check = (String) sessionMap.get("lowprice_check");
        newproduct_check = (String) sessionMap.get("newproduct_check");
        oldproduct_check = (String) sessionMap.get("oldproduct_check");
        withgift_check = (String) sessionMap.get("withgift_check");
        sch_check = (String) sessionMap.get("sch_check");
        FilterManager filters = initFilters();
        vendors = vendorDAO.findAll(filters);
        return new DefaultHttpHeaders("success").disableCaching();
    }

    @Override
    public Object getModel()
    {
        return vendors;
    }
    @Override
    public void setSession(Map<String, Object> stringObjectMap)
    {
        sessionMap = stringObjectMap;
    }
}

工作控制器

package stemo.controllers;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import stemo.hibernate.model.DAO.PenaltyDAO;
import stemo.hibernate.model.entity.PenaltyInfo;
import stemo.hibernate.model.entity.User;
import stemo.hibernate.model.entity.date.MonthItem;
import java.util.List;
import java.util.Map;

@Results({
        @Result(name = "success", type = "freemarker", location = "/penalty_details.ftl"),
        @Result(name = "list", type = "freemarker", location = "/penalty_all_details.ftl"),
        @Result(name = "error", type = "redirect", location = "/products")
})
public class PenaltyController implements ModelDriven<Object>, SessionAware
{
    private Map<String, Object> sessionMap;
    private List<PenaltyInfo> penaltyInfo;
    private String date;
    private Double penalty;
    private PenaltyDAO penaltyDAO;

    @Autowired
    public void setPenaltyDAO(PenaltyDAO penaltyDAO)
    {
        this.penaltyDAO = penaltyDAO;
    }

    @Override
    public void setSession(Map<String, Object> stringObjectMap)
    {
        this.sessionMap = stringObjectMap;
    }
    @Override
    public Object getModel()
    {
        return penaltyInfo;
    }
    public String getDate()
    {
        return date;
    }
    public void setDate(String date)
    {
        this.date = date;
    }
    public Double getPenalty()
    {
        return penalty;
    }
//GET
    public HttpHeaders index()
    {
        User user = (User) sessionMap.get("user");
        if ((user != null))
        {
            //months = MonthItem.getMonths(null);
            if (date == null)
            {
                date = MonthItem.getCurrent();
            }
            penaltyInfo = penaltyDAO.getList(user,MonthItem.toDate(date));
            penalty = penaltyDAO.getPenalty(user,MonthItem.toDate(date));
            return new DefaultHttpHeaders("success").disableCaching();
        }
        else
        return new DefaultHttpHeaders("error").disableCaching();
    }
    public HttpHeaders list()
    {
        User user = (User) sessionMap.get("user");
        if ((user != null))
        {
            penaltyInfo = penaltyDAO.getAllList(user);
            penalty = user.getPenalty();
            return new DefaultHttpHeaders("list").disableCaching();
        }
        else
        return new DefaultHttpHeaders("error").disableCaching();
    }
}

自定义映射器

public class HierarchicalRestActionMapper extends RestActionMapper {
    protected void parseNameAndNamespace(String uri, ActionMapping mapping, ConfigurationManager configManager) {
        Set<String> actions = new HashSet<String>();
        PackageConfig packageConfig;
        Configuration configuration = configManager.getConfiguration();
        // get the current set of action names in our packages of interest
        Map<String, PackageConfig> packageConfigs = configuration.getPackageConfigs();
        for (Map.Entry<String, PackageConfig> packageEntry : packageConfigs.entrySet()) {
            packageConfig = packageEntry.getValue();
            actions.addAll(packageConfig.getActionConfigs().keySet());
        }
        // parse the uri into namespace, action, method and id
        Map<String, String> params = URIActionMethodParser.process(uri, actions);
        if (params != null) {
            // update the mapping
            mapping.setNamespace(params.get("namespace"));
            params.remove("namespace");
            mapping.setName(params.get("action"));
            params.remove("action");
            mapping.setParams((Map) params);
        }
    }
}

你知道为什么吗?

当我执行动作标签没有输入方法

<@s.action name="vendor-tree" executeResult="true"/>

Struts抛出缺失执行方法错误。我把我的input方法重命名为execute,现在一切正常。

相关内容

  • 没有找到相关文章

最新更新