After learning about session management in the same service, click to open the link. Today, let's take a look at the cross-service session management. I wrote the server last night, but only the client code is left, when I got off work, I had to write it this morning. It would be a review.
For a complex system, it is impossible to have only one WebService. For example, there must be at least one WebService that manages users (user logon and registration) and the WebService that processes services. In this case, the Session state must be shared among multiple WebService services, also known as cross-service Session management. The steps for implementing cross-service session management are similar to those for implementing session management for the same service, but there are still some differences. The steps for implementing cross-service session management are as follows:
The following three steps are required to implement cross-service Session management:
1. Use MessageContext and ServiceGroupContext to obtain and set the key-value pair.
2. Add a scope attribute for the <service> element corresponding to the WebService class for Session management, and set the attribute value to application.
3. Use setManageSession (true) on the client to enable the Session management function.
From the above steps, we can see that there are differences between implementing cross-service session management and implementing session management for the same service in the first two steps, while Step 2 is the same. The following is an instance of cross-service session management. In this example, there are two WebService classes: LoginService and SearchService. The Code is as follows:
[Java] package crossSession;
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 ))
{
// Step 2: Set the key-value Pair
MessageContext mc = MessageContext. getCurrentMessageContext ();
ServiceGroupContext sgc = mc. getServiceGroupContext ();
Sgc. setProperty ("login", "successfully logged on ");
Return true;
}
Else
{
Return false;
}
}
Public String getLoginMsg ()
{
// Step 2: obtain the value in the key-value Pair
MessageContext mc = MessageContext. getCurrentMessageContext ();
ServiceGroupContext sgc = mc. getServiceGroupContext ();
Return (String) sgc. getProperty ("login ");
}
}
[Java]
Package crossSession;
Import org. apache. axis2.context. MessageContext;
Import org. apache. axis2.context. ServiceGroupContext;
Public class SearchService
{
Public String findByName (String name)
{
// Step 2: obtain the value in the key-value Pair
MessageContext mc = MessageContext. getCurrentMessageContext ();
ServiceGroupContext sgc = mc. getServiceGroupContext ();
If (sgc. getProperty ("login ")! = Null)
Return "Data found <" + name + "> ";
Else
Return "user not logged on ";
}
}
The configuration code in the services. xml file is as follows:
[Html]
<ServiceGroup>
<! -- Step 2: add the scope attribute and set the attribute value to application -->
<Service name = "loginSession" scope = "application">
<Description>
LOGON SERVICE
</Description>
<Parameter name = "ServiceClass">
CrossSession. LoginService
</Parameter>
<MessageReceivers>
<MessageReceiver mep = "http://www.w3.org/2004/08/wsdl/in-out"
Class = "org. apache. axis2.rpc. receivers. RPCMessageReceiver"/>
</MessageReceivers>
</Service>
<! -- Step 2: add the scope attribute and set the attribute value to application -->
<Service name = "searchSession" scope = "application">
<Description>
Search Service
</Description>
<Parameter name = "ServiceClass">
CrossSession. SearchService
</Parameter>
<MessageReceivers>
<MessageReceiver mep = "http://www.w3.org/2004/08/wsdl/in-out"
Class = "org. apache. axis2.rpc. receivers. RPCMessageReceiver"/>
</MessageReceivers>
</Service>
</ServiceGroup>
Step 2 is similar to the method described in the open link.
The following describes how to use two stub class object instances to access the client code of the two WebServices implemented above: (because there are two services, we need to implement two stub classes respectively)
[Java]
Package crossSession;
Import java. rmi. RemoteException;
Public class LoginSearchStubClient {
Public static void main (String [] args) throws RemoteException {
// TODO Auto-generated method stub
LoginSessionStub lss = new LoginSessionStub ();
LoginSessionStub. Login login = new LoginSessionStub. Login ();
LoginSessionStub. GetLoginMsg glm = new LoginSessionStub. GetLoginMsg ();
Login. setUsername ("bill ");
Login. setPassword ("1234 ");
If (lss. login (login). local_return ){
System. out. println (lss. getLoginMsg (glm). get_return ());
SearchSessionStub sss = new SearchSessionStub ();
SearchSessionStub. FindByName fbn = new SearchSessionStub. FindByName ();
Fbn. setName ("bill ");
System. out. println (sss. findByName (fbn). local_return );
}
}
}
After the above code is executed, the following information will be output:
If you change the scope attribute value to transportsession, let's see what will be output!
First, change the loginService's
Normal output, that is to say, the loginService service can only play a role in the same service. Here we only call the login service, so there is no impact.
Second, change
The output is still normal. No, the following code must be cross-service
[Java]
If (sgc. getProperty ("login ")! = Null)
Return "Data found <" + name + "> ";
Else
Return "user not logged on ";
What is the problem?
[Java]
// Step 2: obtain the value in the key-value Pair
MessageContext mc = MessageContext. getCurrentMessageContext ();
ServiceGroupContext sgc = mc. getServiceGroupContext (); // ServiceGroupContext instead of ServiceContext?
[Java] view plaincopy
// <Span style = "color: black;"> does ServiceGroupContext conflict with scope? </Span>
Okay, now that there is a conflict, let's try it one by one. The results are even more unexpected. If we change ServiceGroupContext to ServiceContext, the output is still normal. What is the situation?
This made me wonder whether this program is cross-session or not. I will not wear a cross-session coat. Continue to study!
Let's take a look at the transportsession issue in scope. The following is an official document.
Transport Session Scope
In the case of a Transport session, Axis2 uses transport-related session management techniques to manage session. as an example, in the case of HTTP, it uses HTTP cookies to manage the session. the lifetime of the session is controlled by the transport, not by Axis2; axis2 stores the service context and serviceGroupContext in the transport session object so that the service can access those contexts as long as the session lives.
One of the key advantages of the Transport session over other sessions is that you can talk to multiple service groups within one transport session. in a SOAP session, you don't have a way to communicate between two service groups, but with the transport session you have that capability. in this case, the number of service instances created depends on the number of transport sessions created.
Deploying a service in a transport session requires you to change services. xml as follows:
<Service name = "foo" scope = "transportsession">
</Service>
If you are using Axis2 nightly builds or planning to use them the next version, deploying a service in a transport session requires additional changes to axis2.xml. that is mainly to improve the memory usage; otherwise, whether you deploy the service in a transport session or not Axis2 tries to create a session object at the transport level; with these changes, it will not create unnecessary objects. to manage the transport-level session, you need to set the manageTransportSession parameter value to true in axis2.xml:
When I saw this passage, I realized that transportsession is not only as simple as a single service.
As for ServiceGroupContext and ServiceContext, I checked the API documentation.
It can be seen that they all inherit from the same class, And the setProperty () method of this abstract class is as follows,
From this we can see that this method is used to store values. As for the access permission of stored values, we can only know ServiceGroupContext and ServiceContext.
The following describes ServiceContext.
Here we can see that its life cycle is unclear and not recommended, and its construction method can be externalized. For this question, please refer to this article and click the open link.
The following describes ServiceGroupContext.
As a matter of fact, I still don't quite understand the main differences between ServiceGroupContext and ServiceContext. So I read MessageContext, and I had another question.
Why does MessageContext only hold ServiceGroupContext, but does not mention ServiceContext?
It seems that we still need the wisdom of everyone. If you have a good understanding of these problems, please leave a message to solve them.