Sunday, June 19, 2011

WS: Keep REST/HTTP/HESSIAN client state by one line of code


Stateful HTTP-services require you to pass the jsessionid back and forth between a Java-based HTTP client (like Hessian, REST-client like Jersey/RESTeasy, SOAP, or plain HTTP-connection) as URL-extension or cookie. 

JDK 1.6 comes with java.net.CookieManager which handles all the bookkeeping for you.

I modified the already introduced Hessian example to be stateful - it takes a single (but bold) line of code:

import java.net.CookiePolicy;
import java.net.CookieManager;
import java.net.CookieHandler;
public class HessianStatefulTimeEndpoint {
    private TimeService timeService;

    @Before
    public void initProxy() throws MalformedURLException {
        
        CookieHandler.setDefault(new CookieManager(null /*=default in-memory store*/, CookiePolicy.ACCEPT_ALL));
        String url = "http://localhost:8080/EJB31AndHessian/TimeService";
        HessianProxyFactory factory = new HessianProxyFactory();
        this.timeService = (TimeService) factory.create(TimeService.class,url);
        assertNotNull(timeService);
    }

    
    @Test
    public void statefulness(){
        int numberOfSessions = this.timeService.getNumberOfSessions();
        int nextInvocation = this.timeService.getNumberOfSessions();
        assertEquals(numberOfSessions,nextInvocation);
    }
}
On the server server you can inject @SessionScoped beans into the HessianServlet:

public class HessianTimeEndpoint extends HessianServlet implements TimeService{

    @Inject
    CurrentTime currentTime;
...
}

@SessionScoped
public class CurrentTime implements Serializable{
    
    private static AtomicInteger instanceCount = new AtomicInteger(0);
    
    @PostConstruct
    public void onNewSession(){
        System.out.println("On new session: " + new Date());
        instanceCount.incrementAndGet();
    }
    
    public int getNumberOfSessions(){
        return instanceCount.get();
    }
    
    public long nanos(){
        return System.nanoTime();
    }
}