【问题标题】:Mapping WebService-Client-Access to @Stateful将 WebService-Client-Access 映射到 @Stateful
【发布时间】:2015-02-22 17:40:18
【问题描述】:

如果我理解正确,@Stateful bean 会保存状态。如果客户端再次发出请求,它会返回到同一个实例。所以可以保存类属性,这是在@Stateless 中做不到的。在另一个线程中,有人写道“它就像一个经典的 java 实例,每次注入都会得到它自己的这个 bean 的实例”。

但我不明白请求到@Stateful bean 的映射是如何工作的——它是如何工作的?这个问题分两种情况:

  1. 我通过客户端软件的网络服务调用@Stateful。它是我必须发送的 ID 吗?但是 ID 是什么?容器如何知道这是标识属性并将其路由到正确的 @Stateful bean?
  2. 我从@Stateless bean 中调用@Stateful。例如,如果客户端首先调用 @Stateless bean 并重定向到他的 @Stateful bean。

这个问题不是针对容器/服务器软件的技术流程,而是针对开发中的具体操作。感谢您的支持。

问候

【问题讨论】:

    标签: java web-services jakarta-ee wildfly stateful-session-bean


    【解决方案1】:

    很遗憾,Web 服务的工作方式并非如此。有状态 bean 仅对无状态 bean 是有状态的。而不是为客户。出于以下几个原因,这非常危险:

    -无状态 bean 将调用的状态保存在其有状态引用中。但是无状态 bean 的下一次调用可能发生在另一个上下文中/由另一个客户端。

    -有状态的bean可以被容器销毁,而无状态的bean还活着/在池中。

    您可以在远程调用或 Web 应用程序中使用有状态 bean,但不能在 Web 服务的上下文中使用。

    Web 服务根据定义而没有任何应用程序状态。 Java EE-Servlet 侦听请求并从实例池中调用一个无状态 bean 实现。

    如果你真的想实现有状态的网络服务,你必须自己做。以下示例适用于 Java EE 6 容器:

    ///  Client depended values(your statefull bean)
    public class SessionValues {
       private final List<String> values = new ArrayList<String>(); 
    
       public void addValue(String s){
            values.add(s);
        }
    
        public List<String> loadValues(){
            return Collections.unmodifiableList(values);
        }
    }
    

    您可以将会话存储在单例中(您自己的池)

     @Singleton
     @Startup
     public class StatefullSingleton {
       private final Map<String, SessionValues> sessions = new Hashtable<String, SessionValues>();
    
        @Lock(LockType.READ)
        public void addValue(String sessionId, String value) {
          if (!sessions.containsKey(sessionId))
              sessions.put(sessionId, new SessionValues());
          SessionValues p = sessions.get(sessionId);
          p.addValue(value);
      }
    
      @Lock(LockType.READ)
      public List<String> loadValues(String sessionId) {
        if (sessions.containsKey(sessionId))
            return sessions.get(sessionId).loadValues();
        else
            return new ArrayList<String>();
      }
    }
    

    并在无状态的webservice beans中注入singleton(池,singleton和singleton的调用由Java EE-Container管理):

    @Stateless
    @WebService
    public class WebserviceBean {
    
    @Inject
    private StatefullSingleton ejb;
    
    public void addvalue(String sessionId, String value) {
        ejb.addValue(sessionId, value);
    }
    
    public List<String> loadValues(String sessionId) {
        return ejb.loadValues(sessionId);
    }
    

    }

    上面的例子只是一个模式。如果你想在生产环境中实现它,你必须非常小心地使用 session-id 和多线程。

    编辑:删除不必要的@localBean

    【讨论】:

    • 只是想知道,为什么您觉得有必要将@LocalBean 添加到您的代码中?你认为它会给你带来什么,如果你把它排除在外,会有什么不同?
    • 你说得对,LocalBean-Annotaion 不是必需的。它是由 Eclipse 添加的,然后将其删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2023-01-25
    • 2016-05-12
    • 2017-07-22
    相关资源
    最近更新 更多