Axis Web Service开发之旅 (七) --跨服务会话(Session)管理

本文介绍了一种在多个WebService服务间实现会话状态共享的方法,即跨服务会话管理。文章详细阐述了其实现步骤,并提供了具体的代码示例。

对于一个复杂的系统,不可能只有一个WebService服务,例如,至少会有一个管理用户的WebService(用户登录和注册)以及处理业务的WebService。象这种情况,就必须在多个WebService服务之间共享会话状态,也称为跨服务会话(Session)管理。实现跨服务会话管理与实现同一个服务的会话管理的步骤类似,但仍然有一些差别,实现跨服务会话管理的步骤如下:

实现跨服务的Session管理需要如下三步:

1. 使用MessageContext和ServiceGroupContext获得与设置key-value对。

2. 为要进行Session管理的WebService类所对应的<service>元素添加一个scope属性,并将该属性值设为application。

3. 在客户端使用setManageSession(true)打开Session管理功能。

从上面的步骤可以看出,实现跨服务会话管理与实现同一个服务的会话管理在前两步上存在着差异,而第3步是完全一样的。下面是一个跨服务的会话管理的实例。在这个例子中有两个WebService类:

LoginService和SearchService,代码如下:

 

LoginService.java   
package service;   
import org.apache.axis2.context.MessageContext;   
import org.apache.axis2.context.ServiceGroupContext;   
public class LoginService   
{   
    public boolean login(String username, String password)   
    {           
        if("bill".equals(username) && "1234".equals(password))   
        {   
            //  第1步:设置key-value对   
            MessageContext mc = MessageContext.getCurrentMessageContext();   
            ServiceGroupContext sgc = mc.getServiceGroupContext();   
            sgc.setProperty("login", "成功登录");       
            return true;   
        }   
        else  
        {   
            return false;   
        }   
    }       
    public String getLoginMsg()   
    {   
       //  第1步:获得key-value对中的value   
        MessageContext mc = MessageContext.getCurrentMessageContext();   
        ServiceGroupContext sgc =  mc.getServiceGroupContext();   
        return (String)sgc.getProperty("login");       
    }   
}   
  
SearchService.java   
package service;   
import org.apache.axis2.context.MessageContext;   
import org.apache.axis2.context.ServiceGroupContext;   
public class SearchService   
{   
    public String findByName(String name)   
    {   
        //  第1步:获得key-value对中的value   
        MessageContext mc = MessageContext.getCurrentMessageContext();   
        ServiceGroupContext sgc =  mc.getServiceGroupContext();                   
        if (sgc.getProperty("login") != null)   
            return "找到的数据<" + name + ">";   
        else  
            return "用户未登录";   
    }   
}  
LoginService.java
package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class LoginService
{
    public boolean login(String username, String password)
    {        
        if("bill".equals(username) && "1234".equals(password))
        {
            //  第1步:设置key-value对
            MessageContext mc = MessageContext.getCurrentMessageContext();
            ServiceGroupContext sgc = mc.getServiceGroupContext();
            sgc.setProperty("login", "成功登录");    
            return true;
        }
        else
        {
            return false;
        }
    }    
    public String getLoginMsg()
    {
       //  第1步:获得key-value对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceGroupContext sgc =  mc.getServiceGroupContext();
        return (String)sgc.getProperty("login");    
    }
}

SearchService.java
package service;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class SearchService
{
    public String findByName(String name)
    {
        //  第1步:获得key-value对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceGroupContext sgc =  mc.getServiceGroupContext();                
        if (sgc.getProperty("login") != null)
            return "找到的数据<" + name + ">";
        else
            return "用户未登录";
    }
}
 

 
services.xml文件中的配置代码如下:


<serviceGroup>  
    <!--  第2步:添加scope属性,并设置属性值为application -->  
    <service name="loginService" scope="application">  
        <description>  
            登录服务   
        </description>  
        <parameter name="ServiceClass">  
            service.LoginService   
        </parameter>  
        <messageReceivers>  
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"  
                class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />  
        </messageReceivers>  
    </service>  
    <!--  第2步:添加scope属性,并设置属性值为application -->  
    <service name="searchService" scope="application">  
        <description>  
            搜索服务   
        </description>  
        <parameter name="ServiceClass">  
            service.SearchService   
        </parameter>  
        <messageReceivers>  
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"  
                class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />  
        </messageReceivers>  
    </service>  
