Java uses websocket, and obtains httpsession, source code analysis

Source: Internet
Author: User

A: This article uses the scope

This article is not limited to spring boot, the normal spring project, or even the servlet project, is the same, but the way to configure some listeners is Different.

Through the Author's practice, this paper confirms the perfect Operation.

Two: Spring Boot uses websocket2.1: dependency package

WebSocket itself is a service provided by the servlet container, so it needs to run in a web container, like the tomcat we used, and of course, Tomcat is already embedded in spring Boot.

WebSocket follows the Java EE specification, so it is necessary to introduce Java EE packages

<dependency>      <groupId>javax</groupId>      <artifactid>javaee-api</artifactid >      <version>7.0</version>      <scope>provided</scope>    </dependency>

of course, in fact, Tomcat has already brought this Bag.

If you are in spring boot, you also need to join Websocket's starter

        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId> spring-boot-starter-websocket</artifactid>            <version>1.4.0.RELEASE</version>        </ Dependency>

2.2: Configure WebSocket

If it is not a spring boot project, this is not necessary because Tomcat scans annotations with @serverendpoint as WebSocket if run in tomcat, and spring This bean is required by the boot project to provide registration Management.

@Configurationpublic class Websocketconfig {    @Bean public    serverendpointexporter serverendpointexporter () {        return new Serverendpointexporter ();}    }

Java code for 2.3:websocket

The core of using WebSocket is a series of WebSocket annotations, @ServerEndpoint are registered on the class.

