不幸的是,这不是 Web 服务的工作方式。有状态 bean 仅对无状态 bean 是有状态的。而不是为客户。出于以下几个原因,这是非常危险的:
- 无状态 bean 在其有状态引用中保存调用的状态。但是无状态 bean 的下一次调用可能发生在另一个上下文中/由另一个客户端。
-有状态的bean可以被容器销毁,而无状态的bean仍然存在/在池中。
您可以在远程调用或 Web 应用程序中使用有状态 bean,但不能在 Web 服务的上下文中使用。
根据定义,Web 服务没有任何应用程序状态。Java EE-Servlet 侦听请求并从实例池中调用一个无状态 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);
}
}
您可以将会话存储在单例中(您自己的池)
@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>();
}
}
并将单例注入无状态 Web 服务 bean(池、单例和单例调用由 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