</serviceGroup>  
<serviceGroup>
    <!--  第2步:添加scope属性,并设置属性值为application -->
    <service name="loginService" scope="application">
        <description>
            登录服务
        </description>
        <parameter name="ServiceClass">
            service.LoginService
        </parameter>
        <messageReceivers>
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
        </messageReceivers>
    </service>
    <!--  第2步:添加scope属性,并设置属性值为application -->
    <service name="searchService" scope="application">
        <description>
            搜索服务
        </description>
        <parameter name="ServiceClass">
            service.SearchService
        </parameter>
        <messageReceivers>
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
        </messageReceivers>
    </service>
</serviceGroup>

   


下面是使用两个stub类的对象实例访问上面实现的两个WebService的客户端代码:


LoginServiceStub stub = new LoginServiceStub();   
LoginServiceStub.Login login = new LoginServiceStub.Login();   
login.setUsername("bill");   
login.setPassword("1234");   
if(stub.login(login).local_return)   
{   
    System.out.println(stub.getLoginMsg().local_return);   
    SearchServiceStub searchStub = new SearchServiceStub();   
    SearchServiceStub.FindByName fbn = new SearchServiceStub.FindByName();   
    fbn.setName("abc");   
    System.out.println(searchStub.findByName(fbn).local_return);    
}  
LoginServiceStub stub = new LoginServiceStub();
LoginServiceStub.Login login = new LoginServiceStub.Login();
login.setUsername("bill");
login.setPassword("1234");
if(stub.login(login).local_return)
{
    System.out.println(stub.getLoginMsg().local_return);
    SearchServiceStub searchStub = new SearchServiceStub();
    SearchServiceStub.FindByName fbn = new SearchServiceStub.FindByName();
    fbn.setName("abc");
    System.out.println(searchStub.findByName(fbn).local_return); 
}
 

 
在执行上面的代码后,将输出如下的信息:

成功登录

找到的数据<abc>

读者可以将scope属性值改成transportsession,看看会输出什么!

    实际上,Axis2的会话管理也是通过Cookie实现的,与Web应用中的Session管理类似。如果读者使用C#访问支持会话(在同一个服务中的会话管理)的WebService,需要指定一个CookieContainer对象,代码如下:

 


service.loginService ls = new service.loginService();   
System.Net.CookieContainer cc = new System.Net.CookieContainer();   
ls.CookieContainer = cc;   
bool r, rs;   
ls.login("bill", "1234", out @r, out rs);   
if (r)   
{   
    MessageBox.Show(ls.getLoginMsg().@return);   
}  
service.loginService ls = new service.loginService();
System.Net.CookieContainer cc = new System.Net.CookieContainer();
ls.CookieContainer = cc;
bool r, rs;
ls.login("bill", "1234", out @r, out rs);
if (r)
{
    MessageBox.Show(ls.getLoginMsg().@return);
}
 

如果是访问跨服务的支持会话的WebService,则不需要指定CookieContainer对象,代码如下:

view plaincopy to clipboardprint?
service.loginService ls = new service.loginService();   
bool r, rs;   
ls.login("bill", "1234", out @r, out rs);   
if (r)   
{   
    service1.searchService ss = new service1.searchService();   
    MessageBox.Show(ss.findByName("abc"));   
}  
service.loginService ls = new service.loginService();
bool r, rs;
ls.login("bill", "1234", out @r, out rs);
if (r)
{
    service1.searchService ss = new service1.searchService();
    MessageBox.Show(ss.findByName("abc"));
}
 

  
    如果使用delphi(本文使用的是delphi2009,其他的delphi版本请读者自行测试)调用支持会话的WebService时有一些差别。经笔者测试,使用delphi调用WebService,将scope属性值设为transportsession和application都可以实现跨服务的会话管理,这一点和Java与C#不同,Java和C#必须将scope属性值设为application才支持跨服务会话管理。在delphi中不需要象C#指定一个CookieContainer或其他类似的对象,而只需要象访问普通的WebService一样访问支持会话的WebService即可。


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/crazystone4/archive/2009/06/20/4285752.aspx

