当前位置: 首页 > 知识库问答 >
问题:

访问会话范围bean的Struts2中的依赖注入

杜俊晤
2023-03-14
//@Repository
//@Scope("session")
public class Session {

    private Map<String, Object> map = new HashMap<>();

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }
}

我已经对Spring bean使用的注释进行了注释。我通过spring DI成功地创建了相同的bean,并设置了对象注入的范围。现在,我想用Struts2和di做同样的事情。为此,我在struts.xml中创建了bean定义

<bean name="session" class="jspbean.struts.Session" scope="session"/>

和简单的操作来创建bean并将其注入到我的操作中

public class DefaultAction extends ActionSupport {

    private Session session;

    //  @Autowired
    @Inject("session")
    public void setSession(Session session) {
        this.session = session;
    }

    public Session getSession() {
        return session;
    }

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

    public Map<String, String> getMyMap() {
        return myMap;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    @Override
    public String execute() throws Exception {
        //populate my bean with sample data
        myMap.put("q1", "Question1");
        myMap.put("q2", "Question2");
        session.getMap().put("myMap", myMap);
        return SUCCESS;
    }
}

在JSP中,我在会话bean上使用简单的迭代器

<s:iterator value="session.map['myMap']">
  <s:textfield name="myMap['%{key}']" value="%{value}" theme="simple" size="10" /><br>
</s:iterator>
Stacktraces
Unable to instantiate Action, jspbean.struts.DefaultAction, defined for '' in namespace '/'java.lang.IllegalStateException: Scope strategy not set. Please call Container.setScopeStrategy().

    com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:316)
    com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
    com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
    org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)


java.lang.RuntimeException: java.lang.IllegalStateException: Scope strategy not set. Please call Container.setScopeStrategy().

    com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:301)
    com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:492)
    com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
    com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
    com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
    com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
    com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
    com.opensymphony.xwork2.spring.SpringObjectFactory.autoWireBean(SpringObjectFactory.java:208)
    com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:183)
    com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:154)
    com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
    com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
    com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:297)
    com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
    com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
    org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)


java.lang.IllegalStateException: Scope strategy not set. Please call Container.setScopeStrategy().

    com.opensymphony.xwork2.inject.InternalContext.getScopeStrategy(InternalContext.java:53)
    com.opensymphony.xwork2.inject.Scope$5$1.create(Scope.java:130)
    com.opensymphony.xwork2.inject.ContainerImpl$ParameterInjector.inject(ContainerImpl.java:469)
    com.opensymphony.xwork2.inject.ContainerImpl.getParameters(ContainerImpl.java:484)
    com.opensymphony.xwork2.inject.ContainerImpl.access$000(ContainerImpl.java:34)
    com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:299)
    com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:492)
    com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
    com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
    com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
    com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
    com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
    com.opensymphony.xwork2.spring.SpringObjectFactory.autoWireBean(SpringObjectFactory.java:208)
    com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:183)
    com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(SpringObjectFactory.java:154)
    com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
    com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
    com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:297)
    com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
    com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
    org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:536)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)
    null

共有1个答案

苏弘盛
2023-03-14

让我们从查看文档开始,查看什么是scope.strategy。上面写着

可插入的作用域策略。使用户能够提供请求、会话和向导作用域的自定义实现。实现并传递给container.setScopeStrategy(com.opensymphony.xwork2.inject.scope.Strategy)

好的,假设我想实现会话范围。然后我需要知道我可以实现它的地方。框架有它的扩展点,您可以在这里插入扩展,或者简单地扩展default实现,并提供您自己的自定义实现。通过查看BeanSelectionProvider可以轻松实现这一点。然后分析了stacktraces,我决定最好的方法是扩展DefaultActionProxyFactory。扩展它还需要扩展DefaultActionProxy

public class MyActionProxyFactory extends DefaultActionProxyFactory {

    public MyActionProxyFactory() {
        super();
    }

