Point to Point just wanna be better

25Jan/100

Maintaining State in Web Service Using JAX-WS Library (Part 2)

3.  Using HTTPSessionScope Annotation

One way to bring state to web services is to use Http Session cookies. Storing the state and accessing it from the HttpSession (from WebServiceContext) for each request takes multiple steps and doesn't fit well with the object-oriented way of accessing and storing it with instance fields. On the other hand, we can minimize the drawbacks of this this method (Http Session cookies) using HttpSessionScope. This annotation tells the container web to create one instance of WS object per each HTTP session. As you see this approach still relies on Http cookies but makes it easier to access state from the context just like normal instance variables. By using this method, we are not use to maintain client’s session manually and store all client’s data to HTTP session since all mechanism have been handled by HTTPSessionScope annotation.

/* Server code */
@WebService @HttpSessionScope
public class SWS {
private int counter = 0;
private int amount = 0;
public double getAverage(int n) {
this.amount += n; this.counter++;
return ((double) amount) / counter;
}
}
/* Client code */
public class Main {
public static void main(String[] args) {
try {
service.SWS proxy = new service.SWSService().getSWSPort();
((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);
Scanner scan = new Scanner(System.in);
System.out.print("> ");
int input = scan.nextInt();
while(input != 0) {
double result = proxy.getAverage(input);
System.out.println("Average: " + result);
System.out.print("> ");
input = scan.nextInt();
}
}
catch (Exception e) { }
}
}

4.  Using Addressing and Stateful Annotation

JAX-WS also provides a transport neutral mechanism to address web services and messages using WS-Addressing. Moreover, it also introduces Stateful annotation to take care of maintaining all the state and the user can access it using instance variables. All the user needs to do is to add Stateful and Addressing annotation to web service implementation. As you see, this method requires support for Addressing. Kawaguchi through his blog said that this was the proper way to implement stateful web service which fit with object-oriented concept.

@Stateful @WebService @Addressing
class BankAccount {
    protected final int id;
    private int balance;

    Account(int id) { this.id = id; }

    @WebMethod
    public synchronized void deposit(int amount) { balance+=amount; }

    // either via a public static field
    
    public static StatefulWebServiceManager<BankAccount> manager;
    
    // ... or  via a public static method (the method name could be anything)
    
    public static void setManager(StatefulWebServiceManager<BankAccount> manager) {
       ...
    }
    
}

Each instance of a stateful web service class is identified by an unique EndpointReference (EPR). The application creates an instance of a class, then we'll have the JAX-WS RI assign this unique EPR for the instance as follows:

@WebService
class Bank { // this is ordinary stateless service
    @WebMethod
    public synchronized W3CEndpointReference login(int accountId, int pin) {
        if(!checkPin(pin))
            throw new AuthenticationFailedException("invalid pin");
        BankAccount acc = new BankAccount(accountId);
        return BankAccount.manager.export(acc);
    }
}

Typically we then pass this EPR to remote systems. When they send messages to EPR, the JAX-WS makes sure that the particular exported instance associated with that EPR will receive a service invocation.

  • Delicious
  • Facebook
  • Plurk
  • Twitter
  • Share/Bookmark
Tagged as: Leave a comment
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.