对于需要进行用户认证的应用来说,需要Web Service具有会话的功能,用户在使用Web Service时需要进行登录。Axis2提供了4种会话类型,可以很容易的实现会话管理。
作为一个demo,本文模拟用户通过Web Service登录进系统,然后进行业务操作,最后退出登录。本文假设用户的业务操作是跨服务的,而Axis2的Transport Session实现了跨服务的会话管理,也是本文所使用的会话类型。
用户登录的服务:
package demo.axis2;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class User
{
/**
* 用户登录
* @param userName
* @param password
* @return
*/
public boolean login(String userName, String password)
{
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
sgc.setProperty("userName", userName);
return true;
}
/**
* 用户退出登录
* @return
*/
public String logout()
{
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
if (sgc!= null && sgc.getProperty("userName") != null)
{
String userName = sgc.getProperty("userName").toString();
sgc.setProperty("userName", null);
return userName + "退出登录";
}
return "未登录";
}
}
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class User
{
/**
* 用户登录
* @param userName
* @param password
* @return
*/
public boolean login(String userName, String password)
{
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
sgc.setProperty("userName", userName);
return true;
}
/**
* 用户退出登录
* @return
*/
public String logout()
{
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
if (sgc!= null && sgc.getProperty("userName") != null)
{
String userName = sgc.getProperty("userName").toString();
sgc.setProperty("userName", null);
return userName + "退出登录";
}
return "未登录";
}
}
业务操作的服务:
package demo.axis2;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class Biz
{
/**
* 模拟业务操作
* @return
*/
public String doBiz()
{
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
if (sgc==null || sgc.getProperty("userName") == null) return "未登录,不能进行业务操作";
else return "业务操作成功。操作员:" + sgc.getProperty("userName");
}
}
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceGroupContext;
public class Biz
{
/**
* 模拟业务操作
* @return
*/
public String doBiz()
{
MessageContext mc = MessageContext.getCurrentMessageContext();
ServiceGroupContext sgc = mc.getServiceGroupContext();
if (sgc==null || sgc.getProperty("userName") == null) return "未登录,不能进行业务操作";
else return "业务操作成功。操作员:" + sgc.getProperty("userName");
}
}
services.xml:
<serviceGroup>
<service name="User" scope="transportsession">
<Description>
用户登录服务
</Description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">demo.axis2.User</parameter>
</service>
<service name="Biz" scope="transportsession">
<Description>
业务服务
</Description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">demo.axis2.Biz</parameter>
</service>
</serviceGroup>
<service name="User" scope="transportsession">
<Description>
用户登录服务
</Description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">demo.axis2.User</parameter>
</service>
<service name="Biz" scope="transportsession">
<Description>
业务服务
</Description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">demo.axis2.Biz</parameter>
</service>
</serviceGroup>
客户端访问时,需要加一句“options.setManageSession(true);”,其他的地方都是相同的。客户端示例代码如下:
package demo.axis2.client;
import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class UserClient
{
public static void main(String[] args) throws Exception
{
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
/* 用户登录 */
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/Axis2ServerDemo/services/User");
options.setTo(targetEPR);
options.setManageSession(true);
// 指定方法的参数值
Object[] opAddEntryArgs = new Object[] {"tom", "pwd"};
// 指定方法返回值的数据类型的Class对象
Class[] classes = new Class[] {Boolean.class};
// 指定要调用的getGreeting方法及WSDL文件的命名空间
QName opAddEntry = new QName("http://axis2.demo", "login");
// 调用方法并输出该方法的返回值
System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);
/* 业务操作 */
EndpointReference targetEPR1 = new EndpointReference(
"http://localhost:8080/Axis2ServerDemo/services/Biz");
options.setTo(targetEPR1);
Object[] opAddEntryArgs1 = new Object[] {};
Class[] classes1 = new Class[] {String.class};
QName opAddEntry1 = new QName("http://axis2.demo", "doBiz");
System.out.println(serviceClient.invokeBlocking(opAddEntry1, opAddEntryArgs1, classes1)[0]);
/* 用户退出登录 */
options.setTo(targetEPR);
Object[] opAddEntryArgs2 = new Object[] {};
Class[] classes2 = new Class[] {String.class};
QName opAddEntry2 = new QName("http://axis2.demo", "logout");
System.out.println(serviceClient.invokeBlocking(opAddEntry2, opAddEntryArgs2, classes2)[0]);
}
}
import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class UserClient
{
public static void main(String[] args) throws Exception
{
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
/* 用户登录 */
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/Axis2ServerDemo/services/User");
options.setTo(targetEPR);
options.setManageSession(true);
// 指定方法的参数值
Object[] opAddEntryArgs = new Object[] {"tom", "pwd"};
// 指定方法返回值的数据类型的Class对象
Class[] classes = new Class[] {Boolean.class};
// 指定要调用的getGreeting方法及WSDL文件的命名空间
QName opAddEntry = new QName("http://axis2.demo", "login");
// 调用方法并输出该方法的返回值
System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);
/* 业务操作 */
EndpointReference targetEPR1 = new EndpointReference(
"http://localhost:8080/Axis2ServerDemo/services/Biz");
options.setTo(targetEPR1);
Object[] opAddEntryArgs1 = new Object[] {};
Class[] classes1 = new Class[] {String.class};
QName opAddEntry1 = new QName("http://axis2.demo", "doBiz");
System.out.println(serviceClient.invokeBlocking(opAddEntry1, opAddEntryArgs1, classes1)[0]);
/* 用户退出登录 */
options.setTo(targetEPR);
Object[] opAddEntryArgs2 = new Object[] {};
Class[] classes2 = new Class[] {String.class};
QName opAddEntry2 = new QName("http://axis2.demo", "logout");
System.out.println(serviceClient.invokeBlocking(opAddEntry2, opAddEntryArgs2, classes2)[0]);
}
}
如果客户端是用工具生成的代码,找到相应的地方进行修改。
执行上面的客户端代码,就可以看到结果了。
这个简单的demo实现了一个简单的Web Service的用户会话,在这个基础上可以开发出符合自己需求的功能。