[Java EE] How to get HttpSession into a WebSocket connection using a Managed Bean.

Theekshana Wijesinghe
3 min readJun 21, 2020

You might be wondering why do we need the HttpSession in the WebSocket connection?

For me, I was developing a test chat application and I stored the logged-in user information by the HttpSessionId. It is not the ideal setup but served the purpose. I wanted to have the user information when they chat using the WebSocket protocol. So I needed the current HttpSession in the WebSocket connection.

I found solutions from StackOverflow but wanted to try a different mechanism. So there it goes.

It important to understand that,

HTTP and WebSocket protocols are based on TCP protocol.

And, as given in the below diagram WebSocket uses HTTP handshake request/response to initiate WebSocket connection.

WebSocket Handshake: Image courtesy Java EE 7: The Big Picture by Danny Coward.

This handshake request is used to get the HttpSession. Let’s see the code.

Assume that WebSocket URI ws://<host-name>/<context-path>/message

First, let’s tap into the handshake request by using a Web Filter.

import javax.inject.Inject;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(filterName = "WSFilter", urlPatterns = {"/message"})
public class WSFilter implements Filter {

@Inject
WSHttpSession wsHttpSession;

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
wsHttpSession.setHttpSession(request.getSession());
filterChain.doFilter(servletRequest, servletResponse);
}

@Override
public void destroy() {

}
}

Observe that this class is annotated with @WebFilter annotation to capture HTTP requests to /message which is the URL of the WebSocket connection.

@Inject will inject the WSHttpSession bean into this filter. We will see this class next.

doFilter method is used to save the request.session object in the WSHttpSession bean.

Next up, WSHttpSession class.

@Named("WebSocketHttpSession")
@RequestScoped
public class WSHttpSession {

private HttpSession httpSession;

public HttpSession getHttpSession() {
return httpSession;
}

public void setHttpSession(HttpSession httpSession) {
this.httpSession = httpSession;
}
}

This is the critical piece in this mechanism. With the annotation, @RequesScoped we specify that it is a Managed Bean that will be controlled by the JavaEE platform. JavaEE will create only one instance per request thus this can be used to save the HttpSession of the request.

The final piece, the WebSocket implementation class

import javax.inject.Inject;
import javax.servlet.http.HttpSession;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/message")
public class WSImpl {

@Inject
WSHttpSession wsHttpSession;

private HttpSession httpSession;

@OnOpen
public void open() {
this.httpSession = wsHttpSession.getHttpSession();
}

@OnMessage
public void message(String message) {
// Use this.httpSession as applicable
}
}

@ServerEndpoint("/message") annotation tells JavaEE application server that this class will handle WebSocket connections to /message endpoint.

Method annotated with @onOpen will be called at the instance a connection is opened (Initial handshake). At this point we will save the HttpSession saved in WSHttpSession the managed bean injected here.

It is important to assign HttpSession to a local variable since, WSHttpSession will no longer available when WebSocket connections start to kickoff since it has a request scope.

Note:

Already established HttpSession should be available before we begin the WebSocket connection.

Feel free to share your thoughts!

References

[1] Java EE 7: The Big Picture by Danny Coward.

--

--