    @Override
    public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {

        MyActionProxy proxy = new MyActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
        container.inject(proxy);
        container.setScopeStrategy(new MyScopeStrategy());
        proxy.prepare();
        return proxy;
    }
}

public class MyActionProxy extends DefaultActionProxy {

    protected MyActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {
        super(inv, namespace, actionName, methodName, executeResult, cleanupContext);
    }

    @Override
    protected void prepare() {
        super.prepare();
    }
}

public class MyScopeStrategy implements Scope.Strategy {

    @Override
    public <T> T findInRequest(Class<T> type, String name, Callable<? extends T> factory) throws Exception {
        return null;
    }

    @Override
    public <T> T findInSession(Class<T> type, String name, Callable<? extends T> factory) throws Exception {

        ActionContext context = ActionContext.getContext();
        SessionMap<String, T> sessionMap = (SessionMap<String, T>) context.getSession();

        if (sessionMap == null) {
            sessionMap = new SessionMap<String, T>(ServletActionContext.getRequest());
            context.setSession((Map<String, Object>) sessionMap);
        }

        T obj = sessionMap.get(name);

        if (obj == null) {
            obj = factory.call();
            sessionMap.put(name, obj);
        }
        return obj;
    }

    @Override
    public <T> T findInWizard(Class<T> type, String name, Callable<? extends T> factory) throws Exception {
        return null;
    }
}
<constant name="struts.actionProxyFactory" value="jspbean.struts.factory.MyActionProxyFactory"/>
 类似资料:
  • 问题内容: 我不确定我在做什么是错误的,还是只是错过了某个地方的注释或配置项。情况如下: 我有一个JSF应用程序,其会话范围的bean名为。在创建时,此Bean 注入了一个应用程序范围的Bean引用(类型)。首次创建会话时,此方法正常。依赖项注入是通过文件中的元素完成的,如下所示: 因为序列化时让我的对象包含对象没有意义,所以我在对象中将引用标记为瞬态: 直到停止Web应用程序(在我的Tomcat

  • 我们知道Spring框架提供了单例、原型、请求、会话、全局会话bean范围。 我们还知道Spring Web流提供了flow Scope、viewScope、Request estScope、flash Scope、versationScope。 因此,如果我在spring MVC项目中提到一个组件,比如说Student,作为@Component@Scope=singleton。对于每个请求,它会

  • 问题内容: 我需要从servlet访问会话范围的bean。我已经试过了 在本作描述的职位。但是我只能得到null的结果,尽管UserBean的一个实例已经被无效化了。这些是我用于userBean的注释/导入: 为什么不能摆脱servlet的一些背景知识:我的jsf页面中有一个文件上传小程序。该applet期望可以发送POST请求的地址。(我无法编辑此发帖请求以添加更多字段或其他内容)。然后,我的s

  • 我的bean注释为 我有一些getter和setter,但我对JSP感兴趣的是 然后在我的控制器中,我将产品添加到列表中 然后,在我的JSP中,我尝试了一下,但没有得到结果: 我还使用了下面的属性,以便我的beans向JSP公开:< code > 编辑:控制器: 表始终为空。我已经调试过了,我看到在我的个人豆中,填充了产品列表。

  • 在用户登录时续订HTTP会话是常见的最佳做法。这将强制使用新的会话ID,从而避免会话固定漏洞。 当涉及@SessionScoped bean时,是否有使用CDI实现此功能的首选模式?困难在于,通过使当前HTTP会话无效,您将在下一个请求中获得不同的会话范围bean,但直到下一个请求。 例如,假设一个用于存储用户登录信息的会话bean: 和另一个用于管理登录的bean: 对于托管Bean,这将检索一

  • HttpSession 对象必须被限定在应用(或 servlet 上下文)级别。底层的机制,如使用 cookie 建立会话,不同的上下文可以是相同,但所引用的对象,包括该对象中的属性,决不能在容器上下文之间共享。 用一个例子来说明该要求: 如果 servlet 使用 RequestDispatcher 来调用另一个 Web 应用的 servlet,任何创建的会话和被调用 servlet 所见的必须