【问题标题】:Getting Interceptor Parameters in Struts 2在 Struts 2 中获取拦截器参数
【发布时间】:2013-05-08 12:43:07
【问题描述】:

我有以下动作映射

<action name="theAction" ...>
...
    <param name="param1">one</param>
    <param name="param2">two</param>
    ...
    <param name="paramN">nth-number</param>
...
</action>

我可以使用 Interceptor 中的以下行获取参数映射

Map<String, Object> params = ActionContext.getContext().getParameters();

如上,有什么方法可以获取拦截器参数,如下图所定义。

<action name="theAction" ...>
...
    <interceptor-ref name="theInterceptor">
        <param name="param1">one</param>
        <param name="param2">two</param>
        ...
        <param name="paramN">nth-number</param>
    </interceptor-ref>
...
</action>

动作参数的定义方式如下,动作参数和拦截器参数应该分开访问。

<action name="theAction" ...>
...
    <param name="param1">one</param>
    <param name="param2">two</param>
    ...
    <param name="paramN">nth-number</param>
    ....
    <interceptor-ref name="theInterceptor">
        <param name="param1">one</param>
        <param name="param2">two</param>
        ...
        <param name="paramN">nth-number</param>
    </interceptor-ref>
...
</action>

请注意,我不想将拦截器中的参数字段声明为

//all fields with their getters and setters
private String param1;
private String param2;
...
private String paramN;

在 Dev Blanked 的回答之后,我实施了他的技术。它没有用,所以我在这里分享我的代码。我正在使用 Struts 2.3.1.2。

  • asm-3.3.jar
  • asm-commons-3.3.jar
  • asm-tree-3.3.jar
  • commons-fileupload-1.2.2.jar
  • commons-io-2.0.1.jar
  • commons-lang-2.5.jar
  • freemarker-2.3.18.jar
  • javassist-3.11.0.GA.jar
  • ognl-3.0.4.jar
  • struts2-core-2.3.1.2.jar
  • xwork-core-2.3.1.2.jar

Struts.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <constant name="struts.devMode" value="true" />

    <package name="the-base" namespace="/" extends="struts-default" abstract="true">

        <interceptors>
            <interceptor name="header" class="demo.interceptors.HttpHeaderInterceptor"></interceptor>

        <interceptor-stack name="theStack">
            <interceptor-ref name="defaultStack"></interceptor-ref>
                <interceptor-ref name="header"></interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <default-interceptor-ref name="theStack"></default-interceptor-ref>

    </package>

    <package name="the-module" extends="the-base">
        <action name="theAction">
            <result>/the-action.jsp</result>
            <interceptor-ref name="theStack">
                <param name="header.Cache-control">no-store,no-cache</param>
                <param name="header.Pragma">no-cache</param>
                <param name="header.Expires">-1</param>
                <param name="header.arbitrary">true</param>
            </interceptor-ref>
        </action>
    </package>
</struts>

拦截器

package demo.interceptors;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.StrutsStatics;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class HttpHeaderInterceptor extends AbstractInterceptor {

    private final Map<String, String> interceptorConfigs = new HashMap<String, String>();

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("Calling 'intercept' method.");
        HttpServletResponse response = (HttpServletResponse) invocation.getInvocationContext().get(StrutsStatics.HTTP_RESPONSE);

        for(Entry<String, String> entry: interceptorConfigs.entrySet()) {
            String header = entry.getKey();
            String value = entry.getValue();
            System.out.printf("Adding header: %s=%s\n",header,value);
            response.setHeader(header, value);
        }

        return invocation.invoke();
    }

    public Map<String, String> getInterceptorConfigs() {
        System.out.println("calling method 'getInterceptorConfigs'");
        return interceptorConfigs;
    }

    public void addInterceptorConfig(final String configName, final String configValue) {
        System.out.printf("Calling method 'addInterceptorConfig' with params configName = %s, configValue=%.\n",configName, configValue);
        interceptorConfigs.put(configName, configValue);
    }

}

控制台输出theAction被点击时。

Calling 'intercept' method. 

【问题讨论】:

  • 可能在拦截器中带有列表参数。类似这个问题:stackoverflow.com/q/14474492/1700321.
  • 不清楚你想要达到什么目的:|
  • @Andrea Ligios,我已经编辑了我的问题。但是,我的目标是在 &lt;interceptor-ref&gt; 标签正文中定义参数映射。
  • @Aleksandr M,感谢您提供的链接。但是在这种情况下,可以在配置中定义任何参数名称。

