如何管理有状态的Web服务?

时间:2011-06-28 02:45:09

标签: java java-ee glassfish ejb stateful-session-bean

我正在尝试学习J2EE和Web服务(在GlassFish 3.1中)。这个问题是this的后续问题。

我已经找到了如何使用无状态会话Bean和Web服务。我真的只是出于方便而使用Web服务(@WebService),因为我不想手工解析消息。虽然如果可能的话,我更喜欢比SOAP更轻的东西。但是,当我想维持某种状态时(例如通过有状态会话Bean),我遇到了一个问题。我搜索了这个网站,其他几个人建议我避免这种情况,因为它可能导致很难发现错误并限制可扩展性。

假设我有一个用户刚刚执行了“userLogin”方法并且已成功完成。然后我如何在服务器上知道用户已经登录。例如,登录后用户可能通过SOAP调用“getProfile()”(没有任何参数),我会返回该用户的正确信息。我知道通过将@WebService附加到我的有状态会话Bean是不可能的,因为这仅对@Stateless有效。

如果我使用HttpSession(带有HttpServlet)和Stateless Session Beans,我知道如何存储状态,但是我不能使用生成良好的SOAP消息。

所以我的问题是:如何解决维护用户状态的问题,或者调整问题以便我不需要状态?

2 个答案:

答案 0 :(得分:5)

WS可以是有状态的:使用@Stateful注释和WS-Addressing(例如,参见我的old question

拥有有状态服务器没有任何罪恶感。毕竟,如果需要有状态,为什么要避免它呢?确实,无状态更容易扩展和调试,但如果你需要保持状态(例如在购物卡中) - 那么保留它。

但要考虑的是在超时后清理有状态服务实例。使用StatefulWebServiceManager实例及其setTimeout()方法。

此外,状态可以保持在WS之外(例如数据库),并且状态(会话)标识符作为参数之一传递。工作得很好。

使用HTTP会话是保持无状态服务状态的一种非常简单的方法,但我认为它与@Stateful相比已经过时了。理由是不必要的请求必须通过HTTP; @ Stateful / WS-Addressing适用于任何通道,而HTTP会话则需要HTTP传输。当然,在现实世界中,HTTP是主流,因此这种说法非常纯粹。

答案 1 :(得分:0)

将无状态bean公开为Web服务:

import javax.ejb.Remote;
import javax.jws.WebService;
import javax.jws.WebMethod; 


@WebService
/**
* This is an Enterprise Java Bean Service Endpoint Interface
*/
public interface HelloServiceInf extends java.rmi.Remote {

    /**
    * @param phrase java.lang.String
    * @return java.lang.String
    * @throws String The exception description.
    */
    @WebMethod
    java.lang.String sayHello(java.lang.String name) throws java.rmi.RemoteException;
}

将Web服务实现为无状态bean

import java.rmi.RemoteException;
import java.util.Properties;
import javax.ejb.Stateless;

/**
* This is a session bean class
*/
@Stateless(name="HelloServiceEJB")
public class HelloServiceBean implements HelloServiceInf {

    public String sayHello(String name) {
        return("Hello "+name +" from first EJB3.0 Web Service");
    }
}

您需要在HttpSession中保留UserInfo(用户详细信息和配置文件信息Object),如果HttpSession中没有UserInfo,则需要调用bean(Web服务)。