Small pit: Using requestListner cannot solve this problem!
How to get HttpSession
When using webSocket to implement p2p or one-to-many chat functions, we often have this requirement: the webSocket server needs to obtain user information using the database to obtain personal information after logging in.
So, you'll use code like this:
package ; import ; import ; import ; import ; import ; /** * Created by zipple on 2017/11/14. * Assist the server to obtain http session */ public class HttpSessionWSHelper extends Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { ("Call the modifiedHandshake method..."); HttpSession session = (HttpSession) ();//Session may be empty if (session!=null){ ("Get session id:"+()); ().put((),session); }else{ ("modifyHandshake gets null session"); } } }
Then configure it on the server:
@ServerEndpoint(value ="/chatRoom/{username}",configurator=,encoders = {}) //encoders = {}Used to specifysendObject()Method call parser
RequestListner cannot solve the reason for this problem
After using the above method to complete the configuration, I conducted the test with confidence, but unexpectedly found that the Tomcat Localhost Log reported a null pointer exception.
After debugging, I found that the modifyHandshake method cannot obtain the HttpSession. In the above HttpSessionWSHelper class code, you can see that I have processed it with empty commands. But this does not actually work. We need to figure out why HandshakeRequest cannot get the HttpSession.
At the beginning, I tried to go to Baidu and found that there is a code like this:
package ; import ; import ; import ; import ; import ; /** * Created by zipple on 2017/11/14. */ @WebListener public class RequestListener implements ServletRequestListener { public void requestInitialized(ServletRequestEvent sre) { //Bring all request requests with httpSession---This will create a new session! This will result in a recreation of the session ("request--:"+().getLocalAddr()); ((HttpServletRequest) ()).getSession(); } public RequestListener() { // TODO Auto-generated constructor stub } public void requestDestroyed(ServletRequestEvent arg0) { // TODO Auto-generated method stub } }
The Internet explained that it is because the HttpSession was not activated when the WS connection was made, so the HttpSession could not be obtained. The solution they gave is to call the()).getSession() method for each request request.
This can indeed solve the problem of null pointer exceptions, but new problems have emerged.
When there is no HttpSession activation state, using the getSession() method will create a new HttpSession, which means that in fact, the listener continuously creates a new session without HttpSession activation.
This has completely deviated from the needs of our program: to obtain personal information saved in the HttpSession that is online at the same time.
So what should I do?
In fact, the root cause of this null pointer exception is not in our backend code.
localhost and 127.0.0.1 are not actually the same connection
When connecting to WebSocket on the front end, my code looks like this:
loadWS("ws://127.0.0.1/chatRoom/null");
However, the browser address bar looks like this:
http://localhost:8080/
It is explained online that if the same host is not used, different connection requests will be created. Interested friends can learn more about the details.
So we can splice it like this:
var host = ; var url = "ws://"+host+"/chatRoom/null";
This way, the ws request can be established normally, and the HttpSession can be obtained using the custom HttpSessionWSHelper class.
This is the article about the solution to the WebSocket obtaining httpSession null pointer exception. For more related content about WebSocket obtaining httpSession null pointer, please search for my previous article or continue browsing the related articles below. I hope everyone will support me in the future!