@ServerEndpoint (value = "/websocket") @Componentpublic class Mywebsocket {//connection session with a client, which is required to send data to the client private Sessi    On session;    /** * Connection succeeded */@OnOpen public void OnOpen (session Session) {this.session = session;     }/** * method to close the call * * * @OnClose public void OnClose () {}/** * Receive Message * * @param messages */@OnMessage public void OnMessage (String message, session Session) {System.out.println ("message from browser:" + Me        ssage);            Mass message for (mywebsocket item:websocketset) {try {item.sendmessage (message);            } catch (ioexception E) {e.printstacktrace ();        }}}/** * called */@OnError public void OnError (session session, throwable error) When an error occurs {        System.out.println ("error occurred");    Error.printstacktrace (); The public void SendMessage (String Message) throws IOException {this.session.getBasicRemote (). sendText (message);//synchronous//this.session.getasyncremote (). SendText (message);//asynchronous}} 

In fact, I also feel very strange, why do not use interface to Standardize. Even though some additional parameters can be defined in other attributes in the @serverendpoint annotation, it can be abstracted, but presumably Java EE should have its intention.

2.4: browser-side Code

Browser-side code needs browser support websocket, of course, There are socket.js can support to ie7, but this I did not use. After all, ie basically no one to use, the market on the browser basically all support Websocket.

<! DOCTYPE Html>

So the connection is Successful.

Three: access to httpsession, source analysis

Getting httpsession is an issue that needs to be discussed, because the Java backend need to know which user is currently in use to process the User's business logic, or authorize the user, but because the WebSocket protocol is different from the HTTP protocol, So it was impossible to get the session Directly. But the problem is always solved, otherwise the WebSocket agreement will not be used in the SCENE.

3.1: Get HttpSession tool class, Source Detailed analysis

Let's take a look at the source code for @serverendpoint Annotations.

Package Javax.websocket.server;import Java.lang.annotation.elementtype;import java.lang.annotation.Retention; Import Java.lang.annotation.retentionpolicy;import Java.lang.annotation.target;import javax.websocket.Decoder; Import javax.websocket.Encoder; @Retention (retentionpolicy.runtime) @Target (elementtype.type) public @interface Serverendpoint {    /**     * URI or uri-template that the annotated class should is mapped To.     * @return The URI or uri-template that the annotated class should is mapped     * to         .     *    /String value ();    string[] subprotocols () Default {};    class<? Extends decoder>[] decoders () default {};    class<? Extends encoder>[] encoders () default {};    public class< extends serverendpointconfig.configurator> Configurator ()            Default ServerEndpointConfig.Configurator.class;}

We see the last method, that is, the method of Bold. As you can see, it requires the return of a serverendpointconfig.configurator subclass, and we write a class to inherit it.

Import Javax.servlet.http.httpsession;import Javax.websocket.handshakeresponse;import Javax.websocket.server.handshakerequest;import Javax.websocket.server.serverendpointconfig;import Javax.websocket.server.serverendpointconfig.configurator;public class Httpsessionconfigurator extends Configurator {    @Override public    void Modifyhandshake (serverendpointconfig sec, handshakerequest request, Handshakeresponse Response) {//how?    }}

When we cover the Modifyhandshake method, we can see three parameters, of which the following two parameters let us feel a little bit of the feeling, we look at a handshakerequest source

Package Javax.websocket.server;import Java.net.uri;import Java.security.principal;import java.util.List;import java.util.map;/** * Represents the HTTP request that asked to being upgraded to WebSocket.    */public interface handshakerequest {static final String sec_websocket_key = "sec-websocket-key";    Static final String Sec_websocket_protocol = "sec-websocket-protocol";    Static final String sec_websocket_version = "sec-websocket-version";    Static final String sec_websocket_extensions= "sec-websocket-extensions";    Map<string,list<string>> getheaders ();    Principal Getuserprincipal ();    URI Getrequesturi ();    Boolean IsUserInRole (String role); /** * Get The HTTP Session object associated with this Request.     Object is used * To avoid a direct dependency on the Servlet API.     * @return The Javax.servlet.http.HttpSession object associated with this * request, if any.    */Object gethttpsession (); map<string, list<string>> GETparametermap (); String getquerystring ();}

We found it to be an interface in which the interface was standardized in such a way

    /**     * Get the HTTP Session object associated with this Request. Object is used     * to avoid a direct dependency on the Servlet API.     * @return The Javax.servlet.http.HttpSession object associated with this     *         request, if Any.     *    /Object gethttpsession ();

There is a corresponding comment that says you can get the appropriate httpsession from the servlet api.

When we found this method, it was actually a sigh of relief.

Then we can complete the unfinished code.

Import Javax.servlet.http.httpsession;import Javax.websocket.handshakeresponse;import Javax.websocket.server.handshakerequest;import Javax.websocket.server.serverendpointconfig;import javax.websocket.server.serverendpointconfig.configurator;/** * Get user session from WebSocket * * */public class Httpsessionconfigurator extends Configurator {    @Override public    void Modifyhandshake (serverendpointconfig sec, handshakerequest request, handshakeresponse response) {          HttpSession HttpSession = (HttpSession) Request.gethttpsession ();
       sec.getuserproperties (). put (HttpSession. class . GetName (), httpSession);} }

In fact, through the above source code analysis, you should know the acquisition of Httpsession. But Here's another line of Code.

Sec.getuserproperties (). put (HttpSession.class.getName (), HttpSession);

What does this line of code mean?

Let's take a look at Serverenpointconfig's Statement.

Public interface Serverendpointconfig extends Endpointconfig

We found that this interface inherits the Endpointconfig interface, ok, Let's look at the source code of Endpointconfig:

Package Javax.websocket;import Java.util.list;import Java.util.map;public interface endpointconfig {    List< class<? Extends encoder>> getencoders ();    list<class<? Extends decoder>> getdecoders ();    Map <String,Object> getuserproperties ();}

We have found such a method to define

Map<string,object> getuserproperties ();

As can be seen, it is a map, from the method name can also be understood that it is a user of some of the properties of storage, and since it provides a get method, then it means that we can get the map, and the value inside the operation,

So there's the top one.

Sec.getuserproperties (). put (HttpSession.class.getName (), HttpSession);

So to this, obtain HttpSession source code analysis, is Finished.

3.2: set the class of the HttpSession

As we have said before, because the HTTP protocol differs from the WebSocket protocol, it is not able to get the protocol directly from the websocket, Then in 3.1 we have written the code to get httpsession, but if it is actually released to execute, then the null value is reported as an exception, because the httpsession is not set in.

well, This step, let's set the Httpsession. At this point we need to write a listener.

Import Javax.servlet.servletrequestevent;import Javax.servlet.servletrequestlistener;import Javax.servlet.http.httpservletrequest;import org.springframework.stereotype.Component; @Componentpublic Class Requestlistener implements Servletrequestlistener {public    void requestinitialized (servletrequestevent sre)  {        //bring all request requests on HttpSession        ((httpservletrequest) sre.getservletrequest ()). getsession ();    Public Requestlistener () {    } public    void requestdestroyed (servletrequestevent arg0)  {    }}

then we need to register this class as a listener , if it's a normal spring project, or a servlet project, either in Web. xml, or using@WebListener注解。

Because this article is the Spring boot project to demonstrate, so here only write the Spring boot configuration listener code, the other configuration, please SELF-BAIDU.

This is the way to use @bean annotations

@Autowird
Private Requestlistener requestlistener;
  

@Bean public servletlistenerregistrationbean<requestlistener> Servletlistenerregistrationbean () { servletlistenerregistrationbean<requestlistener> Servletlistenerregistrationbean = new Servletlistenerregistrationbean<> (); Servletlistenerregistrationbean.setlistener (requestlistener); return servletlistenerregistrationbean; }

Or you can also use @weblistener annotations

Then use the @servletcomponentscan annotation, which is configured on the boot Method.

3.3: get the User's session in WebSocket

And then we just passed the source code analysis, is to know that the @serverendpoint annotation is a parameter can be configured we just inherited the class. ok, Let's do the configuration now.

@ServerEndpoint (value = "/websocket", Configurator = Httpsessionconfigurator.class)

You can then get the Endpointconfig object in the method modified in the @onopen annotation, and through this object, get the map we set in

@OnOpen public    void OnOpen (Session session,endpointconfig config) {        HttpSession httpsession= (HttpSession) Config.getuserproperties (). get (HttpSession.class.getName ());        User user = (user) httpsession.getattribute (sessionname.user);        If (user! = Null) {            this.session = session;            This.httpsession = httpSession;        } Else{            //user not logged in            try {                session.close ();            } catch (ioexception e) {                e.printstacktrace ()}        }    }

So we get the User's session from the Java Webscoket.

Source
: http://www.cnblogs.com/zhuxiaojie/p/6238826.html

Java uses websocket, and obtains httpsession, source code analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.