AI 代码审查Review工具 是一个旨在自动化代码审查流程的工具。它通过集成版本控制系统(如 GitHub 和 GitLab)的 Webhook,利用大型语言模型(LLM)对代码变更进行分析,并将审查意见反馈到相应的 Pull Request 或 Merge Request 中。此外,它还支持将审查结果通知到企业微信等通讯工具。 一个基于 LLM 的自动化代码审查助手。通过 GitHub/GitLab Webhook 监听 PR/MR 变更,调用 AI 分析代码,并将审查意见自动评论到 PR/MR,同时支持多种通知渠道。 主要功能 多平台支持: 集成 GitHub 和 GitLab Webhook,监听 Pull Request / Merge Request 事件。 智能审查模式: 详细审查 (/github_webhook, /gitlab_webhook): AI 对每个变更文件进行分析,旨在找出具体问题。审查意见会以结构化的形式(例如,定位到特定代码行、问题分类、严重程度、分析和建议)逐条评论到 PR/MR。AI 模型会输出 JSON 格式的分析结果,系统再将其转换为多条独立的评论。 通用审查 (/github_webhook_general, /gitlab_webhook_general): AI 对每个变更文件进行整体性分析,并为每个文件生成一个 Markdown 格式的总结性评论。 自动化流程: 自动将 AI 审查意见(详细模式下为多条,通用模式下为每个文件一条)发布到 PR/MR。 在所有文件审查完毕后,自动在 PR/MR 中发布一条总结性评论。 即便 AI 未发现任何值得报告的问题,也会发布相应的友好提示和总结评论。 异步处理审查任务,快速响应 Webhook。 通过 Redis 防止对同一 Commit 的重复审查。 灵活配置: 通过环境变量设置基
【直流微电网】径向直流微电网的状态空间建模与线性化:一种耦合DC-DC变换器状态空间平均模型的方法 (Matlab代码实现)内容概要:本文介绍了径向直流微电网的状态空间建模与线性化方法,重点提出了一种基于耦合DC-DC变换器的状态空间平均模型的建模策略。该方法通过数学建模手段对直流微电网系统进行精确的状态空间描述,并对其进行线性化处理,以便于系统稳定性分析与控制器设计。文中结合Matlab代码实现,展示了建模与仿真过程,有助于研究人员理解和复现相关技术,推动直流微电网系统的动态性能研究与工程应用。; 适合人群:具备电力电子、电力系统或自动化等相关背景,熟悉Matlab/Simulink仿真工具,从事新能源、微电网或智能电网研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握直流微电网的动态建模方法;②学习DC-DC变换器在耦合条件下的状态空间平均建模技巧;③实现系统的线性化分析并支持后续控制器设计(如电压稳定控制、功率分配等);④为科研论文撰写、项目仿真验证提供技术支持与代码参考。; 阅读建议:建议读者结合Matlab代码逐步实践建模流程,重点关注状态变量选取、平均化处理和线性化推导过程,同时可扩展应用于更复杂的直流微电网拓扑结构中,提升系统分析与设计能力。
内容概要:本文介绍了基于物PINN驱动的三维声波波动方程求解(Matlab代码实现)理信息神经网络(PINN)求解三维声波波动方程的Matlab代码实现方法,展示了如何利用PINN技术在无需大量标注数据的情况下,结合物理定律约束进行偏微分方程的数值求解。该方法将神经网络与物理方程深度融合,适用于复杂波动问题的建模与仿真,并提供了完整的Matlab实现方案,便于科研人员理解和复现。此外,文档还列举了多个相关科研方向和技术服务内容,涵盖智能优化算法、机器学习、信号处理、电力系统等多个领域,突出其在科研仿真中的广泛应用价值。; 适合人群:具备一定数学建模基础和Matlab编程能力的研究生、科研人员及工程技术人员,尤其适合从事计算物理、声学仿真、偏微分方程数值解等相关领域的研究人员; 使用场景及目标:①学习并掌握PINN在求解三维声波波动方程中的应用原理与实现方式;②拓展至其他物理系统的建模与仿真,如电磁场、热传导、流体力学等问题;③为科研项目提供可复用的代码框架和技术支持参考; 阅读建议:建议读者结合文中提供的网盘资源下载完整代码,按照目录顺序逐步学习,重点关注PINN网络结构设计、损失函数构建及物理边界条件的嵌入方法,同时可借鉴其他案例提升综合仿真能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值