标签: java parameters struts2 interceptor interceptorstack


【解决方案1】:

在您的自定义拦截器中,您可以定义如下图

private final Map<String, String> interceptorConfigs = new HashMap<String, String>();

public Map<String, String> getInterceptorConfigs() {
    return interceptorConfigs;
}


public void addInterceptorConfig(final String configName, final String configValue) {
    interceptorConfigs.put(configName, configValue);
}

然后在您的动作映射中,您可以传入如下参数 .. 这些将存储在拦截器的映射中

    <action name="yourAction" class="your.actionClass">
        <result name="success">some.jsp</result>
        <interceptor-ref name="defaultStack">
            <param name="yourInterceptor.interceptorConfigs.key">value</param>
            <param name="yourInterceptor.interceptorConfigs.aParamName">paramValue</param>            </interceptor-ref>
    </action>

"yourInterceptor" 是指你在将拦截器添加到 struts.xml 时给出的拦截器的名称。当像上面那样配置'interceptorConfigs'时,拦截器内的映射将有,键/值对。

如果您想让这些对您的操作可用,您可以将地图设置为ActionContext 中的上下文变量。然后可以在操作中检索它。

【讨论】:

  • 我试过但没用。发出请求时,不会调用方法 addInterceptorConfig 和/或 getInterceptorConfigs。我需要实现一些接口吗?
  • @BilalMirza 这些方法将在应用程序启动和读取 struts.xml 时调用。不会为每个请求调用它们。对于该特定操作的每个请求,您在操作映射中指定的参数将保持不变。 Struts 将为每个动作映射保留单独的拦截器实例
  • @BilalMirza no-cache 是错误的。它应该是 no-cache
  • 缓存控制作为键可能不适用于 OGNL,因为 '-' 但其他人应该可以正常工作
  • addInterceptorConfig 方法是不需要的。它根本没有被调用。
【解决方案2】:

简而言之,我会说,如果你在interceptor-ref 元素中定义了拦截器参数,你就无法获取它们。这些参数在构建期间设置并应用于拦截器。但是,如果您将参数放入 interceptor 元素中,例如

<interceptor name="theInterceptor" class="com.struts.interceptor.TheInterceptor">
  <param name="param1">one</param>
  <param name="param2">two</param>
</interceptor>

您可以即时检索它们

PackageConfig packageConfig = Dispatcher.getInstance().getConfigurationManager().getConfiguration().getPackageConfig("default");
Map<String, Object> interceptorConfigs = packageConfig.getInterceptorConfigs();
InterceptorConfig interceptorConfig =  (InterceptorConfig)interceptorConfigs.get("theInterceptor");
Map<String, String> params = interceptorConfig.getParams();  

如果您不想在拦截器上定义属性来保存值,那么 OGNL 不会设置值但会尝试,所以我看不出不定义这些属性的原因,xml 配置标记为无效如果您的拦截器 bean 不包含这些属性,那么在这种情况下,构建器可能会抛出异常。所以,我不推荐不为参数定义属性。

【讨论】:

  • 我已经尝试过了,但interceprotConfigs 是空的。结果发现inteptorConfig 为null,并在获取params 时抛出NullPointerException。我已将拦截器放在默认堆栈中的最后一个位置。我已经从拦截器代码和配置(struts.xml)中匹配了拦截器名称。我错过了什么?
  • 你把它弄空了,因为你没有指定用于映射你的拦截器的包名。因此,我需要替换一个虚构的名称,与其他拦截器名称相同,因为您没有发布配置拦截器的代码我需要这样做。包名是"default",需要放在struts.xml中。
  • 我根据我的代码更改了包名和拦截器名。我得到packageConfig 的正确配置,正如我在struts.xml 中定义的那样。这意味着提供的包名称是正确的。我想知道为什么我没有收到interceptorConfigs
  • 正如你所说,我尝试的事情是不可能的,所以我接受它作为正确答案。但我必须知道你在回答中所说的另一件事。
  • @BilalMirza 可能您没有使用interceptors 标签配置它们,您应该在intercept 方法中运行代码。
猜你喜欢
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
  • 2023-03-31
  • 2011-03-16
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 2014-07-30
相关资源
最近更新 更多