Java 将WebService客户端访问映射到@Stateful

Java 将WebService客户端访问映射到@Stateful,java,web-services,jakarta-ee,wildfly,stateful-session-bean,Java,Web Services,Jakarta Ee,Wildfly,Stateful Session Bean,如果我理解正确,@statefulbean保存状态。如果客户端再次执行请求,它将返回到同一实例。所以可以保存类属性,而@Stateless中不可能这样做。在这里的另一个线程中,有人写道“它就像一个经典的java实例,每次注入都会得到它自己的这个bean实例” 但是我不明白请求到@statefulbean的映射是如何工作的——该怎么做才能使它工作?这个问题适用于两种情况: 我通过Web服务通过客户端软件调用@Stateful。这是我必须随信发送的身份证吗?但是ID是什么?容器如何知道这是ident

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

但是我不明白请求到@statefulbean的映射是如何工作的——该怎么做才能使它工作?这个问题适用于两种情况:

  • 我通过Web服务通过客户端软件调用@Stateful。这是我必须随信发送的身份证吗?但是ID是什么?容器如何知道这是identify属性并将其路由到正确的@statefulbean
  • 我从@Stateless bean中调用@Stateful。例如,如果客户机首先调用@Stateless bean并重定向到他的@Stateful bean
  • 这个问题不是针对容器/服务器软件的技术流程,而是针对开发中的具体操作。谢谢你的支持


    问候语

    不幸的是,这不是web服务的工作方式。有状态bean只对无状态bean有状态。而不是客户。这是非常危险的,有几个原因:

    -无状态bean将调用的状态保存在有状态引用中。但是无状态bean的下一个调用可以在另一个上下文中/由另一个客户机进行

    -当池中的无状态bean仍处于活动状态时,容器可以销毁有状态bean

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

    Web服务是按定义提供的,没有任何应用程序状态。JavaEEservlet侦听请求并从实例池中调用一个无状态bean实现

    如果您真的想实现有状态的web服务,那么必须自己实现。以下示例将在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);
        }
    }
    
    ///依赖于客户端的值(您的statefull bean)
    公共类SessionValues{
    私有最终列表值=新的ArrayList();
    公共void addValue(字符串s){
    价值。添加(s);
    }
    公共列表加载值(){
    返回集合。不可修改列表(值);
    }
    }
    
    您可以将会话存储在单例(您自己的池)中

    @Singleton
    @启动
    公共类StatefullSingleton{
    私有最终映射会话=新哈希表();
    @锁(LockType.READ)
    public void addValue(字符串sessionId,字符串值){
    if(!sessions.containsKey(sessionId))
    sessions.put(sessionId,newsessionvalues());
    SessionValues p=sessions.get(sessionId);
    p、 附加值(value);
    }
    @锁(LockType.READ)
    公共列表加载值(字符串sessionId){
    if(sessions.containsKey(sessionId))
    return sessions.get(sessionId.loadValues();
    其他的
    返回新的ArrayList();
    }
    }
    
    并将单例注入无状态webservice bean(池、单例和单例调用由JavaEE容器管理):

    @无状态
    @网络服务
    公共类WebserviceBean{
    @注入
    私有单例ejb;
    public void addvalue(字符串sessionId,字符串值){
    addValue(sessionId,value);
    }
    公共列表加载值(字符串sessionId){
    返回ejb.loadValues(sessionId);
    }
    
    }

    上面的例子只是一种模式。如果要在生产中实现会话id和多线程,必须非常小心地使用它


    编辑:删除不必要的@localBean

    只是想知道,为什么您觉得需要在代码中添加
    @localBean
    ?你认为它会给你带来什么?如果你不使用它,会有什么不同?你是对的,LocalBean注释是不必要的。它是由Eclipse添加的,但被删除了。
     @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>();
      }
    }
    
    @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);
    }