@Override
  protected void handleRawWebSocketRequest(
      ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler)
      throws IOException {

    TransportHandler transportHandler = this.handlers.get(TransportType.WEBSOCKET);
    if (!(transportHandler instanceof HandshakeHandler)) {
      logger.error("No handler configured for raw WebSocket messages");
      response.setStatusCode(HttpStatus.NOT_FOUND);
      return;
    }

    HandshakeInterceptorChain chain = new HandshakeInterceptorChain(this.interceptors, handler);
    HandshakeFailureException failure = null;

    try {
      Map<String, Object> attributes = new HashMap<String, Object>();
      if (!chain.applyBeforeHandshake(request, response, attributes)) {
        return;
      }
      ((HandshakeHandler) transportHandler).doHandshake(request, response, handler, attributes);
      chain.applyAfterHandshake(request, response, null);
    } catch (HandshakeFailureException ex) {
      failure = ex;
    } catch (Throwable ex) {
      failure =
          new HandshakeFailureException("Uncaught failure for request " + request.getURI(), ex);
    } finally {
      if (failure != null) {
        chain.applyAfterHandshake(request, response, failure);
        throw failure;
      }
    }
  }
  public boolean applyBeforeHandshake(
      ServerHttpRequest request, ServerHttpResponse response, Map<String, Object> attributes)
      throws Exception {

    for (int i = 0; i < this.interceptors.size(); i++) {
      HandshakeInterceptor interceptor = this.interceptors.get(i);
      if (!interceptor.beforeHandshake(request, response, this.wsHandler, attributes)) {
        if (logger.isDebugEnabled()) {
          logger.debug(interceptor + " returns false from beforeHandshake - precluding handshake");
        }
        applyAfterHandshake(request, response, null);
        return false;
      }
      this.interceptorIndex = i;
    }
    return true;
  }
  @Override
  protected void handleTransportRequest(
      ServerHttpRequest request,
      ServerHttpResponse response,
      WebSocketHandler handler,
      String sessionId,
      String transport)
      throws SockJsException {

    TransportType transportType = TransportType.fromValue(transport);
    if (transportType == null) {
      logger.error("Unknown transport type for " + request.getURI());
      response.setStatusCode(HttpStatus.NOT_FOUND);
      return;
    }

    TransportHandler transportHandler = this.handlers.get(transportType);
    if (transportHandler == null) {
      logger.error("No TransportHandler for " + request.getURI());
      response.setStatusCode(HttpStatus.NOT_FOUND);
      return;
    }

    HttpMethod supportedMethod = transportType.getHttpMethod();
    if (!supportedMethod.equals(request.getMethod())) {
      if (HttpMethod.OPTIONS.equals(request.getMethod()) && transportType.supportsCors()) {
        if (checkAndAddCorsHeaders(request, response, HttpMethod.OPTIONS, supportedMethod)) {
          response.setStatusCode(HttpStatus.NO_CONTENT);
          addCacheHeaders(response);
        }
      } else if (transportType.supportsCors()) {
        sendMethodNotAllowed(response, supportedMethod, HttpMethod.OPTIONS);
      } else {
        sendMethodNotAllowed(response, supportedMethod);
      }
      return;
    }

    HandshakeInterceptorChain chain = new HandshakeInterceptorChain(this.interceptors, handler);
    SockJsException failure = null;

    try {
      SockJsSession session = this.sessions.get(sessionId);
      if (session == null) {
        if (transportHandler instanceof SockJsSessionFactory) {
          Map<String, Object> attributes = new HashMap<String, Object>();
          if (!chain.applyBeforeHandshake(request, response, attributes)) {
            return;
          }
          SockJsSessionFactory sessionFactory = (SockJsSessionFactory) transportHandler;
          session = createSockJsSession(sessionId, sessionFactory, handler, attributes);
        } else {
          response.setStatusCode(HttpStatus.NOT_FOUND);
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Session not found, sessionId="
                    + sessionId
                    + ". The session may have been closed "
                    + "(e.g. missed heart-beat) while a message was coming in.");
          }
          return;
        }
      }

      if (transportType.sendsNoCacheInstruction()) {
        addNoCacheHeaders(response);
      }

      if (transportType.supportsCors()) {
        if (!checkAndAddCorsHeaders(request, response)) {
          return;
        }
      }

      transportHandler.handleRequest(request, response, handler, session);
      chain.applyAfterHandshake(request, response, null);
    } catch (SockJsException ex) {
      failure = ex;
    } catch (Throwable ex) {
      failure =
          new SockJsException("Uncaught failure for request " + request.getURI(), sessionId, ex);
    } finally {
      if (failure != null) {
        chain.applyAfterHandshake(request, response, failure);
        throw failure;
      }
    }
  }